From 7a2368d6ac689c82a2f330a996bb606fb139b56f Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Wed, 15 Sep 2021 11:40:51 +0200 Subject: [PATCH 001/452] add testing for version 1.18 (#11) --- .CI/Jenkinsfile | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index 1004a57..bf50730 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -8,6 +8,7 @@ pipeline { booleanParam(name: 'v1_14', defaultValue: false, description: 'maintenance/v1.14 branch (ripper1)') booleanParam(name: 'v1_16', defaultValue: false, description: 'maintenance/v1.16 branch (ripper1)') booleanParam(name: 'v1_17', defaultValue: false, description: 'maintenance/v1.17 branch (ripper1)') + booleanParam(name: 'v1_18', defaultValue: false, description: 'maintenance/v1.18 branch (ripper1)') booleanParam(name: 'master', defaultValue: false, description: 'master branch (ripper1)') booleanParam(name: 'fmi_v1_12', defaultValue: false, description: 'maintenance/v1.12 branch with FMI (ripper2)') @@ -15,6 +16,7 @@ pipeline { booleanParam(name: 'fmi_v1_14', defaultValue: false, description: 'maintenance/v1.14 branch with FMI (ripper2)') booleanParam(name: 'fmi_v1_16', defaultValue: false, description: 'maintenance/v1.16 branch with FMI (ripper2)') booleanParam(name: 'fmi_v1_17', defaultValue: false, description: 'maintenance/v1.17 branch with FMI (ripper2)') + booleanParam(name: 'fmi_v1_18', defaultValue: false, description: 'maintenance/v1.18 branch with FMI (ripper2)') booleanParam(name: 'fmi_master', defaultValue: false, description: 'master branch with FMI (ripper2)') booleanParam(name: 'newInst_daeMode', defaultValue: false, description: 'master branch, --daeMode with -d=newInst (ripper2)') booleanParam(name: 'oldInst', defaultValue: false, description: 'master branch, with -d=nonewInst (ripper2)') @@ -115,6 +117,23 @@ pipeline { } } + stage('v1.18') { + agent { + node { + label 'ripper.openmodelica.org' + customWorkspace 'ws/OpenModelicaLibraryTestingWork' + } + } + options { skipDefaultCheckout() } + when { + beforeAgent true + expression { params.v1_18 } + } + steps { + test('maintenance/v1.18', 'v1.18', '', '', 'LibraryTestingRipper1DB', false, '', false, false) + } + } + stage('master') { agent { node { @@ -229,6 +248,22 @@ pipeline { test('maintenance/v1.17', 'v1.17-fmi', '', omsimulatorHash(), 'LibraryTestingRipper2DB', false, '', false, false) } } + stage('v1.18 FMI') { + agent { + node { + label 'ripper2-1' + customWorkspace 'ws/OpenModelicaLibraryTestingWork' + } + } + options { skipDefaultCheckout() } + when { + beforeAgent true + expression { params.fmi_v1_18 } + } + steps { + test('maintenance/v1.18', 'v1.18-fmi', '', omsimulatorHash(), 'LibraryTestingRipper2DB', false, '', false, false) + } + } stage('master FMI') { agent { node { @@ -308,7 +343,7 @@ pipeline { expression { params.v1_12 || params.v1_13 || params.v1_14 || params.v1_16 || params.v1_17 || params.master || params.conversion_script || params.report_ripper1 } } environment { - GITBRANCHES = 'maintenance/v1.12 maintenance/v1.13 maintenance/v1.14 maintenance/v1.16 maintenance/v1.17 master' + GITBRANCHES = 'maintenance/v1.12 maintenance/v1.13 maintenance/v1.14 maintenance/v1.16 maintenance/v1.17 maintenance/v1.18 master' PYTHONIOENCODING = 'utf-8' } steps { @@ -360,7 +395,7 @@ pipeline { expression { params.fmi_v1_12 || params.fmi_v1_13 || params.fmi_v1_14 || params.fmi_v1_16 || params.fmi_v1_17 || params.fmi_master || params.newInst_daeMode || params.oldInst || params.report_ripper2 || params.cvode } } environment { - GITBRANCHES_FMI = 'maintenance/v1.12-fmi maintenance/v1.13-fmi maintenance/v1.14-fmi maintenance/v1.16-fmi maintenance/v1.17-fmi master-fmi' + GITBRANCHES_FMI = 'maintenance/v1.12-fmi maintenance/v1.13-fmi maintenance/v1.14-fmi maintenance/v1.16-fmi maintenance/v1.17-fmi maintenance/v1.18-fmi master-fmi' GITBRANCHES_NEWINST = 'oldInst' GITBRANCHES_DAE = 'daemode newInst-daemode' PYTHONIOENCODING = 'utf-8' From cfae58dfbd75674e7f6d13018dd0f6def9dd5bb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Wed, 15 Sep 2021 13:26:43 +0200 Subject: [PATCH 002/452] Print library names before conversion to catch failures --- conversionscript.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/conversionscript.py b/conversionscript.py index 9f2536b..f7f1f90 100755 --- a/conversionscript.py +++ b/conversionscript.py @@ -77,6 +77,7 @@ def convertPackage(p): return None if libname in ["Modelica", "ModelicaServices", "Complex", "ModelicaTest", "ModelicaTestOverdetermined"]: return None + print("Start working on %s" % libnameOnFile) omc = OMCSessionZMQ() libnameOnFileFullPath = "converted-libraries/.openmodelica/libraries/%s/package.mo" % libnameOnFile omcAssert(omc, 'loadFile("%s", uses=false)' % libnameOnFileFullPath) @@ -89,6 +90,7 @@ def convertPackage(p): gcProfStatsBeforeConversion = omc.sendExpression("GC_get_prof_stats()") timeBeforeConvert = time.time() omcAssert(omc, 'convertPackage(%s, "%s")' % (libname, conversionScript)) + print("convertPackage(%s, %s) OK" % (libnameOnFile, conversionScript)) uses = data["uses"] for (n,v) in data["uses"].items(): if n in ["Modelica", "ModelicaServices", "Complex"]: From 786536baeb17fc7c50193174af3c798ef86400bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Wed, 15 Sep 2021 20:48:20 +0200 Subject: [PATCH 003/452] Remove support for Python2,CORBA,RML --- .CI/Jenkinsfile | 2 +- shared.py | 11 +++++----- test.py | 53 ++++++++++++++++--------------------------------- 3 files changed, 23 insertions(+), 43 deletions(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index bf50730..b1e1b3c 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -705,7 +705,7 @@ def test(branch, name, extraFlags, omsHash, sshConfig, omcompiler, extrasimflags export HOME="${libraryPath}" cd OpenModelicaLibraryTesting # Force /usr/bin/omc as being used for generating the mos-files. Ensures consistent behavior among all tested OMC versions - stdbuf -oL -eL time python2 ./test.py --ompython_omhome=/usr ${FMI_TESTING_FLAG} --extraflags='${extraFlags}' --extrasimflags='${extrasimflags}' --branch="${name}" --output="libraries.openmodelica.org:/var/www/branches/${name}/" --libraries='${libraryPath}/.openmodelica/libraries/' configs/conf.json ${conversionScript ? "" : "configs/conf-c++.json"} ${params.OLD_LIBS ? "configs/conf-old.json configs/conf-nonstandard.json" : ""} || (killall omc ; false) || exit 1 + stdbuf -oL -eL time ./test.py --ompython_omhome=/usr ${FMI_TESTING_FLAG} --extraflags='${extraFlags}' --extrasimflags='${extrasimflags}' --branch="${name}" --output="libraries.openmodelica.org:/var/www/branches/${name}/" --libraries='${libraryPath}/.openmodelica/libraries/' configs/conf.json ${conversionScript ? "" : "configs/conf-c++.json"} ${params.OLD_LIBS ? "configs/conf-old.json configs/conf-nonstandard.json" : ""} || (killall omc ; false) || exit 1 """ sh 'date' sh 'rm -f OpenModelicaLibraryTesting/sqlite3.db.tmp' diff --git a/shared.py b/shared.py index 5056352..2e1d059 100644 --- a/shared.py +++ b/shared.py @@ -3,7 +3,7 @@ import re, os, subprocess import simplejson as json -def fixData(data,rmlStyle,abortSimulationFlag,alarmFlag,overrideDefaults,defaultCustomCommands,extrasimflags): +def fixData(data,abortSimulationFlag,alarmFlag,overrideDefaults,defaultCustomCommands,extrasimflags): data["configFromFile"] = dict(data) for (key,default) in overrideDefaults: if key not in data: @@ -16,10 +16,9 @@ def fixData(data,rmlStyle,abortSimulationFlag,alarmFlag,overrideDefaults,default data["reference_reltol"] = float(data.get("reference_reltol") or 3e-3) data["reference_reltolDiffMinMax"] = float(data.get("reference_reltolDiffMinMax") or 3e-3) data["reference_rangeDelta"] = float(data.get("reference_rangeDelta") or 1e-3) - debug = "+d" if rmlStyle else "-d" if data["simCodeTarget"]=="Cpp": defaultCustomCommands2 = defaultCustomCommands[:] - defaultCustomCommands2.append('setCommandLineOptions("%ssimCodeTarget=Cpp")' % ("+" if rmlStyle else "--")) + defaultCustomCommands2.append('setCommandLineOptions("--simCodeTarget=Cpp")') else: defaultCustomCommands2 = defaultCustomCommands data["customCommands"] = (data.get("customCommands") or defaultCustomCommands2) + (data.get("extraCustomCommands") or []) @@ -40,11 +39,11 @@ def fixData(data,rmlStyle,abortSimulationFlag,alarmFlag,overrideDefaults,default data["changeHash"] = data["changeHash"] return (data["library"],data) except: - print("Failed to fix data for: %s with extra args: %s" % (str(data),str((rmlStyle,abortSimulationFlag,alarmFlag,defaultCustomCommands)))) + print("Failed to fix data for: %s with extra args: %s" % (str(data),str((abortSimulationFlag,alarmFlag,defaultCustomCommands)))) raise -def readConfig(c,rmlStyle=False,abortSimulationFlag="",alarmFlag="",overrideDefaults=[],defaultCustomCommands=[],extrasimflags=""): - return [fixData(data,rmlStyle,abortSimulationFlag,alarmFlag,overrideDefaults,defaultCustomCommands,extrasimflags) for data in json.load(open(c))] +def readConfig(c,abortSimulationFlag="",alarmFlag="",overrideDefaults=[],defaultCustomCommands=[],extrasimflags=""): + return [fixData(data,abortSimulationFlag,alarmFlag,overrideDefaults,defaultCustomCommands,extrasimflags) for data in json.load(open(c))] def libname(library, conf): if "libraryVersionNameForTests" in conf: diff --git a/test.py b/test.py index b7278cb..ac1b695 100755 --- a/test.py +++ b/test.py @@ -4,6 +4,9 @@ # TODO: When libraries hash changes, run with the old OMC against the new libs # Then run with the new OMC against the new libs +if (sys.version_info < (3, 0)): + raise Exception("Python2 is no longer supported") + import html, shutil, sys, os, re, glob, time, argparse, sqlite3, datetime, math, platform from joblib import Parallel, delayed import simplejson as json @@ -17,9 +20,6 @@ import signal -if (sys.version_info > (3, 0)): - basestring = (str, bytes) - def rmtree(f): try: shutil.rmtree(f) @@ -96,8 +96,6 @@ def target(): parser.add_argument('--extrasimflags', default='') parser.add_argument('--ompython_omhome', default='') parser.add_argument('--noclean', action="store_true", default=False) -parser.add_argument('--rml', action="store_true", default=False) -parser.add_argument('--corba', action="store_true", default=False) parser.add_argument('--fmisimulator', default='') parser.add_argument('--ulimitvmem', help="Virtual memory limit (in kB)", type=int, default=8*1024*1024) parser.add_argument('--default', action='append', help="Add a default value for some configuration key, such as --default=ulimitExe=60. The equals sign is mandatory.", default=[]) @@ -117,8 +115,6 @@ def target(): ulimitMemory = args.ulimitvmem docker = args.docker librariespath = args.libraries -rmlStyle = args.rml -corbaStyle = args.corba overrideDefaults = [arg.split("=", 1) for arg in args.default] print("branch: %s, n_jobs: %d" % (branch, n_jobs)) if clean: @@ -157,9 +153,6 @@ def target(): version_cmd = "--version" single_thread="-n=1" -rmlStyle=False - - # Try to make the processes a bit nicer... os.environ["GC_MARKERS"]="1" @@ -169,18 +162,13 @@ def target(): if ompython_omhome != "": # Use a different OMC for running OMPython than for running the tests omhome = os.environ["OPENMODELICAHOME"] - if rmlStyle: - omc_version = subprocess.check_output(omc_cmd + ["+version"], stderr=subprocess.STDOUT).decode("ascii").strip() - version_cmd = "+version" - print("Work-around for RML-style command-line arguments (+version)") - else: - omc_version = subprocess.check_output(omc_cmd + ["--version"], stderr=subprocess.STDOUT).decode("ascii").strip() + omc_version = subprocess.check_output(omc_cmd + ["--version"], stderr=subprocess.STDOUT).decode("ascii").strip() os.environ["OPENMODELICAHOME"] = ompython_omhome omc = OMCSessionZMQ() ompython_omc_version=omc.sendExpression('getVersion()') os.environ["OPENMODELICAHOME"] = omhome else: - omc = OMCSession(docker=docker, dockerExtraArgs=dockerExtraArgs) if corbaStyle else OMCSessionZMQ(docker=docker, dockerExtraArgs=dockerExtraArgs) + omc = OMCSessionZMQ(docker=docker, dockerExtraArgs=dockerExtraArgs) omhome=omc.sendExpression('getInstallationDirectoryPath()') omc_version=omc.sendExpression('getVersion()') ompython_omc_version=omc_version @@ -199,14 +187,8 @@ def timeSeconds(f): # Do feature checks. Handle things like old RML-style arguments... -try: - subprocess.check_output(omc_cmd + ["-n=1", version_cmd], stderr=subprocess.STDOUT).strip() - single_thread="-n=1" -except: - subprocess.check_output(omc_cmd + ["+n=1", version_cmd], stderr=subprocess.STDOUT).strip() - single_thread="+n=1" - rmlStyle=True - print("Work-around for RML-style command-line arguments (+n=1)") +subprocess.check_output(omc_cmd + ["-n=1", version_cmd], stderr=subprocess.STDOUT).strip() +single_thread="-n=1" sys.stdout.flush() @@ -225,7 +207,7 @@ def timeSeconds(f): os.unlink("HelloWorld") except OSError: pass -subprocess.check_output(omc_cmd + ["%ssimCodeTarget=Cpp" % ("+" if rmlStyle else "--"), "HelloWorld.mos"], stderr=subprocess.STDOUT) +subprocess.check_output(omc_cmd + ["--simCodeTarget=Cpp", "HelloWorld.mos"], stderr=subprocess.STDOUT) if os.path.exists("HelloWorld"): print("Have C++ HelloWorld simulation executable") haveCppRuntime=simulationAcceptsFlag("") @@ -258,7 +240,6 @@ def timeSeconds(f): defaultCustomCommands = [] if extraflags: defaultCustomCommands += [extraflags] -debug = "+d" if rmlStyle else "-d" def testHelloWorld(cmd): with open("HelloWorld.mos") as fin: @@ -277,12 +258,12 @@ def testHelloWorld(cmd): return False for cmd in [ - 'setCommandLineOptions("%s=nogen");' % debug, - 'setCommandLineOptions("%s=initialization");' % debug, - 'setCommandLineOptions("%s=backenddaeinfo");' % debug, - 'setCommandLineOptions("%s=discreteinfo");' % debug, - 'setCommandLineOptions("%s=stateselection");' % debug, - 'setCommandLineOptions("%s=execstat");' % debug, + 'setCommandLineOptions("-d=nogen");', + 'setCommandLineOptions("-d=initialization");', + 'setCommandLineOptions("-d=backenddaeinfo");', + 'setCommandLineOptions("-d=discreteinfo");', + 'setCommandLineOptions("-d=stateselection");', + 'setCommandLineOptions("-d=execstat");', 'setMatchingAlgorithm("PFPlusExt");', 'setIndexReductionMethod("dynamicStateSelection");' ]: @@ -325,7 +306,7 @@ def testHelloWorld(cmd): abortSimulationFlag="-abortSlowSimulation" if simulationAcceptsFlag("-abortSlowSimulation") else "" alarmFlag="-alarm" if simulationAcceptsFlag("-alarm=480") else "" -configs_lst = [readConfig(c, rmlStyle=rmlStyle, abortSimulationFlag=abortSimulationFlag, alarmFlag=alarmFlag, overrideDefaults=overrideDefaults, defaultCustomCommands=defaultCustomCommands, extrasimflags=extrasimflags) for c in configs] +configs_lst = [readConfig(c, abortSimulationFlag=abortSimulationFlag, alarmFlag=alarmFlag, overrideDefaults=overrideDefaults, defaultCustomCommands=defaultCustomCommands, extrasimflags=extrasimflags) for c in configs] configs = [] preparedReferenceDirs = {} for c in configs_lst: @@ -333,7 +314,7 @@ def testHelloWorld(cmd): for (lib,c) in configs: if "referenceFiles" in c: c["referenceFilesURL"] = c["referenceFiles"] - if isinstance(c["referenceFiles"], basestring): + if isinstance(c["referenceFiles"], (str, bytes)): m = re.search("^[$][A-Z]+", c["referenceFiles"]) if m: k = m.group(0)[1:] @@ -580,7 +561,7 @@ def runScript(c, timeout, memoryLimit): pass start=monotonic() # runCommand("%s %s %s.mos" % (omc_exe, single_thread, c), prefix=c, timeout=timeout) - if 0 != runCommand("ulimit -v %d; ./testmodel.py --libraries=%s %s --ompython_omhome=%s %s %s.conf.json > files/%s.cmdout 2>&1" % (memoryLimit, librariespath, ("--docker %s --dockerExtraArgs '%s'" % (docker, " ".join(dockerExtraArgs))) if docker else "", ompython_omhome, "--corba" if corbaStyle else "", c, c), prefix=c, timeout=timeout): + if 0 != runCommand("ulimit -v %d; ./testmodel.py --libraries=%s %s --ompython_omhome=%s %s.conf.json > files/%s.cmdout 2>&1" % (memoryLimit, librariespath, ("--docker %s --dockerExtraArgs '%s'" % (docker, " ".join(dockerExtraArgs))) if docker else "", ompython_omhome, c, c), prefix=c, timeout=timeout): print("files/%s.err" % c) with open("files/%s.err" % c, "a+") as errfile: errfile.write("Failed to read output from testmodel.py, exit status != 0:\n") From 92e73d92f1705558f4a1aeb0abf289787805fc64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Thu, 16 Sep 2021 21:20:02 +0200 Subject: [PATCH 004/452] import sys needs to come before feature check --- test.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test.py b/test.py index ac1b695..696dd93 100755 --- a/test.py +++ b/test.py @@ -4,10 +4,11 @@ # TODO: When libraries hash changes, run with the old OMC against the new libs # Then run with the new OMC against the new libs +import sys if (sys.version_info < (3, 0)): raise Exception("Python2 is no longer supported") -import html, shutil, sys, os, re, glob, time, argparse, sqlite3, datetime, math, platform +import html, shutil, os, re, glob, time, argparse, sqlite3, datetime, math, platform from joblib import Parallel, delayed import simplejson as json import psutil, subprocess, threading, hashlib From 94b223c8988839702e2067b3b35cdad0aa2e9582 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Fri, 17 Sep 2021 15:34:48 +0200 Subject: [PATCH 005/452] Also send email for conversions --- .CI/Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index b1e1b3c..286f287 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -358,7 +358,7 @@ pipeline { sh 'wget -q https://libraries.openmodelica.org/sqlite3/ripper1/sqlite3.db' sh './clean-empty-omcversion-dates.py' - sh "./all-reports.py --email --omcgitdir=OpenModelica ${env.GITBRANCHES}" + sh "./all-reports.py --email --omcgitdir=OpenModelica ${env.GITBRANCHES} conversion" sh "./all-plots.py ${env.GITBRANCHES}" sh "./report.py --branches='${env.GITBRANCHES}' configs/conf-c++.json" From 74c1812bd1113de9962a1c618bd7511b85986d39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Tue, 21 Sep 2021 13:25:49 +0200 Subject: [PATCH 006/452] Update path for ThermofluidStream regression files --- .CI/Jenkinsfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index 286f287..726244c 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -667,8 +667,8 @@ def test(branch, name, extraFlags, omsHash, sshConfig, omcompiler, extrasimflags REFERENCEFILES="${WORKSPACE}/OpenModelica/testsuite/ReferenceFiles" GITREPOS="${WORKSPACE}/OpenModelica/libraries/git" PNLIBREFS="/mnt/ReferenceFiles/PNlib/ReferenceFiles" - THERMOFLUIDSTREAMREFS="/mnt/ReferenceFiles/ThermofluidStream-main/ReferenceData" - THERMOFLUIDSTREAMREFSOM="/mnt/ReferenceFiles/ThermofluidStream-OM/ReferenceData" + THERMOFLUIDSTREAMREFS="/mnt/ReferenceFiles/ThermofluidStream-main-regression/ReferenceData" + THERMOFLUIDSTREAMREFSOM="/mnt/ReferenceFiles/ThermofluidStream-OM-regression/ReferenceData" sh """ test -f "${MSLREFERENCE}/MAP-LIB_ReferenceResults/v4.0.0/README.md" || exit 1 From 5f494dfb124266d12756a20a44907bf923fb5347 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Tue, 12 Oct 2021 09:25:54 +0200 Subject: [PATCH 007/452] Use 1.16.3 image for the reports --- .CI/build-dep/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.CI/build-dep/Dockerfile b/.CI/build-dep/Dockerfile index 02de218..93e3bb9 100644 --- a/.CI/build-dep/Dockerfile +++ b/.CI/build-dep/Dockerfile @@ -1,3 +1,3 @@ -FROM docker.openmodelica.org/build-deps:v1.13 +FROM docker.openmodelica.org/build-deps:v1.16.3 RUN pip3 install matplotlib From d8bd50709765d834258497f84ce4828c116bfa05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Fri, 15 Oct 2021 13:09:24 +0200 Subject: [PATCH 008/452] Decode as ascii --- test.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test.py b/test.py index 696dd93..9497478 100755 --- a/test.py +++ b/test.py @@ -41,7 +41,7 @@ def target(): while process[0].poll() is None: process[0].communicate(1) process[0].wait(1) - + thread = threading.Thread(target=target) thread.start() @@ -459,7 +459,7 @@ def hashReferenceFiles(s): except: print("Failed to load library %s %s. OpenModelica.Scripting.getErrorString() failed..." % (library,conf["libraryVersion"])) conf["loadFiles"] = sorted(omc.sendExpression("{getSourceFile(cl) for cl in getClassNames()}")) - + if not (omc.sendExpression('setCommandLineOptions("-g=MetaModelica")') or omc.sendExpression('setCommandLineOptions("+g=Modelica")')): print("Failed to set MetaModelica grammar") sys.exit(1) @@ -486,8 +486,8 @@ def hashReferenceFiles(s): if not conf["libraryVersionRevision"]: conf["libraryVersionRevision"] = conf["libraryLastChange"] if conf.get("fmi") and fmisimulatorversion: - conf["libraryVersionRevision"] = conf["libraryVersionRevision"] + " " + fmisimulatorversion - conf["libraryLastChange"] = conf["libraryLastChange"] + " " + fmisimulatorversion + conf["libraryVersionRevision"] = conf["libraryVersionRevision"] + " " + fmisimulatorversion.decode("ascii") + conf["libraryLastChange"] = conf["libraryLastChange"] + " " + fmisimulatorversion.decode("ascii") res=omc.sendExpression('{c for c guard isExperiment(c) and not regexBool(typeNameString(x), "^Modelica_Synchronous\\.WorkInProgress") in getClassNames(%s, recursive=true)}' % library) if conf.get("ignoreModelPrefix"): prefix = conf["ignoreModelPrefix"] From 0e0d365a8f5c0b92bb9c1f12c121f8e3da74db57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Wed, 20 Oct 2021 11:50:56 +0200 Subject: [PATCH 009/452] Add uses MSL 3.2.3 for TAeZoSysPro_testsuite --- conversionscript.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/conversionscript.py b/conversionscript.py index f7f1f90..0404f97 100755 --- a/conversionscript.py +++ b/conversionscript.py @@ -68,11 +68,13 @@ def convertPackage(p): latin1Data = fin.read() with open(os.path.join(root, file), "w", encoding="UTF-8") as fout: fout.write(latin1Data) - + if libname in ["Modelica", "ModelicaServices", "Complex", "ModelicaTest", "ModelicaTestOverdetermined"]: ver = libnameOnFile.split(" ")[1] if ver.startswith("1.") or ver.startswith("3."): return None + if libname in ["TAeZoSysPro_testsuite"] and "Modelica" not in uses: + uses['Modelica'] = '3.2.3' if not uses.get('Modelica','0.0.0') in convertFromVersion: return None if libname in ["Modelica", "ModelicaServices", "Complex", "ModelicaTest", "ModelicaTestOverdetermined"]: @@ -162,7 +164,7 @@ def convertPackage(p): diffOutput = subprocess.call(["diff", "-ur", os.path.dirname(p), "converted-libraries/.openmodelica/libraries/%s" % libnameOnFile], stdout=diffOut) del omc return {"errorsInDiff": errorsInDiff, "path": path, "timeForConversion": timeForConversion, "statsByFile": statsByFile, "gcProfStatsBeforeConversion": gcProfStatsBeforeConversion, "gcProfStatsBefore": gcProfStatsBefore, "gcProfStats": gcProfStats} - + pat = "%s/*/openmodelica.metadata.json" % libdir with Pool(processes=numThreads) as pool: res = pool.map(convertPackage, sorted(glob.glob(pat))) From 5fc7303b23175720db78c82179ba26e4ac216127 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Fri, 22 Oct 2021 09:14:37 +0200 Subject: [PATCH 010/452] Use a database prefix --- .CI/Jenkinsfile | 66 ++++++++++++++++++++++++------------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index 726244c..5030fed 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -45,7 +45,7 @@ pipeline { expression { params.v1_12 } } steps { - test('maintenance/v1.12', 'v1.12', '', '', 'LibraryTestingRipper1DB', true, '', true, false) + test('maintenance/v1.12', 'v1.12', '', '', 'ripper1', 'LibraryTestingRipper1DB', true, '', true, false) } } @@ -62,7 +62,7 @@ pipeline { expression { params.v1_13 } } steps { - test('maintenance/v1.13', 'v1.13', '', '', 'LibraryTestingRipper1DB', true, '', true, false) + test('maintenance/v1.13', 'v1.13', '', '', 'ripper1', 'LibraryTestingRipper1DB', true, '', true, false) } } @@ -79,7 +79,7 @@ pipeline { expression { params.v1_14 } } steps { - test('maintenance/v1.14', 'v1.14', '', '', 'LibraryTestingRipper1DB', false, '', true, false) + test('maintenance/v1.14', 'v1.14', '', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', true, false) } } @@ -96,7 +96,7 @@ pipeline { expression { params.v1_16 } } steps { - test('maintenance/v1.16', 'v1.16', '', '', 'LibraryTestingRipper1DB', false, '', false, false) + test('maintenance/v1.16', 'v1.16', '', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', false, false) } } @@ -113,7 +113,7 @@ pipeline { expression { params.v1_17 } } steps { - test('maintenance/v1.17', 'v1.17', '', '', 'LibraryTestingRipper1DB', false, '', false, false) + test('maintenance/v1.17', 'v1.17', '', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', false, false) } } @@ -130,7 +130,7 @@ pipeline { expression { params.v1_18 } } steps { - test('maintenance/v1.18', 'v1.18', '', '', 'LibraryTestingRipper1DB', false, '', false, false) + test('maintenance/v1.18', 'v1.18', '', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', false, false) } } @@ -147,7 +147,7 @@ pipeline { expression { params.master } } steps { - test('master', 'master', '', '', 'LibraryTestingRipper1DB', false, '', false, false) + test('master', 'master', '', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', false, false) } } @@ -164,7 +164,7 @@ pipeline { expression { params.conversion_script } } steps { - test('master', 'conversion', '', '', 'LibraryTestingRipper1DB', false, '', false, true) + test('master', 'conversion', '', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', false, true) } } @@ -181,7 +181,7 @@ pipeline { expression { params.fmi_v1_12 } } steps { - test('maintenance/v1.12', 'v1.12-fmi', '', omsimulatorHash(), 'LibraryTestingRipper2DB', true, '', true, false) + test('maintenance/v1.12', 'v1.12-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', true, '', true, false) } } stage('v1.13 FMI') { @@ -197,7 +197,7 @@ pipeline { expression { params.fmi_v1_13 } } steps { - test('maintenance/v1.13', 'v1.13-fmi', '', omsimulatorHash(), 'LibraryTestingRipper2DB', true, '', true, false) + test('maintenance/v1.13', 'v1.13-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', true, '', true, false) } } stage('v1.14 FMI') { @@ -213,7 +213,7 @@ pipeline { expression { params.fmi_v1_14 } } steps { - test('maintenance/v1.14', 'v1.14-fmi', '', omsimulatorHash(), 'LibraryTestingRipper2DB', false, '', true, false) + test('maintenance/v1.14', 'v1.14-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', false, '', true, false) } } stage('v1.16 FMI') { @@ -229,7 +229,7 @@ pipeline { expression { params.fmi_v1_16 } } steps { - test('maintenance/v1.16', 'v1.16-fmi', '', omsimulatorHash(), 'LibraryTestingRipper2DB', false, '', false, false) + test('maintenance/v1.16', 'v1.16-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) } } stage('v1.17 FMI') { @@ -245,7 +245,7 @@ pipeline { expression { params.fmi_v1_17 } } steps { - test('maintenance/v1.17', 'v1.17-fmi', '', omsimulatorHash(), 'LibraryTestingRipper2DB', false, '', false, false) + test('maintenance/v1.17', 'v1.17-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) } } stage('v1.18 FMI') { @@ -261,7 +261,7 @@ pipeline { expression { params.fmi_v1_18 } } steps { - test('maintenance/v1.18', 'v1.18-fmi', '', omsimulatorHash(), 'LibraryTestingRipper2DB', false, '', false, false) + test('maintenance/v1.18', 'v1.18-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) } } stage('master FMI') { @@ -277,7 +277,7 @@ pipeline { expression { params.fmi_master } } steps { - test('master', 'master-fmi', '', 'origin/master', 'LibraryTestingRipper2DB', false, '', false, false) + test('master', 'master-fmi', '', 'origin/master', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) } } stage('newInst-daeMode') { @@ -293,7 +293,7 @@ pipeline { expression { params.newInst_daeMode } } steps { - test('master', 'newInst-daeMode', 'setCommandLineOptions("-d=newInst,-frontEndUnitCheck --daeMode=true")', '', 'LibraryTestingRipper2DB', false, '', false, false) + test('master', 'newInst-daeMode', 'setCommandLineOptions("-d=newInst,-frontEndUnitCheck --daeMode=true")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) } } stage('oldInst') { @@ -309,7 +309,7 @@ pipeline { expression { params.oldInst } } steps { - test('master', 'oldInst', 'setCommandLineOptions("-d=nonewInst")', '', 'LibraryTestingRipper2DB', false, '', false, false) + test('master', 'oldInst', 'setCommandLineOptions("-d=nonewInst")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) } } stage('cvode') { @@ -325,7 +325,7 @@ pipeline { expression { params.cvode } } steps { - test('master', 'cvode', 'setCommandLineOptions("-d=newInst,-frontEndUnitCheck")', '', 'LibraryTestingRipper2DB', false, '-s cvode', false, false) + test('master', 'cvode', 'setCommandLineOptions("-d=newInst,-frontEndUnitCheck")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '-s cvode', false, false) } } } } @@ -462,10 +462,10 @@ pipeline { } } stage('cleanup') { parallel { // The cleanup is needed because we can't save the cleanup done in the report stage - stage('lib') { + stage('ripper1') { agent { node { - label 'libraries.openmodelica.org' + label 'ripper.openmodelica.org' } } when { @@ -473,9 +473,9 @@ pipeline { expression { params.v1_12 || params.v1_13 || params.v1_14 || params.v1_16 || params.v1_17 || params.master || params.report_ripper1 } } steps { - sh 'cp ~/TEST_LIBS_BACKUP/sqlite3.db .' + sh 'cp ~/TEST_LIBS_BACKUP/ripper1-sqlite3.db sqlite3.db' sh './clean-empty-omcversion-dates.py' - sh 'cp sqlite3.db ~/TEST_LIBS_BACKUP/' + sh 'cp sqlite3.db ~/TEST_LIBS_BACKUP/ripper1-sqlite3.db' } } stage('ripper2') { @@ -489,9 +489,9 @@ pipeline { expression { params.fmi_v1_12 || params.fmi_v1_13 || params.fmi_v1_14 || params.fmi_v1_16 || params.fmi_v1_17 || params.fmi_master || params.newInst_daeMode || params.oldInst || params.report_ripper2 } } steps { - sh 'cp ~/TEST_LIBS_BACKUP/sqlite3.db .' + sh 'cp ~/TEST_LIBS_BACKUP/ripper2-sqlite3.db sqlite3.db' sh './clean-empty-omcversion-dates.py' - sh 'cp sqlite3.db ~/TEST_LIBS_BACKUP/' + sh 'cp ripper2-sqlite3.db ~/TEST_LIBS_BACKUP/ripper2-sqlite3.db' } } } } @@ -522,11 +522,11 @@ def installLibraries(boolean removePackageOrder, boolean conversionScript, name, return "${env.HOME}/saved_omc/libraries" } } -def test(branch, name, extraFlags, omsHash, sshConfig, omcompiler, extrasimflags, boolean removePackageOrder, boolean conversionScript) { +def test(branch, name, extraFlags, omsHash, dbPrefix, sshConfig, omcompiler, extrasimflags, boolean removePackageOrder, boolean conversionScript) { sh ''' find /tmp -name "*openmodelica.hudson*" -exec rm {} ";" || true mkdir -p ~/TEST_LIBS_BACKUP - find ~/TEST_LIBS_BACKUP -name sqlite3.*.db -mtime +7 -exec rm {} ";" + find ~/TEST_LIBS_BACKUP -name *sqlite3.*.db -mtime +7 -exec rm {} ";" if test -z "$WORKSPACE"; then echo "Odd workspace" @@ -687,10 +687,10 @@ def test(branch, name, extraFlags, omsHash, sshConfig, omcompiler, extrasimflags sh "test -d '${libraryPath}/.openmodelica/libraries/Modelica trunk'" - sh ''' - cp ~/TEST_LIBS_BACKUP/sqlite3.db OpenModelicaLibraryTesting/sqlite3.db + sh """ + cp ~/TEST_LIBS_BACKUP/${dbPrefix}-sqlite3.db OpenModelicaLibraryTesting/sqlite3.db test -s OpenModelicaLibraryTesting/sqlite3.db - ''' + """ sh 'date' @@ -708,11 +708,11 @@ def test(branch, name, extraFlags, omsHash, sshConfig, omcompiler, extrasimflags stdbuf -oL -eL time ./test.py --ompython_omhome=/usr ${FMI_TESTING_FLAG} --extraflags='${extraFlags}' --extrasimflags='${extrasimflags}' --branch="${name}" --output="libraries.openmodelica.org:/var/www/branches/${name}/" --libraries='${libraryPath}/.openmodelica/libraries/' configs/conf.json ${conversionScript ? "" : "configs/conf-c++.json"} ${params.OLD_LIBS ? "configs/conf-old.json configs/conf-nonstandard.json" : ""} || (killall omc ; false) || exit 1 """ sh 'date' - sh 'rm -f OpenModelicaLibraryTesting/sqlite3.db.tmp' - sh 'ln OpenModelicaLibraryTesting/sqlite3.db OpenModelicaLibraryTesting/sqlite3.db.tmp' + sh "rm -f OpenModelicaLibraryTesting/${dbPrefix}-sqlite3.db.tmp" + sh "ln OpenModelicaLibraryTesting/sqlite3.db OpenModelicaLibraryTesting/${dbPrefix}-sqlite3.db.tmp" - sh 'cp OpenModelicaLibraryTesting/sqlite3.db ~/TEST_LIBS_BACKUP/sqlite3.db' - sh 'rm -f ~/TEST_LIBS_BACKUP/`date +sqlite3.%Y%m%d.db`' + sh "cp OpenModelicaLibraryTesting/sqlite3.db ~/TEST_LIBS_BACKUP/${dbPrefix}-sqlite3.db" + sh "rm -f ~/TEST_LIBS_BACKUP/${dbPrefix}-`date +sqlite3.%Y%m%d.db`" sshPublisher(publishers: [sshPublisherDesc(configName: sshConfig, transfers: [sshTransfer(removePrefix: 'OpenModelicaLibraryTesting', sourceFiles: 'OpenModelicaLibraryTesting/sqlite3.db', failOnError: true)])]) From b1508e2f43880f5ac29722fcb8976959a2e5753c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Fri, 22 Oct 2021 09:25:10 +0200 Subject: [PATCH 011/452] Automatically download the database if missing --- .CI/Jenkinsfile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index 5030fed..bf4e6fe 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -688,6 +688,10 @@ def test(branch, name, extraFlags, omsHash, dbPrefix, sshConfig, omcompiler, ext sh "test -d '${libraryPath}/.openmodelica/libraries/Modelica trunk'" sh """ + if ! test -f ~/TEST_LIBS_BACKUP/${dbPrefix}-sqlite3.db; then + wget -O ~/TEST_LIBS_BACKUP/${dbPrefix}-sqlite3.db.tmp -q https://libraries.openmodelica.org/sqlite3/${dbPrefix}/sqlite3.db + mv ~/TEST_LIBS_BACKUP/${dbPrefix}-sqlite3.db.tmp ~/TEST_LIBS_BACKUP/${dbPrefix}-sqlite3.db + fi cp ~/TEST_LIBS_BACKUP/${dbPrefix}-sqlite3.db OpenModelicaLibraryTesting/sqlite3.db test -s OpenModelicaLibraryTesting/sqlite3.db """ From c5e7337f01939e420eac529480be5b8d9a69b59a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Thu, 28 Oct 2021 14:39:43 +0200 Subject: [PATCH 012/452] [Jenkins] Fix copying the cleanup of the database --- .CI/Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index bf4e6fe..fb49a01 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -491,7 +491,7 @@ pipeline { steps { sh 'cp ~/TEST_LIBS_BACKUP/ripper2-sqlite3.db sqlite3.db' sh './clean-empty-omcversion-dates.py' - sh 'cp ripper2-sqlite3.db ~/TEST_LIBS_BACKUP/ripper2-sqlite3.db' + sh 'cp sqlite3.db ~/TEST_LIBS_BACKUP/ripper2-sqlite3.db' } } } } From 47df691278962c751aa6009fda7f2a3fad3670bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Fri, 29 Oct 2021 13:16:47 +0200 Subject: [PATCH 013/452] Fix error on uses --- conversionscript.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/conversionscript.py b/conversionscript.py index 0404f97..99d00dd 100755 --- a/conversionscript.py +++ b/conversionscript.py @@ -75,6 +75,7 @@ def convertPackage(p): return None if libname in ["TAeZoSysPro_testsuite"] and "Modelica" not in uses: uses['Modelica'] = '3.2.3' + data['uses'] = uses if not uses.get('Modelica','0.0.0') in convertFromVersion: return None if libname in ["Modelica", "ModelicaServices", "Complex", "ModelicaTest", "ModelicaTestOverdetermined"]: @@ -144,7 +145,7 @@ def convertPackage(p): errStr = omc.sendExpression("getErrorString()") if errStr: print(errStr) - raise Exception('echo(false);before:=readFile("%s");\nafter:=readFile("%s");echo(true);\ndiffModelicaFileListings(before, after, OpenModelica.Scripting.DiffFormat.plain, failOnSemanticsChange=true);\ngetErrorString();' % (oldFile, newFile)) + raise Exception('--allowErrorsInDiff is not active:\necho(false);before:=readFile("%s");\nafter:=readFile("%s");echo(true);\ndiffModelicaFileListings(before, after, OpenModelica.Scripting.DiffFormat.plain, failOnSemanticsChange=true);\ngetErrorString();' % (oldFile, newFile)) else: omcAssert(omc, 'writeFile("%s", res)' % (newFile)) isDiff = before != res From 5ff4291177bec03a275756a54634211842a2f368 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20=C3=96stlund?= Date: Mon, 1 Nov 2021 16:08:37 +0100 Subject: [PATCH 014/452] Set default libraries folder --- test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test.py b/test.py index 9497478..9645556 100755 --- a/test.py +++ b/test.py @@ -92,7 +92,7 @@ def target(): parser.add_argument('--fmi', default=False) parser.add_argument('--output', default='') parser.add_argument('--docker', default='') -parser.add_argument('--libraries', default='') +parser.add_argument('--libraries', default=os.path.expanduser('~/.openmodelica/libraries/')) parser.add_argument('--extraflags', default='') parser.add_argument('--extrasimflags', default='') parser.add_argument('--ompython_omhome', default='') From 6c0e293cf9711f77006d66e7549c1cd2a4d58de9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Wed, 3 Nov 2021 09:40:08 +0100 Subject: [PATCH 015/452] Fix for OLD_LIBS vs OLDLIBS --- .CI/Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index fb49a01..4a3cc1d 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -709,7 +709,7 @@ def test(branch, name, extraFlags, omsHash, dbPrefix, sshConfig, omcompiler, ext export HOME="${libraryPath}" cd OpenModelicaLibraryTesting # Force /usr/bin/omc as being used for generating the mos-files. Ensures consistent behavior among all tested OMC versions - stdbuf -oL -eL time ./test.py --ompython_omhome=/usr ${FMI_TESTING_FLAG} --extraflags='${extraFlags}' --extrasimflags='${extrasimflags}' --branch="${name}" --output="libraries.openmodelica.org:/var/www/branches/${name}/" --libraries='${libraryPath}/.openmodelica/libraries/' configs/conf.json ${conversionScript ? "" : "configs/conf-c++.json"} ${params.OLD_LIBS ? "configs/conf-old.json configs/conf-nonstandard.json" : ""} || (killall omc ; false) || exit 1 + stdbuf -oL -eL time ./test.py --ompython_omhome=/usr ${FMI_TESTING_FLAG} --extraflags='${extraFlags}' --extrasimflags='${extrasimflags}' --branch="${name}" --output="libraries.openmodelica.org:/var/www/branches/${name}/" --libraries='${libraryPath}/.openmodelica/libraries/' configs/conf.json ${conversionScript ? "" : "configs/conf-c++.json"} ${params.OLDLIBS ? "configs/conf-old.json configs/conf-nonstandard.json" : ""} || (killall omc ; false) || exit 1 """ sh 'date' sh "rm -f OpenModelicaLibraryTesting/${dbPrefix}-sqlite3.db.tmp" From 1bce0a25e66ee163253625b905bbd1e0322b937d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Fri, 5 Nov 2021 20:26:30 +0100 Subject: [PATCH 016/452] Change labels to ryzen instead of ripper --- .CI/Jenkinsfile | 84 ++++++++++++++++++++++++------------------------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index 4a3cc1d..50a1678 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -3,28 +3,28 @@ pipeline { parameters { booleanParam(name: 'OLDLIBS', defaultValue: false, description: 'Also test some outdated libraries') - booleanParam(name: 'v1_12', defaultValue: false, description: 'maintenance/v1.12 branch (ripper1)') - booleanParam(name: 'v1_13', defaultValue: false, description: 'maintenance/v1.13 branch (ripper1)') - booleanParam(name: 'v1_14', defaultValue: false, description: 'maintenance/v1.14 branch (ripper1)') - booleanParam(name: 'v1_16', defaultValue: false, description: 'maintenance/v1.16 branch (ripper1)') - booleanParam(name: 'v1_17', defaultValue: false, description: 'maintenance/v1.17 branch (ripper1)') - booleanParam(name: 'v1_18', defaultValue: false, description: 'maintenance/v1.18 branch (ripper1)') - booleanParam(name: 'master', defaultValue: false, description: 'master branch (ripper1)') - - booleanParam(name: 'fmi_v1_12', defaultValue: false, description: 'maintenance/v1.12 branch with FMI (ripper2)') - booleanParam(name: 'fmi_v1_13', defaultValue: false, description: 'maintenance/v1.13 branch with FMI (ripper2)') - booleanParam(name: 'fmi_v1_14', defaultValue: false, description: 'maintenance/v1.14 branch with FMI (ripper2)') - booleanParam(name: 'fmi_v1_16', defaultValue: false, description: 'maintenance/v1.16 branch with FMI (ripper2)') - booleanParam(name: 'fmi_v1_17', defaultValue: false, description: 'maintenance/v1.17 branch with FMI (ripper2)') - booleanParam(name: 'fmi_v1_18', defaultValue: false, description: 'maintenance/v1.18 branch with FMI (ripper2)') - booleanParam(name: 'fmi_master', defaultValue: false, description: 'master branch with FMI (ripper2)') - booleanParam(name: 'newInst_daeMode', defaultValue: false, description: 'master branch, --daeMode with -d=newInst (ripper2)') - booleanParam(name: 'oldInst', defaultValue: false, description: 'master branch, with -d=nonewInst (ripper2)') - booleanParam(name: 'report_ripper1', defaultValue: false, description: 'Generate a report for ripper1 without running the tests') - booleanParam(name: 'report_ripper2', defaultValue: false, description: 'Generate a report for ripper2 without running the tests') - - booleanParam(name: 'conversion_script', defaultValue: false, description: 'master branch with conversion script from MSL 3 to 4 (ripper1). This is an experimental job that does not run on a fixed schedule.') - booleanParam(name: 'cvode', defaultValue: false, description: 'master branch, with -d=newInst and -s cvode (ripper2). This is an experimental job that does not run on a fixed schedule.') + booleanParam(name: 'v1_12', defaultValue: false, description: 'maintenance/v1.12 branch (ryzen-5950x-1)') + booleanParam(name: 'v1_13', defaultValue: false, description: 'maintenance/v1.13 branch (ryzen-5950x-1)') + booleanParam(name: 'v1_14', defaultValue: false, description: 'maintenance/v1.14 branch (ryzen-5950x-1)') + booleanParam(name: 'v1_16', defaultValue: false, description: 'maintenance/v1.16 branch (ryzen-5950x-1)') + booleanParam(name: 'v1_17', defaultValue: false, description: 'maintenance/v1.17 branch (ryzen-5950x-1)') + booleanParam(name: 'v1_18', defaultValue: false, description: 'maintenance/v1.18 branch (ryzen-5950x-1)') + booleanParam(name: 'master', defaultValue: false, description: 'master branch (ryzen-5950x-1)') + + booleanParam(name: 'fmi_v1_12', defaultValue: false, description: 'maintenance/v1.12 branch with FMI (ryzen-5950x-2)') + booleanParam(name: 'fmi_v1_13', defaultValue: false, description: 'maintenance/v1.13 branch with FMI (ryzen-5950x-2)') + booleanParam(name: 'fmi_v1_14', defaultValue: false, description: 'maintenance/v1.14 branch with FMI (ryzen-5950x-2)') + booleanParam(name: 'fmi_v1_16', defaultValue: false, description: 'maintenance/v1.16 branch with FMI (ryzen-5950x-2)') + booleanParam(name: 'fmi_v1_17', defaultValue: false, description: 'maintenance/v1.17 branch with FMI (ryzen-5950x-2)') + booleanParam(name: 'fmi_v1_18', defaultValue: false, description: 'maintenance/v1.18 branch with FMI (ryzen-5950x-2)') + booleanParam(name: 'fmi_master', defaultValue: false, description: 'master branch with FMI (ryzen-5950x-2)') + booleanParam(name: 'newInst_daeMode', defaultValue: false, description: 'master branch, --daeMode with -d=newInst (ryzen-5950x-2)') + booleanParam(name: 'oldInst', defaultValue: false, description: 'master branch, with -d=nonewInst (ryzen-5950x-2)') + booleanParam(name: 'report_ryzen_5950x_1', defaultValue: false, description: 'Generate a report for ryzen-5950x-1 without running the tests') + booleanParam(name: 'report_ryzen-5950x-2', defaultValue: false, description: 'Generate a report for ryzen-5950x-2 without running the tests') + + booleanParam(name: 'conversion_script', defaultValue: false, description: 'master branch with conversion script from MSL 3 to 4 (ryzen-5950x-1). This is an experimental job that does not run on a fixed schedule.') + booleanParam(name: 'cvode', defaultValue: false, description: 'master branch, with -d=newInst and -s cvode (ryzen-5950x-2). This is an experimental job that does not run on a fixed schedule.') } environment { LC_ALL = 'C.UTF-8' @@ -35,7 +35,7 @@ pipeline { stage('v1.12') { agent { node { - label 'ripper.openmodelica.org' + label 'ryzen-5950x-1' customWorkspace 'ws/OpenModelicaLibraryTestingWork' } } @@ -52,7 +52,7 @@ pipeline { stage('v1.13') { agent { node { - label 'ripper.openmodelica.org' + label 'ryzen-5950x-1' customWorkspace 'ws/OpenModelicaLibraryTestingWork' } } @@ -69,7 +69,7 @@ pipeline { stage('v1.14') { agent { node { - label 'ripper.openmodelica.org' + label 'ryzen-5950x-1' customWorkspace 'ws/OpenModelicaLibraryTestingWork' } } @@ -86,7 +86,7 @@ pipeline { stage('v1.16') { agent { node { - label 'ripper.openmodelica.org' + label 'ryzen-5950x-1' customWorkspace 'ws/OpenModelicaLibraryTestingWork' } } @@ -103,7 +103,7 @@ pipeline { stage('v1.17') { agent { node { - label 'ripper.openmodelica.org' + label 'ryzen-5950x-1' customWorkspace 'ws/OpenModelicaLibraryTestingWork' } } @@ -120,7 +120,7 @@ pipeline { stage('v1.18') { agent { node { - label 'ripper.openmodelica.org' + label 'ryzen-5950x-1' customWorkspace 'ws/OpenModelicaLibraryTestingWork' } } @@ -137,7 +137,7 @@ pipeline { stage('master') { agent { node { - label 'ripper.openmodelica.org' + label 'ryzen-5950x-1' customWorkspace 'ws/OpenModelicaLibraryTestingWork' } } @@ -154,7 +154,7 @@ pipeline { stage('conversion script') { agent { node { - label 'ripper.openmodelica.org' + label 'ryzen-5950x-1' customWorkspace 'ws/OpenModelicaLibraryTestingWork' } } @@ -171,7 +171,7 @@ pipeline { stage('v1.12 FMI') { agent { node { - label 'ripper2-1' + label 'ryzen-5950x-2-1' customWorkspace 'ws/OpenModelicaLibraryTestingWork' } } @@ -187,7 +187,7 @@ pipeline { stage('v1.13 FMI') { agent { node { - label 'ripper2-1' + label 'ryzen-5950x-2-1' customWorkspace 'ws/OpenModelicaLibraryTestingWork' } } @@ -203,7 +203,7 @@ pipeline { stage('v1.14 FMI') { agent { node { - label 'ripper2-1' + label 'ryzen-5950x-2-1' customWorkspace 'ws/OpenModelicaLibraryTestingWork' } } @@ -219,7 +219,7 @@ pipeline { stage('v1.16 FMI') { agent { node { - label 'ripper2-1' + label 'ryzen-5950x-2-1' customWorkspace 'ws/OpenModelicaLibraryTestingWork' } } @@ -235,7 +235,7 @@ pipeline { stage('v1.17 FMI') { agent { node { - label 'ripper2-1' + label 'ryzen-5950x-2-1' customWorkspace 'ws/OpenModelicaLibraryTestingWork' } } @@ -251,7 +251,7 @@ pipeline { stage('v1.18 FMI') { agent { node { - label 'ripper2-1' + label 'ryzen-5950x-2-1' customWorkspace 'ws/OpenModelicaLibraryTestingWork' } } @@ -267,7 +267,7 @@ pipeline { stage('master FMI') { agent { node { - label 'ripper2-1' + label 'ryzen-5950x-2-1' customWorkspace 'ws/OpenModelicaLibraryTestingWork' } } @@ -283,7 +283,7 @@ pipeline { stage('newInst-daeMode') { agent { node { - label 'ripper2-1' + label 'ryzen-5950x-2-1' customWorkspace 'ws/OpenModelicaLibraryTestingWork' } } @@ -299,7 +299,7 @@ pipeline { stage('oldInst') { agent { node { - label 'ripper2-1' + label 'ryzen-5950x-2-1' customWorkspace 'ws/OpenModelicaLibraryTestingWork' } } @@ -315,7 +315,7 @@ pipeline { stage('cvode') { agent { node { - label 'ripper2-1' + label 'ryzen-5950x-2-1' customWorkspace 'ws/OpenModelicaLibraryTestingWork' } } @@ -465,7 +465,7 @@ pipeline { stage('ripper1') { agent { node { - label 'ripper.openmodelica.org' + label 'ryzen-5950x-1' } } when { @@ -481,7 +481,7 @@ pipeline { stage('ripper2') { agent { node { - label 'ripper2-1' + label 'ryzen-5950x-2-1' } } when { From b1b01a6807a9762a088f4981a3c32300b739ed8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Mon, 8 Nov 2021 14:14:39 +0100 Subject: [PATCH 017/452] Test Buildings 8.0.x instead of 8.0.0 --- .CI/installLibraries.mos | 2 +- configs/conf.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.CI/installLibraries.mos b/.CI/installLibraries.mos index e9004a6..08562b2 100644 --- a/.CI/installLibraries.mos +++ b/.CI/installLibraries.mos @@ -9,7 +9,7 @@ for v in {"3.2.1","3.2.2","3.2.3","4.0.0","trunk"} loop exit(1); end if; end for; -for v in {"1.6", "3.0.0", "maint.7.0.x", "8.0.0", "master"} loop +for v in {"1.6", "3.0.0", "maint.7.0.x", "maint.8.0.x", "master"} loop if not installPackage(Buildings, v) then print("Buildings " + v + " " + getErrorString() + "\n"); exit(1); diff --git a/configs/conf.json b/configs/conf.json index 88bef18..157d5dc 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -126,7 +126,7 @@ { "library":"Buildings", "ignoreModelPrefix":"Buildings.Utilities.IO.BCVTB.Examples", - "libraryVersion":"8.0.0", + "libraryVersion":"maint.8.0.x", "libraryVersionLatestInPackageManager":true }, { From d1ad10217be19e6870a09bf92ce35855be2601c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Fri, 12 Nov 2021 13:40:12 +0100 Subject: [PATCH 018/452] Test M_LS2 development branch --- .CI/installLibraries.mos | 2 +- configs/conf-nonstandard.json | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.CI/installLibraries.mos b/.CI/installLibraries.mos index 08562b2..3b2d6ae 100644 --- a/.CI/installLibraries.mos +++ b/.CI/installLibraries.mos @@ -23,7 +23,7 @@ for lib in {"AdvancedNoise", "AixLib", "BioChem", "BuildingSystems", "BuildSysPr end if; end for; -for l in {{"AES", "main"}, {"Annex60", ""}, {"ExtendedPetriNets", ""}, {"iPSL", ""}, {"PhotoVoltaics", ""}, {"PhotoVoltaics_TGM", ""}, {"PowerSystems","master"}, {"PowerSystems",""}, {"SiemensPower",""}, {"SiemensPower","OMCtest"}, {"Modelica_StateGraph2", ""}, {"OpenIPSL", ""}, {"Physiomodel", ""}, {"ThermofluidStream", "main"}, {"ThermofluidStream", "0.2.0-OM_adaptions"}, {"TILMedia", "ClaRa"}} loop +for l in {{"AES", "main"}, {"Annex60", ""}, {"ExtendedPetriNets", ""}, {"iPSL", ""}, {"PhotoVoltaics", ""}, {"PhotoVoltaics_TGM", ""}, {"PowerSystems","master"}, {"PowerSystems",""}, {"SiemensPower",""}, {"SiemensPower","OMCtest"}, {"Modelica_LinearSystems2", "dev"}, {"Modelica_StateGraph2", ""}, {"OpenIPSL", ""}, {"Physiomodel", ""}, {"ThermofluidStream", "main"}, {"ThermofluidStream", "0.2.0-OM_adaptions"}, {"TILMedia", "ClaRa"}} loop if not installPackage(stringTypeName(l[1]), l[2]) then print(l[1] + " " + l[2] + getErrorString() + "\n"); exit(1); diff --git a/configs/conf-nonstandard.json b/configs/conf-nonstandard.json index 435f885..8c2b19b 100644 --- a/configs/conf-nonstandard.json +++ b/configs/conf-nonstandard.json @@ -2,6 +2,10 @@ { "library":"Modelica_LinearSystems2" }, + { + "library":"Modelica_LinearSystems2", + "libraryVersion":"dev" + }, { "library":"Modelica_StateGraph2" } From 4b80bd4f9e66428dc6e93ad18bdef8def3aeefab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Fri, 19 Nov 2021 07:40:15 +0100 Subject: [PATCH 019/452] Test Physiomodel master instead of latest release Releases are very rare for the library. --- .CI/installLibraries.mos | 2 +- configs/conf-nonstandard.json | 10 +++++++++- configs/conf.json | 10 +++------- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/.CI/installLibraries.mos b/.CI/installLibraries.mos index 3b2d6ae..26e51cf 100644 --- a/.CI/installLibraries.mos +++ b/.CI/installLibraries.mos @@ -23,7 +23,7 @@ for lib in {"AdvancedNoise", "AixLib", "BioChem", "BuildingSystems", "BuildSysPr end if; end for; -for l in {{"AES", "main"}, {"Annex60", ""}, {"ExtendedPetriNets", ""}, {"iPSL", ""}, {"PhotoVoltaics", ""}, {"PhotoVoltaics_TGM", ""}, {"PowerSystems","master"}, {"PowerSystems",""}, {"SiemensPower",""}, {"SiemensPower","OMCtest"}, {"Modelica_LinearSystems2", "dev"}, {"Modelica_StateGraph2", ""}, {"OpenIPSL", ""}, {"Physiomodel", ""}, {"ThermofluidStream", "main"}, {"ThermofluidStream", "0.2.0-OM_adaptions"}, {"TILMedia", "ClaRa"}} loop +for l in {{"AES", "main"}, {"Annex60", ""}, {"ExtendedPetriNets", ""}, {"iPSL", ""}, {"PhotoVoltaics", ""}, {"PhotoVoltaics_TGM", ""}, {"PowerSystems","master"}, {"PowerSystems",""}, {"SiemensPower",""}, {"SiemensPower","OMCtest"}, {"Modelica_LinearSystems2", "dev"}, {"Modelica_StateGraph2", ""}, {"OpenIPSL", ""}, {"Physiomodel", "master"}, {"ThermofluidStream", "main"}, {"ThermofluidStream", "0.2.0-OM_adaptions"}, {"TILMedia", "ClaRa"}} loop if not installPackage(stringTypeName(l[1]), l[2]) then print(l[1] + " " + l[2] + getErrorString() + "\n"); exit(1); diff --git a/configs/conf-nonstandard.json b/configs/conf-nonstandard.json index 8c2b19b..96fe190 100644 --- a/configs/conf-nonstandard.json +++ b/configs/conf-nonstandard.json @@ -1,6 +1,14 @@ [ { - "library":"Modelica_LinearSystems2" + "library":"FCSys" + }, + { + "library":"IdealizedContact" + }, + { + "library":"Modelica_LinearSystems2", + "libraryVersionNameForTests":"", + "libraryVersion":"master" }, { "library":"Modelica_LinearSystems2", diff --git a/configs/conf.json b/configs/conf.json index 157d5dc..909509c 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -172,9 +172,6 @@ { "library":"FastBuildings" }, - { - "library":"FCSys" - }, { "library":"HanserModelica" }, @@ -186,9 +183,6 @@ { "library":"IndustrialControlSystems" }, - { - "library":"IdealizedContact" - }, { "library":"KeyWordIO" }, @@ -236,7 +230,9 @@ "library":"Physiolibrary" }, { - "library":"Physiomodel" + "library":"Physiomodel", + "libraryVersion":"master", + "libraryVersionNameForTests":"" }, { "library":"PlanarMechanics" From 4a8099d2d3067bf16a3246753add69f6a54a51ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20=C3=96stlund?= Date: Fri, 19 Nov 2021 16:23:21 +0100 Subject: [PATCH 020/452] Update conversion testing - Change convertPackage => runConversionScript (#8169) --- conversionscript.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/conversionscript.py b/conversionscript.py index 99d00dd..a2500c0 100755 --- a/conversionscript.py +++ b/conversionscript.py @@ -92,8 +92,8 @@ def convertPackage(p): raise Exception("Expected to have loaded %s but got %s" % (libnameOnFileFullPath, loadedFilePath)) gcProfStatsBeforeConversion = omc.sendExpression("GC_get_prof_stats()") timeBeforeConvert = time.time() - omcAssert(omc, 'convertPackage(%s, "%s")' % (libname, conversionScript)) - print("convertPackage(%s, %s) OK" % (libnameOnFile, conversionScript)) + omcAssert(omc, 'runConversionScript(%s, "%s")' % (libname, conversionScript)) + print("runConversionScript(%s, %s) OK" % (libnameOnFile, conversionScript)) uses = data["uses"] for (n,v) in data["uses"].items(): if n in ["Modelica", "ModelicaServices", "Complex"]: From 188c3e02d11ec85d53226beddbb731a1240dee27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Tue, 23 Nov 2021 09:44:45 +0100 Subject: [PATCH 021/452] Do not install Physiomodel master as its dependencies are broken --- .CI/installLibraries.mos | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/.CI/installLibraries.mos b/.CI/installLibraries.mos index 26e51cf..9636fb1 100644 --- a/.CI/installLibraries.mos +++ b/.CI/installLibraries.mos @@ -23,7 +23,25 @@ for lib in {"AdvancedNoise", "AixLib", "BioChem", "BuildingSystems", "BuildSysPr end if; end for; -for l in {{"AES", "main"}, {"Annex60", ""}, {"ExtendedPetriNets", ""}, {"iPSL", ""}, {"PhotoVoltaics", ""}, {"PhotoVoltaics_TGM", ""}, {"PowerSystems","master"}, {"PowerSystems",""}, {"SiemensPower",""}, {"SiemensPower","OMCtest"}, {"Modelica_LinearSystems2", "dev"}, {"Modelica_StateGraph2", ""}, {"OpenIPSL", ""}, {"Physiomodel", "master"}, {"ThermofluidStream", "main"}, {"ThermofluidStream", "0.2.0-OM_adaptions"}, {"TILMedia", "ClaRa"}} loop +for l in { + {"AES", "main"}, + {"Annex60", ""}, + {"ExtendedPetriNets", ""}, + {"iPSL", ""}, + {"PhotoVoltaics", ""}, + {"PhotoVoltaics_TGM", ""}, + {"PowerSystems","master"}, + {"PowerSystems",""}, + {"SiemensPower",""}, + {"SiemensPower","OMCtest"}, + {"Modelica_LinearSystems2", "dev"}, + {"Modelica_StateGraph2", ""}, + {"OpenIPSL", ""}, + {"Physiomodel", ""}, + {"ThermofluidStream", "main"}, + {"ThermofluidStream", "0.2.0-OM_adaptions"}, + {"TILMedia", "ClaRa"} +} loop if not installPackage(stringTypeName(l[1]), l[2]) then print(l[1] + " " + l[2] + getErrorString() + "\n"); exit(1); From 78529f494529c5b5154c22fb5cdbcdd1d39c1c15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Wed, 24 Nov 2021 08:27:40 +0100 Subject: [PATCH 022/452] ThermofluidStream 0.3 was released --- .CI/installLibraries.mos | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.CI/installLibraries.mos b/.CI/installLibraries.mos index 9636fb1..048647f 100644 --- a/.CI/installLibraries.mos +++ b/.CI/installLibraries.mos @@ -39,7 +39,7 @@ for l in { {"OpenIPSL", ""}, {"Physiomodel", ""}, {"ThermofluidStream", "main"}, - {"ThermofluidStream", "0.2.0-OM_adaptions"}, + {"ThermofluidStream", "0.3.0-OM_adaptions"}, {"TILMedia", "ClaRa"} } loop if not installPackage(stringTypeName(l[1]), l[2]) then From 654b7115da7d7c890e7398ddf8ddacd126a8b0bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Fri, 10 Dec 2021 08:55:25 +0100 Subject: [PATCH 023/452] Test Buildings 8.1.x instead of 8.0.x --- .CI/installLibraries.mos | 2 +- configs/conf.json | 3 ++- conversionscript.py | 2 ++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.CI/installLibraries.mos b/.CI/installLibraries.mos index 048647f..4c7777e 100644 --- a/.CI/installLibraries.mos +++ b/.CI/installLibraries.mos @@ -9,7 +9,7 @@ for v in {"3.2.1","3.2.2","3.2.3","4.0.0","trunk"} loop exit(1); end if; end for; -for v in {"1.6", "3.0.0", "maint.7.0.x", "maint.8.0.x", "master"} loop +for v in {"1.6", "3.0.0", "maint.7.0.x", "maint.8.1.x", "master"} loop if not installPackage(Buildings, v) then print("Buildings " + v + " " + getErrorString() + "\n"); exit(1); diff --git a/configs/conf.json b/configs/conf.json index 909509c..d253554 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -126,7 +126,8 @@ { "library":"Buildings", "ignoreModelPrefix":"Buildings.Utilities.IO.BCVTB.Examples", - "libraryVersion":"maint.8.0.x", + "libraryVersionNameForTests":"8", + "libraryVersion":"maint.8.1.x", "libraryVersionLatestInPackageManager":true }, { diff --git a/conversionscript.py b/conversionscript.py index a2500c0..662a89d 100755 --- a/conversionscript.py +++ b/conversionscript.py @@ -138,6 +138,8 @@ def convertPackage(p): omc.sendExpression('writeFile("%s", after)' % newFile) if allowErrorsInDiff: errorsInDiff += [newFile] + omc.sendExpression('writeFile("%s.before",before)' % newFile) + omc.sendExpression('writeFile("%s.after",after)' % newFile) res = after nFail += 1 isFail = True From ff65645d63aeea3d6fe151ff745e3fd0611cd3aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Fri, 10 Dec 2021 13:20:39 +0100 Subject: [PATCH 024/452] Do backslashreplace if utf8 decoding fails Also fix utf8 decoding --- testmodel.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/testmodel.py b/testmodel.py index 5034e10..f46a129 100755 --- a/testmodel.py +++ b/testmodel.py @@ -92,10 +92,7 @@ def target(res): try: res[0] = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT).decode().strip() except subprocess.CalledProcessError as e: - try: - outputStr = str(e.output).decode("utf-8") - except: - outputStr = str(e.output) + outputStr = e.output.decode("utf-8","backslashreplace") res[1] = cmd + " " + outputStr except Exception as e: res[1] = cmd + " " + str(e) From 6f75f848ec2dc29e3a7c710446da5d902e77ab2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20=C3=96stlund?= Date: Sat, 11 Dec 2021 12:41:09 +0100 Subject: [PATCH 025/452] Update ThermofluidStream OM_adaptions branch --- .CI/installLibraries.mos | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.CI/installLibraries.mos b/.CI/installLibraries.mos index 4c7777e..020a89e 100644 --- a/.CI/installLibraries.mos +++ b/.CI/installLibraries.mos @@ -39,7 +39,7 @@ for l in { {"OpenIPSL", ""}, {"Physiomodel", ""}, {"ThermofluidStream", "main"}, - {"ThermofluidStream", "0.3.0-OM_adaptions"}, + {"ThermofluidStream", "0.3.1-OM_adaptions"}, {"TILMedia", "ClaRa"} } loop if not installPackage(stringTypeName(l[1]), l[2]) then From 48fc28e34b72b70a7be446c07cc612ddde2792b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Mon, 13 Dec 2021 12:29:30 +0100 Subject: [PATCH 026/452] Add testing of BLDC --- .CI/installLibraries.mos | 1 + configs/conf.json | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/.CI/installLibraries.mos b/.CI/installLibraries.mos index 020a89e..05f9ffe 100644 --- a/.CI/installLibraries.mos +++ b/.CI/installLibraries.mos @@ -26,6 +26,7 @@ end for; for l in { {"AES", "main"}, {"Annex60", ""}, + {"BLDC", ""}, {"ExtendedPetriNets", ""}, {"iPSL", ""}, {"PhotoVoltaics", ""}, diff --git a/configs/conf.json b/configs/conf.json index d253554..9e65a6d 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -117,6 +117,10 @@ "libraryVersionNameForTests":"latest", "extraCustomCommands":["setCommandLineOptions(\"-d=ignoreCycles\")"] }, + { + "library":"BLDC", + "libraryVersionNameForTests":"" + }, { "library":"Buildings", "ignoreModelPrefix":"Buildings.Utilities.IO.BCVTB.Examples", From 0c611054a78d5ac97ed06eb051d413a875c887e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Mon, 13 Dec 2021 15:32:59 +0100 Subject: [PATCH 027/452] Add brief README --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..083927b --- /dev/null +++ b/README.md @@ -0,0 +1,12 @@ +Brief instructions. Customize as you please: + +```bash +apt install openmodelica # See instructions on https://openmodelica.org +omc .CI/installLibraries.mos # Or install the libraries you need to test yourself +pip install -r requirements.txt +./test.py --noclean configs/conf.json # sqlite3.db is then generated +./report.py configs/conf.json +# Upload the relevant files somewhere. Backup sqlite3.db +``` + +There are flags such as --branch to test.py in order to test different OMC versions. From 7523e6ba4de16531bb3808ef1199b98f65849790 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Tue, 14 Dec 2021 09:37:20 +0100 Subject: [PATCH 028/452] Allow manual loadFile commands in JSON to load specific libraries --- test.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/test.py b/test.py index 9645556..52c011e 100755 --- a/test.py +++ b/test.py @@ -442,7 +442,17 @@ def hashReferenceFiles(s): print("Failed to set Modelica grammar") sys.exit(1) omc.sendExpression('clear()') - for (lib,version) in [[library,conf["libraryVersion"]]] + conf.get("extraLibraries", []): + if "loadFileCommands" in conf: + for command in conf["loadFileCommands"]: + if not omc.sendExpression(command): + try: + print("Failed to run command %s: %s" % (command,omc.sendExpression('OpenModelica.Scripting.getErrorString()'))) + except: + print("Failed to run command %s OpenModelica.Scripting.getErrorString() failed..." % command) + librariesToLoad = [] + else: + librariesToLoad = [[library,conf["libraryVersion"]]] + conf.get("extraLibraries", []) + for (lib,version) in librariesToLoad: if conf["libraryVersionLatestInPackageManager"]: availableVersions = omc.sendExpression('getAvailablePackageVersions(%s,"%s")' % (lib,version)) if not availableVersions: From 7581dad48667cf4596961e296d012cfe8c5c25ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Tue, 14 Dec 2021 10:46:11 +0100 Subject: [PATCH 029/452] Test ClaRa dev version --- configs/conf.json | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/configs/conf.json b/configs/conf.json index 9e65a6d..389e063 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -157,6 +157,15 @@ { "library":"ClaRa" }, + { + "library":"ClaRa", + "libraryVersionNameForTests":"dev", + "loadFileCommands":[ + "loadFile(\"/mnt/ReferenceFiles/ExtraLibs/packaged/ClaRa_Obsolete/package.mo\", uses=false)", + "loadFile(\"/mnt/ReferenceFiles/ExtraLibs/packaged/TILMedia/package.mo\", uses=false)", + "loadFile(\"/mnt/ReferenceFiles/ExtraLibs/packaged/ClaRa/package.mo\")" + ] + }, { "library":"ConPNlib", "libraryVersion":"master", From 782a8c92dba5ba24b04f989faedf21c5d88fae00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Wed, 15 Dec 2021 13:13:39 +0100 Subject: [PATCH 030/452] Use html module instead of cgi --- report.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/report.py b/report.py index ddc6240..29db1d1 100755 --- a/report.py +++ b/report.py @@ -7,7 +7,7 @@ parser = argparse.ArgumentParser(description='OpenModelica library testing report generation tool') parser.add_argument('configs', nargs='*') -parser.add_argument('--branches', default='') +parser.add_argument('--branches', default='master') args = parser.parse_args() configs = args.configs @@ -23,7 +23,7 @@ libs = {} -import cgi, sqlite3, time, datetime +import html, sqlite3, time, datetime from omcommon import friendlyStr, multiple_replace configs_lst = [shared.readConfig(c) for c in configs] @@ -129,9 +129,9 @@ def checkEqual(iterator): # print(sorted(list(libs[lib]))) nummodels = sum(len(l) for l in libs.values()) -branches_lines = [("%s%s%s%s%d%d\n" % (cgi.escape(branch), cgi.escape( +branches_lines = [("%s%s%s%s%d%d\n" % (html.escape(branch), html.escape( (cursor.execute("SELECT omcversion FROM [omcversion] WHERE date=? AND branch=?", (max(dates[branch][lib] for lib in libnames),branch)).fetchone() or ["unknown"])[0] - ), cgi.escape(dates_str[branch]), friendlyStr(exectime[branch]), + ), html.escape(dates_str[branch]), friendlyStr(exectime[branch]), " class=\"warning\"" if nummodels!=nmodels[branch] else "", nsimulate[branch], nmodels[branch] From 82153c71b77abcb0c9417775c370407750cf1980 Mon Sep 17 00:00:00 2001 From: Andreas <38031952+AnHeuermann@users.noreply.github.com> Date: Thu, 16 Dec 2021 16:08:01 +0100 Subject: [PATCH 031/452] Adding README and OSMC public license (#15) --- OSMC-License.txt | 271 +++++++++++++++++++++++++++++++++++++++++++++++ README.md | 135 +++++++++++++++++++++-- 2 files changed, 398 insertions(+), 8 deletions(-) create mode 100644 OSMC-License.txt diff --git a/OSMC-License.txt b/OSMC-License.txt new file mode 100644 index 0000000..10d0e2e --- /dev/null +++ b/OSMC-License.txt @@ -0,0 +1,271 @@ +--- Start of Definition of OSMC Public License --- + +/* + * This file is part of OpenModelica. + * + * Copyright (c) 1998-CurrentYear, Open Source Modelica Consortium (OSMC), + * c/o Linköpings universitet, Department of Computer and Information Science, + * SE-58183 Linköping, Sweden. + * + * All rights reserved. + * + * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR + * THIS OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.2. + * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES + * RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL VERSION 3, + * ACCORDING TO RECIPIENTS CHOICE. + * + * The OpenModelica software and the Open Source Modelica + * Consortium (OSMC) Public License (OSMC-PL) are obtained + * from OSMC, either from the above address, + * from the URLs: http://www.ida.liu.se/projects/OpenModelica or + * http://www.openmodelica.org, and in the OpenModelica distribution. + * GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html. + * + * This program is distributed WITHOUT ANY WARRANTY; without + * even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH + * IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF OSMC-PL. + * + * See the full OSMC Public License conditions for more details. + * + */ + +--- End of OSMC Public License Header --- + +The OSMC-PL is a public license for OpenModelica with three modes/alternatives +(GPL, OSMC-Internal-EPL, OSMC-External-EPL) for use and redistribution, +in source and/or binary/object-code form: + +* GPL. Any party (member or non-member of OSMC) may use and redistribute + OpenModelica under GPL version 3. + +* Level 1 members of OSMC may also use and redistribute OpenModelica under + OSMC-Internal-EPL conditions. + +* Level 2 members of OSMC may also use and redistribute OpenModelica under + OSMC-Internal-EPL or OSMC-External-EPL conditions. + +Definitions of OSMC Public license modes: + +* GPL = GPL version 3. + +* OSMC-Internal-EPL = These OSMC Public license conditions together with + Internally restricted EPL, i.e., EPL version 1.0 with the Additional + Condition that use and redistribution by an OSMC member is only allowed + within the OSMC member's own organization (i.e., its own legal entity), + or for an OSMC member paying a membership fee corresponding to the size + of the organization including all its affiliates, use and redistribution + is allowed within/between its affiliates. + +* OSMC-External-EPL = These OSMC Public license conditions together with + Externally restricted EPL, i.e., EPL version 1.0 with the Additional + Condition that use and redistribution by an OSMC member, or by a Licensed + Third Party Distributor having a redistribution agreement with that member, + to parties external to the OSMC member’s own organization (i.e., its own + legal entity) is only allowed in binary/object-code form, except the case of + redistribution to other OSMC members to which source is also allowed to be + distributed. + +[This has the consequence that an external party who wishes to use +OpenModelica in source form together with its own proprietary software in all +cases must be a member of OSMC]. + +In all cases of usage and redistribution by recipients, the following +conditions also apply: + +a) Redistributions of source code must retain the above copyright notice, + all definitions, and conditions. It is sufficient if the OSMC-PL Header is + present in each source file, if the full OSMC-PL is available in a prominent + and easily located place in the redistribution. + +b) Redistributions in binary/object-code form must reproduce the above + copyright notice, all definitions, and conditions. It is sufficient if the + OSMC-PL Header and the location in the redistribution of the full OSMC-PL + are present in the documentation and/or other materials provided with the + redistribution, if the full OSMC-PL is available in a prominent and easily + located place in the redistribution. + +c) A recipient must clearly indicate its chosen usage mode of OSMC-PL, + in accompanying documentation and in a text file OSMC-USAGE-MODE.txt, + provided with the distribution. + +d) Contributor(s) making a Contribution to OpenModelica thereby also makes a + Transfer of Contribution Copyright. In return, upon the effective date of + the transfer, OSMC grants the Contributor(s) a Contribution License of the + Contribution. OSMC has the right to accept or refuse Contributions. + +Definitions: + +"Subsidiary license conditions" means: + +The additional license conditions depending on the by the recipient chosen +mode of OSMC-PL, defined by GPL version 3.0 for GPL, and by EPL for +OSMC-Internal-EPL and OSMC-External-EPL. + +"OSMC-PL" means: + +Open Source Modelica Consortium Public License version 1.2, i.e., the license +defined here (the text between +"--- Start of Definition of OSMC Public License ---" and +"--- End of Definition of OSMC Public License ---", or later versions thereof. + +"OSMC-PL Header" means: + +Open Source Modelica Consortium Public License Header version 1.2, i.e., the +text between "--- Start of Definition of OSMC Public License ---" and +"--- End of OSMC Public License Header ---, or later versions thereof. + +"Contribution" means: + +a) in the case of the initial Contributor, the initial code and documentation + distributed under OSMC-PL, and + +b) in the case of each subsequent Contributor: + i) changes to OpenModelica, and + ii) additions to OpenModelica; + +where such changes and/or additions to OpenModelica originate from and are +distributed by that particular Contributor. A Contribution 'originates' from +a Contributor if it was added to OpenModelica by such Contributor itself or +anyone acting on such Contributor's behalf. + +For Contributors licensing OpenModelica under OSMC-Internal-EPL or +OSMC-External-EPL conditions, the following conditions also hold: + +Contributions do not include additions to the distributed Program which: (i) +are separate modules of software distributed in conjunction with OpenModelica +under their own license agreement, (ii) are separate modules which are not +derivative works of OpenModelica, and (iii) are separate modules of software +distributed in conjunction with OpenModelica under their own license agreement +where these separate modules are merged with (weaved together with) modules of +OpenModelica to form new modules that are distributed as object code or source +code under their own license agreement, as allowed under the Additional +Condition of internal distribution according to OSMC-Internal-EPL and/or +Additional Condition for external distribution according to OSMC-External-EPL. + +"Transfer of Contribution Copyright" means that the Contributors of a +Contribution transfer the ownership and the copyright of the Contribution to +Open Source Modelica Consortium, the OpenModelica Copyright owner, for +inclusion in OpenModelica. The transfer takes place upon the effective date +when the Contribution is made available on the OSMC web site under OSMC-PL, by +such Contributors themselves or anyone acting on such Contributors' behalf. +The transfer is free of charge. If the Contributors or OSMC so wish, +an optional Copyright transfer agreement can be signed between OSMC and the +Contributors, as specified in an Appendix of the OSMC Bylaws. + +"Contribution License" means a license from OSMC to the Contributors of the +Contribution, effective on the date of the Transfer of Contribution Copyright, +where OSMC grants the Contributors a non-exclusive, world-wide, transferable, +free of charge, perpetual license, including sublicensing rights, to use, +have used, modify, have modified, reproduce and or have reproduced the +contributed material, for business and other purposes, including but not +limited to evaluation, development, testing, integration and merging with +other software and distribution. The warranty and liability disclaimers of +OSMC-PL apply to this license. + +"Contributor" means any person or entity that distributes (part of) +OpenModelica. + +"The Program" means the Contributions distributed in accordance with OSMC-PL. + +"OpenModelica" means the Contributions distributed in accordance with OSMC-PL. + +"Recipient" means anyone who receives OpenModelica under OSMC-PL, +including all Contributors. + +"Licensed Third Party Distributor" means a reseller/distributor having signed +a redistribution/resale agreement in accordance with OSMC-PL and OSMC Bylaws, +with an OSMC Level 2 organizational member which is not an Affiliate of the +reseller/distributor, for distributing a product containing part(s) of +OpenModelica. The Licensed Third Party Distributor shall only be allowed +further redistribution to other resellers if the Level 2 member is granting +such a right to it in the redistribution/resale agreement between the +Level 2 member and the Licensed Third Party Distributor. + +"Affiliate" shall mean any legal entity, directly or indirectly, through one +or more intermediaries, controlling or controlled by or under common control +with any other legal entity, as the case may be. For purposes of this +definition, the term "control" (including the terms "controlling," +"controlled by" and "under common control with") means the possession, +direct or indirect, of the power to direct or cause the direction of the +management and policies of a legal entity, whether through the ownership of +voting securities, by contract or otherwise. + +NO WARRANTY + +EXCEPT AS EXPRESSLY SET FORTH IN THE BY RECIPIENT SELECTED SUBSIDIARY +LICENSE CONDITIONS OF OSMC-PL, OPENMODELICA IS PROVIDED ON AN "AS IS" +BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR +IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF +TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR +PURPOSE. Each Recipient is solely responsible for determining the +appropriateness of using and distributing OPENMODELICA and assumes all risks +associated with its exercise of rights under OSMC-PL , including but not +limited to the risks and costs of program errors, compliance with applicable +laws, damage to or loss of data, programs or equipment, and unavailability +or interruption of operations. + +DISCLAIMER OF LIABILITY + +EXCEPT AS EXPRESSLY SET FORTH IN THE BY RECIPIENT SELECTED SUBSIDIARY +LICENSE CONDITIONS OF OSMC-PL, NEITHER RECIPIENT NOR ANY CONTRIBUTORS +SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION +LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF OPENMODELICA OR THE +EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + +A Contributor licensing OpenModelica under OSMC-Internal-EPL or +OSMC-External-EPL may choose to distribute (parts of) OpenModelica in object +code form under its own license agreement, provided that: + +a) it complies with the terms and conditions of OSMC-PL; or for the case of +redistribution of OpenModelica together with proprietary code it is a dual +license where the OpenModelica parts are distributed under OSMC-PL compatible +conditions and the proprietary code is distributed under proprietary license +conditions; and + +b) its license agreement: + i) effectively disclaims on behalf of all Contributors all warranties and +conditions, express and implied, including warranties or conditions of title +and non-infringement, and implied warranties or conditions of merchantability +and fitness for a particular purpose; + ii) effectively excludes on behalf of all Contributors all liability for +damages, including direct, indirect, special, incidental and consequential +damages, such as lost profits; + iii) states that any provisions which differ from OSMC-PL are offered by that +Contributor alone and not by any other party; and + iv) states from where the source code for OpenModelica is available, and +informs licensees how to obtain it in a reasonable manner on or through a +medium customarily used for software exchange. + +When OPENMODELICA is made available in source code form: + + a) it must be made available under OSMC-PL; and + + b) a copy of OSMC-PL must be included with each copy of OPENMODELICA. + + c) a copy of the subsidiary license associated with the selected mode of +OSMC-PL must be included with each copy of OPENMODELICA. + +Contributors may not remove or alter any copyright notices contained within +OPENMODELICA. + +If there is a conflict between OSMC-PL and the subsidiary license conditions, +OSMC-PL has priority. + +This Agreement is governed by the laws of Sweden. The place of jurisdiction +for all disagreements related to this Agreement, is Linköping, Sweden. + +The EPL 1.0 license definition has been obtained from: +http://www.eclipse.org/legal/epl-v10.html. It is also reproduced in Appendix B +of the OSMC Bylaws, and in the OpenModelica distribution. + +The GPL Version 3 license definition has been obtained from +http://www.gnu.org/copyleft/gpl.html. It is also reproduced in Appendix C +of the OSMC Bylaws, and in the OpenModelica distribution. + +--- End of Definition of OSMC Public License --- \ No newline at end of file diff --git a/README.md b/README.md index 083927b..cca17d4 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,131 @@ -Brief instructions. Customize as you please: +# OpenModelica Library Testing +[![License: OSMC-PL](https://img.shields.io/badge/license-OSMC--PL-lightgrey.svg)](OSMC-License.txt) + +This repository provides scripts to run the nightly Modelica library tests for OpenModelica. + +The scripts from this repository can be uses to run regression tests for public, non-public or commercial Modelica libraries to keep track of coverage with different OpenModelica versions. + +## Dependencies (Linux) +- [OpenModelica](https://openmodelica.org) +- [Python](https://www.python.org/) +- [Optional] Reference Files + + +## Set-Up + +- Install or build OpenModelica + - [Install instructions](https://openmodelica.org/download/download-linux) + - [Build instructions](https://github.com/OpenModelica/OpenModelica#readme) + - Make sure `omc` is in your `PATH` +- Install Python requirements + ```bash + pip install -r requirements.txt + ``` +- Install libraries you want to test + - (Optional) Remove already installed libraries + ```bash + rm -rf ~/.openmodelica/libraries/ + rm -rf /path/to/OpenModelica/build/lib/omlibraries + ``` + - Install all available libraries. + ```bash + /path/to/omc .CI/installLibraries.mos + ``` + + *or* + - Install your libraries. +- Create configs/myConf.json to specify what libraries to test. + ```json + [ + { + "library":"MyModelicaLibrary", + "libraryVersion":"master", + "referenceFileExtension":"mat", + "referenceFileNameDelimiter":"/", + "referenceFileNameExtraName":"$ClassName", + "referenceFiles":{ + "giturl":"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/myName/MyModelicaLibrary-ref", + "destination":"ReferenceFiles/MyModelicaLibrary" + }, + "optlevel":"-Os -march=native" + } + ] + ``` + + You can add extra compiler settings + ```json + "extraCustomCommands":["setCommandLineOptions(\"--std=3.2\");"] + ``` + and more. Check `config/conf.json` for more. +- If you used `.CI/installLibraries.mos` to test all libraries you'll need to install reference results and set environment variables, see [Reference Results](#reference-results). + ```bash + export MSLREFERENCE="/path/to/ReferenceFiles/" + export REFERENCEFILES="/path/to/OpenModelica/testsuite/ReferenceFiles" + export PNLIBREFS="/path/to/ReferenceFiles/PNlib/ReferenceFiles" + export THERMOFLUIDSTREAMREFS="/path/to/ReferenceFiles/ThermofluidStream-main-regression/ReferenceData" + export THERMOFLUIDSTREAMREFSOM="/path/to/ReferenceFiles/ThermofluidStream-OM-regression/ReferenceData" + ``` + +- Run the library test + ```bash + ./test.py --noclean configs/myConf.json + ``` + Use `configs/*.json` to specify what to test. + The test results are saved in `sqlite3.db`. +- Generate HTML results + ```bash + ./report.py configs/myConf.json + ``` +- Upload and backup + - Upload HTML files somewhere + - backup sqlite3.db + +### Reference Results + +If you use the default configs `config/conf.json` and +`config/conf-c++.json` to test all libraries you need to +download the reference files and make them available by +defining `MSLREFERENCE` and `REFERENCEFILES`. + +Some result file locations: + - Modelica Association: https://github.com/modelica/MAP-LIB_ReferenceResults + - PNLib: https://github.com/AMIT-FHBielefeld/PNlib + - DLR-SR: https://github.com/DLR-SR/ThermoFluidStream-Regression.git and https://github.com/DLR-SR/ThermoFluidStream-Regression.git + + +To download the MSL reference files create a file +installReferenceResults.sh with +```sh +#!/bin/sh + +refdir="/some/path/to/ReferenceFiles" # Change the path! + +# Update git repo for MSL Reference files +mkdir -p $refdir/modelica.org/ReferenceResults +cd $refdir/modelica.org/ReferenceResults +rm -rf $refdir/MAP-LIB_ReferenceResults/ + +test -f MAP-LIB_ReferenceResults.git/config || git clone --bare https://github.com/modelica/MAP-LIB_ReferenceResults.git MAP-LIB_ReferenceResults.git +cd MAP-LIB_ReferenceResults.git +git fetch origin '*:*' +git fetch --tags + +for tag in $(git for-each-ref --format="%(refname:lstrip=-1)" refs/heads/) +do + echo "tag: $tag" + base="$refdir/MAP-LIB_ReferenceResults/$tag" + mkdir -p $base + echo "mkdir -p $base" + git archive --format=tar $tag | (cd $base && tar xvf -) +done +``` + +and run it ```bash -apt install openmodelica # See instructions on https://openmodelica.org -omc .CI/installLibraries.mos # Or install the libraries you need to test yourself -pip install -r requirements.txt -./test.py --noclean configs/conf.json # sqlite3.db is then generated -./report.py configs/conf.json -# Upload the relevant files somewhere. Backup sqlite3.db +chmod a+rx installReferenceResults.sh +./installReferenceResults.sh +export MSLREFERENCE="/some/path/to/ReferenceFiles/" ``` -There are flags such as --branch to test.py in order to test different OMC versions. +For the other libraries just clone the repositories to `/some/path/to/ReferenceFiles/`. \ No newline at end of file From 9ac84c88ca2db16584c2ab6639dc716eceed125c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Fri, 17 Dec 2021 07:52:25 +0100 Subject: [PATCH 032/452] Skip loading ClaRa_Obsolete --- configs/conf.json | 1 - 1 file changed, 1 deletion(-) diff --git a/configs/conf.json b/configs/conf.json index 389e063..0980bb1 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -161,7 +161,6 @@ "library":"ClaRa", "libraryVersionNameForTests":"dev", "loadFileCommands":[ - "loadFile(\"/mnt/ReferenceFiles/ExtraLibs/packaged/ClaRa_Obsolete/package.mo\", uses=false)", "loadFile(\"/mnt/ReferenceFiles/ExtraLibs/packaged/TILMedia/package.mo\", uses=false)", "loadFile(\"/mnt/ReferenceFiles/ExtraLibs/packaged/ClaRa/package.mo\")" ] From e1b3370f0d8b0ce85c891745ec95c1e94e76ad4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Fri, 17 Dec 2021 08:57:06 +0100 Subject: [PATCH 033/452] Test C++ in a separate job --- .CI/Jenkinsfile | 43 +++++++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index 50a1678..863a30b 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -328,9 +328,25 @@ pipeline { test('master', 'cvode', 'setCommandLineOptions("-d=newInst,-frontEndUnitCheck")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '-s cvode', false, false) } } + stage('C++') { + agent { + node { + label 'ryzen-5950x-2-1' + customWorkspace 'ws/OpenModelicaLibraryTestingWork' + } + } + options { skipDefaultCheckout() } + when { + beforeAgent true + expression { params.cpp } + } + steps { + test('master', 'cpp', 'setCommandLineOptions("--simCodeTarget=Cpp")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) + } + } } } stage('report') { parallel { - stage('lib') { + stage('ryzen-5950x-1') { agent { dockerfile { label 'linux' @@ -361,9 +377,7 @@ pipeline { sh "./all-reports.py --email --omcgitdir=OpenModelica ${env.GITBRANCHES} conversion" sh "./all-plots.py ${env.GITBRANCHES}" - sh "./report.py --branches='${env.GITBRANCHES}' configs/conf-c++.json" - sh 'mv overview.html overview-c++.html' - sh "./report.py --branches='${env.GITBRANCHES}' configs/conf.json configs/conf-c++.json configs/conf-old.json configs/conf-nonstandard.json" + sh "./report.py --branches='${env.GITBRANCHES}' configs/conf.json configs/conf-old.json configs/conf-nonstandard.json" sh 'mv overview.html overview-combined.html' sh "./report.py --branches='${env.GITBRANCHES}' configs/conf-old.json" sh "mv overview.html overview-old-libs.html" @@ -382,7 +396,7 @@ pipeline { } } - stage('ripper') { + stage('ryzen-5950x-2') { agent { dockerfile { label 'linux' @@ -392,7 +406,7 @@ pipeline { } when { beforeAgent true - expression { params.fmi_v1_12 || params.fmi_v1_13 || params.fmi_v1_14 || params.fmi_v1_16 || params.fmi_v1_17 || params.fmi_master || params.newInst_daeMode || params.oldInst || params.report_ripper2 || params.cvode } + expression { params.fmi_v1_12 || params.fmi_v1_13 || params.fmi_v1_14 || params.fmi_v1_16 || params.fmi_v1_17 || params.fmi_master || params.newInst_daeMode || params.oldInst || params.report_ripper2 || params.cvode || params.cpp } } environment { GITBRANCHES_FMI = 'maintenance/v1.12-fmi maintenance/v1.13-fmi maintenance/v1.14-fmi maintenance/v1.16-fmi maintenance/v1.17-fmi maintenance/v1.18-fmi master-fmi' @@ -417,20 +431,16 @@ pipeline { sh "./report.py --branches='${env.GITBRANCHES_NEWINST}' configs/conf.json" sh "mv overview.html overview-oldinst.html" - sh "./report.py --branches='${env.GITBRANCHES_NEWINST}' configs/conf.json configs/conf-c++.json configs/conf-old.json configs/conf-nonstandard.json" + sh "./report.py --branches='${env.GITBRANCHES_NEWINST}' configs/conf.json configs/conf-old.json configs/conf-nonstandard.json" sh "mv overview.html overview-combined-oldinst.html" sh "./report.py --branches='${env.GITBRANCHES_NEWINST}' configs/conf-old.json" sh "mv overview.html overview-old-libs-oldinst.html" sh "./report.py --branches='${env.GITBRANCHES_NEWINST}' configs/conf-nonstandard.json" sh "mv overview.html overview-nonstandard-libs-oldinst.html" - sh "./report.py --branches='${env.GITBRANCHES_NEWINST}' configs/conf-c++.json" - sh "mv overview.html overview-c++-oldinst.html" sh "./report.py --branches='${env.GITBRANCHES_FMI}' configs/conf.json" sh "mv overview.html overview-fmi.html" - sh "./report.py --branches='${env.GITBRANCHES_FMI}' configs/conf-c++.json" - sh "mv overview.html overview-c++-fmi.html" - sh "./report.py --branches='${env.GITBRANCHES_FMI}' configs/conf.json configs/conf-c++.json configs/conf-old.json configs/conf-nonstandard.json" + sh "./report.py --branches='${env.GITBRANCHES_FMI}' configs/conf.json configs/conf-old.json configs/conf-nonstandard.json" sh "mv overview.html overview-combined-fmi.html" sh "./report.py --branches='${env.GITBRANCHES_FMI}' configs/conf-old.json" sh "mv overview.html overview-old-libs-fmi.html" @@ -439,9 +449,7 @@ pipeline { sh "./report.py --branches='${env.GITBRANCHES_DAE}' configs/conf.json" sh "mv overview.html overview-dae.html" - sh "./report.py --branches='${env.GITBRANCHES_DAE}' configs/conf-c++.json" - sh "mv overview.html overview-c++-dae.html" - sh "./report.py --branches='${env.GITBRANCHES_DAE}' configs/conf.json configs/conf-c++.json configs/conf-old.json configs/conf-nonstandard.json" + sh "./report.py --branches='${env.GITBRANCHES_DAE}' configs/conf.json configs/conf-old.json configs/conf-nonstandard.json" sh "mv overview.html overview-combined-dae.html" sh "./report.py --branches='${env.GITBRANCHES_DAE}' configs/conf-old.json" sh "mv overview.html overview-old-libs-dae.html" @@ -451,6 +459,9 @@ pipeline { sh "./report.py --branches='cvode' configs/conf.json" sh "mv overview.html overview-cvode.html" + sh "./report.py --branches='cpp' configs/conf.json" + sh "mv overview.html overview-c++.html" + sh 'date' sh 'find overview*.html history -type f | wc -l' sh 'find overview*.html history' @@ -709,7 +720,7 @@ def test(branch, name, extraFlags, omsHash, dbPrefix, sshConfig, omcompiler, ext export HOME="${libraryPath}" cd OpenModelicaLibraryTesting # Force /usr/bin/omc as being used for generating the mos-files. Ensures consistent behavior among all tested OMC versions - stdbuf -oL -eL time ./test.py --ompython_omhome=/usr ${FMI_TESTING_FLAG} --extraflags='${extraFlags}' --extrasimflags='${extrasimflags}' --branch="${name}" --output="libraries.openmodelica.org:/var/www/branches/${name}/" --libraries='${libraryPath}/.openmodelica/libraries/' configs/conf.json ${conversionScript ? "" : "configs/conf-c++.json"} ${params.OLDLIBS ? "configs/conf-old.json configs/conf-nonstandard.json" : ""} || (killall omc ; false) || exit 1 + stdbuf -oL -eL time ./test.py --ompython_omhome=/usr ${FMI_TESTING_FLAG} --extraflags='${extraFlags}' --extrasimflags='${extrasimflags}' --branch="${name}" --output="libraries.openmodelica.org:/var/www/branches/${name}/" --libraries='${libraryPath}/.openmodelica/libraries/' configs/conf.json ${params.OLDLIBS ? "configs/conf-old.json configs/conf-nonstandard.json" : ""} || (killall omc ; false) || exit 1 """ sh 'date' sh "rm -f OpenModelicaLibraryTesting/${dbPrefix}-sqlite3.db.tmp" From 755ee9706037e1ef5f4b03f75e7f713d1965212a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Fri, 17 Dec 2021 08:59:13 +0100 Subject: [PATCH 034/452] Add the option for cpp --- .CI/Jenkinsfile | 1 + 1 file changed, 1 insertion(+) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index 863a30b..64bc841 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -20,6 +20,7 @@ pipeline { booleanParam(name: 'fmi_master', defaultValue: false, description: 'master branch with FMI (ryzen-5950x-2)') booleanParam(name: 'newInst_daeMode', defaultValue: false, description: 'master branch, --daeMode with -d=newInst (ryzen-5950x-2)') booleanParam(name: 'oldInst', defaultValue: false, description: 'master branch, with -d=nonewInst (ryzen-5950x-2)') + booleanParam(name: 'cpp', defaultValue: false, description: 'master branch, with --simCodeTarget=Cpp (ryzen-5950x-2).') booleanParam(name: 'report_ryzen_5950x_1', defaultValue: false, description: 'Generate a report for ryzen-5950x-1 without running the tests') booleanParam(name: 'report_ryzen-5950x-2', defaultValue: false, description: 'Generate a report for ryzen-5950x-2 without running the tests') From aa1cdfbe492ac7f80534282f97fd00bcbaf8be3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Fri, 17 Dec 2021 09:40:35 +0100 Subject: [PATCH 035/452] Support extracting xz reference-files --- test.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test.py b/test.py index 52c011e..44d238f 100755 --- a/test.py +++ b/test.py @@ -335,6 +335,7 @@ def testHelloWorld(cmd): subprocess.check_call(["git", "fetch", "origin"], stderr=subprocess.STDOUT, cwd=destination) subprocess.check_call(["git", "reset", "--hard", "origin/master"], stderr=subprocess.STDOUT, cwd=destinationReal) subprocess.check_call(["git", "clean", "-fdx", "--exclude=*.hash"], stderr=subprocess.STDOUT, cwd=destinationReal) + subprocess.check_call(["find", ".", "-name", "*.mat.xz", "-exec", "xz", "--decompress", "--keep", "{}", ";"], stderr=subprocess.STDOUT, cwd=destinationReal) githash = subprocess.check_output(["git", "rev-parse", "--verify", "HEAD"], stderr=subprocess.STDOUT, cwd=destinationReal) c["referenceFiles"] = destinationReal if giturl.startswith("https://github.com"): From 36cbd2c24e7b4cc7ed9f4b41d06df4a8ab1d9859 Mon Sep 17 00:00:00 2001 From: rfranke Date: Fri, 17 Dec 2021 09:41:40 +0100 Subject: [PATCH 036/452] Add reference results to PowerSystems_latest and PowerSystems_cpp (#12) --- configs/conf-c++.json | 6 +++++- configs/conf.json | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/configs/conf-c++.json b/configs/conf-c++.json index c011cb9..85d34ea 100644 --- a/configs/conf-c++.json +++ b/configs/conf-c++.json @@ -67,6 +67,10 @@ "configExtraName":"cpp", "simCodeTarget":"Cpp", "alarmFlag":"--alarm", - "abortSlowSimulation":"" + "abortSlowSimulation":"", + "referenceFiles":{ + "giturl":"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/rfranke/PowerSystems_ReferenceResults", + "destination":"ReferenceFiles/PowerSystems" + } } ] diff --git a/configs/conf.json b/configs/conf.json index 0980bb1..4783b16 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -93,7 +93,11 @@ "library":"PowerSystems", "libraryVersion":"master", "libraryVersionNameForTests":"latest", - "optlevel":"-Os -march=native" + "optlevel":"-Os -march=native", + "referenceFiles":{ + "giturl":"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/rfranke/PowerSystems_ReferenceResults", + "destination":"ReferenceFiles/PowerSystems" + } }, { "library":"AdvancedNoise", From f0f806127a2f3248789c89e5946deaf3531d9188 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Fri, 17 Dec 2021 14:03:40 +0100 Subject: [PATCH 037/452] Also test 1.18 with C++ runtime --- .CI/Jenkinsfile | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index 64bc841..62f64d8 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -20,6 +20,7 @@ pipeline { booleanParam(name: 'fmi_master', defaultValue: false, description: 'master branch with FMI (ryzen-5950x-2)') booleanParam(name: 'newInst_daeMode', defaultValue: false, description: 'master branch, --daeMode with -d=newInst (ryzen-5950x-2)') booleanParam(name: 'oldInst', defaultValue: false, description: 'master branch, with -d=nonewInst (ryzen-5950x-2)') + booleanParam(name: 'cpp_v1_18', defaultValue: false, description: 'maintenance/v1.18 branch, with --simCodeTarget=Cpp (ryzen-5950x-2).') booleanParam(name: 'cpp', defaultValue: false, description: 'master branch, with --simCodeTarget=Cpp (ryzen-5950x-2).') booleanParam(name: 'report_ryzen_5950x_1', defaultValue: false, description: 'Generate a report for ryzen-5950x-1 without running the tests') booleanParam(name: 'report_ryzen-5950x-2', defaultValue: false, description: 'Generate a report for ryzen-5950x-2 without running the tests') @@ -329,6 +330,22 @@ pipeline { test('master', 'cvode', 'setCommandLineOptions("-d=newInst,-frontEndUnitCheck")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '-s cvode', false, false) } } + stage('C++ v1.18') { + agent { + node { + label 'ryzen-5950x-2-1' + customWorkspace 'ws/OpenModelicaLibraryTestingWork' + } + } + options { skipDefaultCheckout() } + when { + beforeAgent true + expression { params.cpp_v1_18 } + } + steps { + test('maintenance/v1.18', 'v1.18-cpp', 'setCommandLineOptions("--simCodeTarget=Cpp")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) + } + } stage('C++') { agent { node { @@ -413,6 +430,7 @@ pipeline { GITBRANCHES_FMI = 'maintenance/v1.12-fmi maintenance/v1.13-fmi maintenance/v1.14-fmi maintenance/v1.16-fmi maintenance/v1.17-fmi maintenance/v1.18-fmi master-fmi' GITBRANCHES_NEWINST = 'oldInst' GITBRANCHES_DAE = 'daemode newInst-daemode' + GITBRANCHES_CPP = 'cpp v1.18-fmi' PYTHONIOENCODING = 'utf-8' } steps { @@ -460,7 +478,7 @@ pipeline { sh "./report.py --branches='cvode' configs/conf.json" sh "mv overview.html overview-cvode.html" - sh "./report.py --branches='cpp' configs/conf.json" + sh "./report.py --branches='${env.GITBRANCHES_CPP}' configs/conf.json" sh "mv overview.html overview-c++.html" sh 'date' From 9454456dc50b774b9eaf8354aa20f15fdc1697b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Mon, 20 Dec 2021 14:04:26 +0100 Subject: [PATCH 038/452] Compare only C++ runtimes in the C++ report... --- .CI/Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index 62f64d8..df613c2 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -430,7 +430,7 @@ pipeline { GITBRANCHES_FMI = 'maintenance/v1.12-fmi maintenance/v1.13-fmi maintenance/v1.14-fmi maintenance/v1.16-fmi maintenance/v1.17-fmi maintenance/v1.18-fmi master-fmi' GITBRANCHES_NEWINST = 'oldInst' GITBRANCHES_DAE = 'daemode newInst-daemode' - GITBRANCHES_CPP = 'cpp v1.18-fmi' + GITBRANCHES_CPP = 'v1.18-cpp cpp' PYTHONIOENCODING = 'utf-8' } steps { From 5cbcc98e08966fb06f949820cda7b7aceb47e667 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Mon, 20 Dec 2021 14:39:06 +0100 Subject: [PATCH 039/452] Make it possible to generate reports only --- .CI/Jenkinsfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index df613c2..1484cc6 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -23,7 +23,7 @@ pipeline { booleanParam(name: 'cpp_v1_18', defaultValue: false, description: 'maintenance/v1.18 branch, with --simCodeTarget=Cpp (ryzen-5950x-2).') booleanParam(name: 'cpp', defaultValue: false, description: 'master branch, with --simCodeTarget=Cpp (ryzen-5950x-2).') booleanParam(name: 'report_ryzen_5950x_1', defaultValue: false, description: 'Generate a report for ryzen-5950x-1 without running the tests') - booleanParam(name: 'report_ryzen-5950x-2', defaultValue: false, description: 'Generate a report for ryzen-5950x-2 without running the tests') + booleanParam(name: 'report_ryzen-5950x_2', defaultValue: false, description: 'Generate a report for ryzen-5950x-2 without running the tests') booleanParam(name: 'conversion_script', defaultValue: false, description: 'master branch with conversion script from MSL 3 to 4 (ryzen-5950x-1). This is an experimental job that does not run on a fixed schedule.') booleanParam(name: 'cvode', defaultValue: false, description: 'master branch, with -d=newInst and -s cvode (ryzen-5950x-2). This is an experimental job that does not run on a fixed schedule.') @@ -374,7 +374,7 @@ pipeline { } when { beforeAgent true - expression { params.v1_12 || params.v1_13 || params.v1_14 || params.v1_16 || params.v1_17 || params.master || params.conversion_script || params.report_ripper1 } + expression { params.v1_12 || params.v1_13 || params.v1_14 || params.v1_16 || params.v1_17 || params.master || params.conversion_script || params.report_ryzen_5950x_1 } } environment { GITBRANCHES = 'maintenance/v1.12 maintenance/v1.13 maintenance/v1.14 maintenance/v1.16 maintenance/v1.17 maintenance/v1.18 master' @@ -424,7 +424,7 @@ pipeline { } when { beforeAgent true - expression { params.fmi_v1_12 || params.fmi_v1_13 || params.fmi_v1_14 || params.fmi_v1_16 || params.fmi_v1_17 || params.fmi_master || params.newInst_daeMode || params.oldInst || params.report_ripper2 || params.cvode || params.cpp } + expression { params.fmi_v1_12 || params.fmi_v1_13 || params.fmi_v1_14 || params.fmi_v1_16 || params.fmi_v1_17 || params.fmi_master || params.newInst_daeMode || params.oldInst || params.report_ryzen_5950x_2 || params.cvode || params.cpp } } environment { GITBRANCHES_FMI = 'maintenance/v1.12-fmi maintenance/v1.13-fmi maintenance/v1.14-fmi maintenance/v1.16-fmi maintenance/v1.17-fmi maintenance/v1.18-fmi master-fmi' From 593a7c6396c7082556b14b86371711e8bb0ba3a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Mon, 20 Dec 2021 14:53:59 +0100 Subject: [PATCH 040/452] Update job param name --- .CI/Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index 1484cc6..9bbfbb3 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -23,7 +23,7 @@ pipeline { booleanParam(name: 'cpp_v1_18', defaultValue: false, description: 'maintenance/v1.18 branch, with --simCodeTarget=Cpp (ryzen-5950x-2).') booleanParam(name: 'cpp', defaultValue: false, description: 'master branch, with --simCodeTarget=Cpp (ryzen-5950x-2).') booleanParam(name: 'report_ryzen_5950x_1', defaultValue: false, description: 'Generate a report for ryzen-5950x-1 without running the tests') - booleanParam(name: 'report_ryzen-5950x_2', defaultValue: false, description: 'Generate a report for ryzen-5950x-2 without running the tests') + booleanParam(name: 'report_ryzen_5950x_2', defaultValue: false, description: 'Generate a report for ryzen-5950x-2 without running the tests') booleanParam(name: 'conversion_script', defaultValue: false, description: 'master branch with conversion script from MSL 3 to 4 (ryzen-5950x-1). This is an experimental job that does not run on a fixed schedule.') booleanParam(name: 'cvode', defaultValue: false, description: 'master branch, with -d=newInst and -s cvode (ryzen-5950x-2). This is an experimental job that does not run on a fixed schedule.') From 378b5f8b65c09d271dd9ab575cfc78701e593c82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Mon, 20 Dec 2021 15:12:02 +0100 Subject: [PATCH 041/452] Also report C++ history --- .CI/Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index 9bbfbb3..ab5e303 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -445,7 +445,7 @@ pipeline { sh 'wget -q https://libraries.openmodelica.org/sqlite3/ripper2/sqlite3.db' sh './clean-empty-omcversion-dates.py' - sh "./all-reports.py --email --omcgitdir=OpenModelica ${env.GITBRANCHES_FMI} ${env.GITBRANCHES_NEWINST} ${env.GITBRANCHES_DAE}" + sh "./all-reports.py --email --omcgitdir=OpenModelica ${env.GITBRANCHES_FMI} ${env.GITBRANCHES_NEWINST} ${env.GITBRANCHES_DAE} ${env.GITBRANCHES_CPP}" sh "./all-plots.py ${env.GITBRANCHES_FMI} ${env.GITBRANCHES_NEWINST} ${env.GITBRANCHES_DAE}" sh "./report.py --branches='${env.GITBRANCHES_NEWINST}' configs/conf.json" From 202d9932029fe9d160f9edca6d96f41d93414ff8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Mon, 20 Dec 2021 15:14:23 +0100 Subject: [PATCH 042/452] Also create plots for C++ jobs --- .CI/Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index ab5e303..2856322 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -446,7 +446,7 @@ pipeline { sh './clean-empty-omcversion-dates.py' sh "./all-reports.py --email --omcgitdir=OpenModelica ${env.GITBRANCHES_FMI} ${env.GITBRANCHES_NEWINST} ${env.GITBRANCHES_DAE} ${env.GITBRANCHES_CPP}" - sh "./all-plots.py ${env.GITBRANCHES_FMI} ${env.GITBRANCHES_NEWINST} ${env.GITBRANCHES_DAE}" + sh "./all-plots.py ${env.GITBRANCHES_FMI} ${env.GITBRANCHES_NEWINST} ${env.GITBRANCHES_DAE} ${env.GITBRANCHES_CPP}" sh "./report.py --branches='${env.GITBRANCHES_NEWINST}' configs/conf.json" sh "mv overview.html overview-oldinst.html" From 422de865b98d1e7dd6f2ae316ec72527d51ec20d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Thu, 27 Jan 2022 09:34:11 +0100 Subject: [PATCH 043/452] Test main branch of TILMedia --- .CI/installLibraries.mos | 2 +- configs/conf.json | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.CI/installLibraries.mos b/.CI/installLibraries.mos index 05f9ffe..8bca028 100644 --- a/.CI/installLibraries.mos +++ b/.CI/installLibraries.mos @@ -41,7 +41,7 @@ for l in { {"Physiomodel", ""}, {"ThermofluidStream", "main"}, {"ThermofluidStream", "0.3.1-OM_adaptions"}, - {"TILMedia", "ClaRa"} + {"TILMedia", "main"} } loop if not installPackage(stringTypeName(l[1]), l[2]) then print(l[1] + " " + l[2] + getErrorString() + "\n"); diff --git a/configs/conf.json b/configs/conf.json index 4783b16..6e75501 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -165,7 +165,7 @@ "library":"ClaRa", "libraryVersionNameForTests":"dev", "loadFileCommands":[ - "loadFile(\"/mnt/ReferenceFiles/ExtraLibs/packaged/TILMedia/package.mo\", uses=false)", + "loadModel(TILMedia, {\"main\"})", "loadFile(\"/mnt/ReferenceFiles/ExtraLibs/packaged/ClaRa/package.mo\")" ] }, @@ -352,6 +352,8 @@ }, { "library":"TILMedia", + "libraryVersion":"main", + "libraryVersionNameForTests":"", "extraLibraries":[ ["ClaRa", "default"] ] From 2e98b615e2237f2a5f02997d642c988654871f40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20=C3=96stlund?= Date: Tue, 15 Feb 2022 11:39:07 +0100 Subject: [PATCH 044/452] Update ThermofluidStream OM_adaptions branch --- .CI/installLibraries.mos | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.CI/installLibraries.mos b/.CI/installLibraries.mos index 8bca028..b623814 100644 --- a/.CI/installLibraries.mos +++ b/.CI/installLibraries.mos @@ -40,7 +40,7 @@ for l in { {"OpenIPSL", ""}, {"Physiomodel", ""}, {"ThermofluidStream", "main"}, - {"ThermofluidStream", "0.3.1-OM_adaptions"}, + {"ThermofluidStream", "0.4.0-OM_adaptions"}, {"TILMedia", "main"} } loop if not installPackage(stringTypeName(l[1]), l[2]) then From 5ee5ff7fe44a188676fbef4e894f96c76d4c8c21 Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Mon, 21 Mar 2022 14:01:16 +0100 Subject: [PATCH 045/452] add newInst_newBackend branch (#16) --- .CI/Jenkinsfile | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index 2856322..9e98982 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -1,3 +1,4 @@ +pipeline { pipeline { agent none parameters { @@ -19,6 +20,7 @@ pipeline { booleanParam(name: 'fmi_v1_18', defaultValue: false, description: 'maintenance/v1.18 branch with FMI (ryzen-5950x-2)') booleanParam(name: 'fmi_master', defaultValue: false, description: 'master branch with FMI (ryzen-5950x-2)') booleanParam(name: 'newInst_daeMode', defaultValue: false, description: 'master branch, --daeMode with -d=newInst (ryzen-5950x-2)') + booleanParam(name: 'newInst_newBackend', defaultValue: false, description: 'master branch, -d=newInst --newBackend, (ryzen-5950x-1)') booleanParam(name: 'oldInst', defaultValue: false, description: 'master branch, with -d=nonewInst (ryzen-5950x-2)') booleanParam(name: 'cpp_v1_18', defaultValue: false, description: 'maintenance/v1.18 branch, with --simCodeTarget=Cpp (ryzen-5950x-2).') booleanParam(name: 'cpp', defaultValue: false, description: 'master branch, with --simCodeTarget=Cpp (ryzen-5950x-2).') @@ -170,6 +172,23 @@ pipeline { } } + stage('newInst-newBackend') { + agent { + node { + label 'ryzen-5950x-1' + customWorkspace 'ws/OpenModelicaLibraryTestingWork' + } + } + options { skipDefaultCheckout() } + when { + beforeAgent true + expression { params.newInst_newBackend } + } + steps { + test('master', 'newInst-newBackend', 'setCommandLineOptions("-d=newInst,-frontEndUnitCheck --newBackend")', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', false, false) + } + } + stage('v1.12 FMI') { agent { node { From a87bc4007a99e35b4747fbafddff6555df5dfe3d Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Mon, 21 Mar 2022 14:25:27 +0100 Subject: [PATCH 046/452] fix some copy-paste error (#17) --- .CI/Jenkinsfile | 1 - 1 file changed, 1 deletion(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index 9e98982..3d1e611 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -1,4 +1,3 @@ -pipeline { pipeline { agent none parameters { From 409a06e44a27047048a83bb0dff83595a3737767 Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Wed, 23 Mar 2022 15:44:31 +0100 Subject: [PATCH 047/452] generate a report for the new backend (#18) * generate a report for the new backend * get the report via email --- .CI/Jenkinsfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index 3d1e611..24076fd 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -392,7 +392,7 @@ pipeline { } when { beforeAgent true - expression { params.v1_12 || params.v1_13 || params.v1_14 || params.v1_16 || params.v1_17 || params.master || params.conversion_script || params.report_ryzen_5950x_1 } + expression { params.v1_12 || params.v1_13 || params.v1_14 || params.v1_16 || params.v1_17 || params.master || params.conversion_script || params.report_ryzen_5950x_1 | params.newInst_newBackend} } environment { GITBRANCHES = 'maintenance/v1.12 maintenance/v1.13 maintenance/v1.14 maintenance/v1.16 maintenance/v1.17 maintenance/v1.18 master' @@ -410,7 +410,7 @@ pipeline { sh 'wget -q https://libraries.openmodelica.org/sqlite3/ripper1/sqlite3.db' sh './clean-empty-omcversion-dates.py' - sh "./all-reports.py --email --omcgitdir=OpenModelica ${env.GITBRANCHES} conversion" + sh "./all-reports.py --email --omcgitdir=OpenModelica ${env.GITBRANCHES} conversion newInst-newBackend" sh "./all-plots.py ${env.GITBRANCHES}" sh "./report.py --branches='${env.GITBRANCHES}' configs/conf.json configs/conf-old.json configs/conf-nonstandard.json" From c994d6eff5f134c3eb973aa3fff6bba861480e84 Mon Sep 17 00:00:00 2001 From: AnHeuermann Date: Tue, 29 Mar 2022 11:14:35 +0200 Subject: [PATCH 048/452] Reference files for ClaRa_dev --- configs/conf.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/configs/conf.json b/configs/conf.json index 6e75501..a7f8c37 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -167,7 +167,11 @@ "loadFileCommands":[ "loadModel(TILMedia, {\"main\"})", "loadFile(\"/mnt/ReferenceFiles/ExtraLibs/packaged/ClaRa/package.mo\")" - ] + ], + "referenceFileExtension":"mat", + "referenceFileNameDelimiter":".", + "referenceFileNameExtraName":"$ClassName", + "referenceFiles":"$/mnt/ReferenceFiles/ExtraLibs/packaged/ReferenceResults" }, { "library":"ConPNlib", From 8a92bff9be863b69b68373b1ed055ac425c2bb6d Mon Sep 17 00:00:00 2001 From: AnHeuermann Date: Tue, 29 Mar 2022 13:00:44 +0200 Subject: [PATCH 049/452] No referenceFileNameExtraName --- configs/conf.json | 1 - 1 file changed, 1 deletion(-) diff --git a/configs/conf.json b/configs/conf.json index a7f8c37..6c207b6 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -170,7 +170,6 @@ ], "referenceFileExtension":"mat", "referenceFileNameDelimiter":".", - "referenceFileNameExtraName":"$ClassName", "referenceFiles":"$/mnt/ReferenceFiles/ExtraLibs/packaged/ReferenceResults" }, { From a398c4faf4a37b337a39cf5ae06b0670748ad12b Mon Sep 17 00:00:00 2001 From: AnHeuermann Date: Tue, 29 Mar 2022 13:53:00 +0200 Subject: [PATCH 050/452] Fix typo --- configs/conf.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/conf.json b/configs/conf.json index 6c207b6..1d7e102 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -170,7 +170,7 @@ ], "referenceFileExtension":"mat", "referenceFileNameDelimiter":".", - "referenceFiles":"$/mnt/ReferenceFiles/ExtraLibs/packaged/ReferenceResults" + "referenceFiles":"/mnt/ReferenceFiles/ExtraLibs/packaged/ReferenceResults" }, { "library":"ConPNlib", From ef7a10dcf00cc152fbe2c8ae1da3bfd6c713696a Mon Sep 17 00:00:00 2001 From: Andreas <38031952+AnHeuermann@users.noreply.github.com> Date: Mon, 4 Apr 2022 10:28:52 +0200 Subject: [PATCH 051/452] Fix referenceFiles location for ClaRa_dev (#20) --- configs/conf.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/conf.json b/configs/conf.json index 1d7e102..20bbc2a 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -170,7 +170,7 @@ ], "referenceFileExtension":"mat", "referenceFileNameDelimiter":".", - "referenceFiles":"/mnt/ReferenceFiles/ExtraLibs/packaged/ReferenceResults" + "referenceFiles":"/mnt/ReferenceFiles/ExtraLibs/clara_om.git/ReferenceResults" }, { "library":"ConPNlib", From de93d7c54e586b5331cd461dd03feaa653396ec7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20=C3=96stlund?= Date: Mon, 4 Apr 2022 13:07:13 +0200 Subject: [PATCH 052/452] Fix sanity check print out --- test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test.py b/test.py index 44d238f..fe456b5 100755 --- a/test.py +++ b/test.py @@ -83,7 +83,7 @@ def target(): try: subprocess.check_output(["./testmodel.py", "--help"], stderr=subprocess.STDOUT) except subprocess.CalledProcessError as e: - print("Sanity check failed (./testmodel.py --help):\n" + e.output) + print("Sanity check failed (./testmodel.py --help):\n" + e.output.decode()) sys.exit(1) parser = argparse.ArgumentParser(description='OpenModelica library testing tool') From 096aeeac6c92b1f58d67c133104e95abb52c784e Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Tue, 12 Apr 2022 13:01:51 +0200 Subject: [PATCH 053/452] Added tests of IDEA (relased and dev) --- configs/conf.json | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/configs/conf.json b/configs/conf.json index 20bbc2a..5dda4ef 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -206,6 +206,16 @@ { "library":"KeyWordIO" }, + { + "library":"IDEAS", + "libraryVersionNameForTests":"", + "libraryVersionLatestInPackageManager":true + }, + { + "library":"IDEAS", + "libraryVersion":"master", + "libraryVersionNameForTests":"dev" + }, { "library":"LibRAS", "extraCustomCommands":["if not setCommandLineOptions(\"--std=3.3\") then exit(1); end if;"] From 81ed3c7ccf122f26df56d5af301df11230d88eeb Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Wed, 13 Apr 2022 18:00:41 +0200 Subject: [PATCH 054/452] Updated README.md --- README.md | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index cca17d4..3265876 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,27 @@ # OpenModelica Library Testing -[![License: OSMC-PL](https://img.shields.io/badge/license-OSMC--PL-lightgrey.svg)](OSMC-License.txt) +This repository provides scripts and documentation to run the nightly Modelica library tests for OpenModelica. + +## Using the OpenModelica nightly testsuite + +Some of the open-source Modelica libraries managed by the [Open Modelica Package Manager](https://github.com/OpenModelica/OMPackageManager) are tested on a daily basis on the OSMC servers. Test results are [publicly available](testresults.md). -This repository provides scripts to run the nightly Modelica library tests for OpenModelica. +The configuration files for the OSMC nightly testsuite jobs are [conf.json](configs/conf.json) for the regular tests using the C runtime, and [conf-c++.json](configs/conf-c%2B%2B.json) for the tests using the C++ runtime. The setup of the configuration files is discussed in [conf-howto.md](conf-howto.md). + +If you want to include your open-source library in the testsuite, please open a pull request on [conf.json](configs/conf.json), or open an issue on the [OpenModelica issue tracker](https://github.com/OpenModelica/OpenModelica/issues/new/choose) and ask us to do it for you. + +## Running the library testing infrastructure on your own server +[![License: OSMC-PL](https://img.shields.io/badge/license-OSMC--PL-lightgrey.svg)](OSMC-License.txt) -The scripts from this repository can be uses to run regression tests for public, non-public or commercial Modelica libraries to keep track of coverage with different OpenModelica versions. +The scripts from this repository can be used to run regression tests for public, private, and commercial Modelica libraries to keep track of coverage with different OpenModelica versions, according to the conditions of the [OSMC-PL license](OSMC-License.txt). -## Dependencies (Linux) +### Dependencies (Linux) - [OpenModelica](https://openmodelica.org) - [Python](https://www.python.org/) -- [Optional] Reference Files +- [Optional] Reference simulation result files -## Set-Up +### Set-Up - Install or build OpenModelica - [Install instructions](https://openmodelica.org/download/download-linux) @@ -128,4 +137,4 @@ chmod a+rx installReferenceResults.sh export MSLREFERENCE="/some/path/to/ReferenceFiles/" ``` -For the other libraries just clone the repositories to `/some/path/to/ReferenceFiles/`. \ No newline at end of file +For the other libraries just clone the repositories to `/some/path/to/ReferenceFiles/`. From f362031a3bd543e9477d5afa1084ab1a1e5442a9 Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Wed, 13 Apr 2022 20:12:26 +0200 Subject: [PATCH 055/452] Added page with links to testing results --- testresults.md | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 testresults.md diff --git a/testresults.md b/testresults.md new file mode 100644 index 0000000..d896538 --- /dev/null +++ b/testresults.md @@ -0,0 +1,38 @@ +# Open-Source Modelica Library Testing using OpenModelica + +The library testsuite job is run every night on the OSMC servers, testing open-source Modelica libraries covered by the +[Package Manager](https://github.com/OpenModelica/OMPackageManager#readme) with various versions of OpenModelica, +including the development version on the master branch. The simulations are run with the C-runtime, unless specified differently. + +Within each library, all models with an experiment(StopTime) annotations are run. For each tested model, the results of the following steps are reported: +- _parsing_ +- _frontend_: flattening the model +- _backend_: structural analysis, index reduction, causalization, tearing, and all kind of symbolic manipulations and optimization to solve the model efficiently +- _simcode_: intermediate stap towards simulation code generation +- _templates_: generation of the actual C code +- _compilation_: compilation of the C code into a simulation executable +- _simulation_: the simulation is actually run to produce simulation results +- _verification_: if reference results file are available, they are compared with the simulation results + +Clicking on the model name shows the log of phases from parsing to compilation. Clicking on the (sim) link shows the log of the runtime simulation. + +Many different reports are available: + +- _Overview with library test results across versions_: These reports shows how libraries with full or partial support level + (see [here](https://github.com/OpenModelica/OMPackageManager/blob/master/README.md#library-support-levels-in-openmodelica) for more details) + are handled by released versions of OpenModelica and by the development version on the master branch. Regressions are marked in orange, improvements in green + - [Default settings](https://libraries.openmodelica.org/branches/overview.html): simulation with C runtime and default settings + - [daeMode](https://libraries.openmodelica.org/branches/overview-dae.html): simulation with daeMode (compiler flag [--daeMode](https://openmodelica.org/doc/OpenModelicaUsersGuide/latest/omchelptext.html#omcflag-daemode)) + - [C++](https://libraries.openmodelica.org/branches/overview-c++.html): simulation with C++ runtime + - [FMI](https://libraries.openmodelica.org/branches/overview-fmi.html): simulation with FMI and C runtime + - [FMI C++](https://libraries.openmodelica.org/branches/overview-c++.html): simulation with FMI and C++ runtime +- _Regression reports and history plots_: regression reports are periodically generated, using the latest development version of OMC. Changes w.r.t. the + previous report are shown. For each tested library, .svg plots are also provided, showing the trends of the results of each step over time + - [Default settings](https://libraries.openmodelica.org/branches/history/master/): default omc settings, C runtime + - [daeMode](https://libraries.openmodelica.org/branches/history/daemode/): simulation with --daeMode + - [C++](https://libraries.openmodelica.org/branches/history/cpp/): simulation with C++ runtime + - [FMI](https://libraries.openmodelica.org/branches/history/master-fmi/): simulation with FMI, C runtime + +If you are actively developing a library, it is recommended to have two tests for it: one testing the latest official release, which can be used +to check if changes to OMC cause regressions to the existing library, another one testing the development version, which also checks regressions +caused by changes to the library code. You can then bookmark the page with regression reports, and the page with the test results with your favourite settings From e50d8da0370a2dc0f208e270ca20804dc5be3447 Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Wed, 13 Apr 2022 20:14:00 +0200 Subject: [PATCH 056/452] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3265876..857da76 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ This repository provides scripts and documentation to run the nightly Modelica l ## Using the OpenModelica nightly testsuite -Some of the open-source Modelica libraries managed by the [Open Modelica Package Manager](https://github.com/OpenModelica/OMPackageManager) are tested on a daily basis on the OSMC servers. Test results are [publicly available](testresults.md). +Some of the open-source Modelica libraries managed by the [Open Modelica Package Manager](https://github.com/OpenModelica/OMPackageManager) are tested on a daily basis on the OSMC servers. Test results are [publicly available](testresults.md#open-source-modelica-library-testing-using-openmodelica). The configuration files for the OSMC nightly testsuite jobs are [conf.json](configs/conf.json) for the regular tests using the C runtime, and [conf-c++.json](configs/conf-c%2B%2B.json) for the tests using the C++ runtime. The setup of the configuration files is discussed in [conf-howto.md](conf-howto.md). From 5dbe4caa2f0cca7d284b434570a968d902ebdcb7 Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Wed, 13 Apr 2022 20:15:34 +0200 Subject: [PATCH 057/452] Update testresults.md --- testresults.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/testresults.md b/testresults.md index d896538..9ab2ea7 100644 --- a/testresults.md +++ b/testresults.md @@ -18,16 +18,18 @@ Clicking on the model name shows the log of phases from parsing to compilation. Many different reports are available: -- _Overview with library test results across versions_: These reports shows how libraries with full or partial support level +- **Overview with library test results across OMC versions**: These reports shows how libraries with full or partial support level (see [here](https://github.com/OpenModelica/OMPackageManager/blob/master/README.md#library-support-levels-in-openmodelica) for more details) - are handled by released versions of OpenModelica and by the development version on the master branch. Regressions are marked in orange, improvements in green + are handled by released versions of OpenModelica and by the development version on the master branch. Regressions are marked in orange, + improvements in green. - [Default settings](https://libraries.openmodelica.org/branches/overview.html): simulation with C runtime and default settings - [daeMode](https://libraries.openmodelica.org/branches/overview-dae.html): simulation with daeMode (compiler flag [--daeMode](https://openmodelica.org/doc/OpenModelicaUsersGuide/latest/omchelptext.html#omcflag-daemode)) - [C++](https://libraries.openmodelica.org/branches/overview-c++.html): simulation with C++ runtime - [FMI](https://libraries.openmodelica.org/branches/overview-fmi.html): simulation with FMI and C runtime - [FMI C++](https://libraries.openmodelica.org/branches/overview-c++.html): simulation with FMI and C++ runtime -- _Regression reports and history plots_: regression reports are periodically generated, using the latest development version of OMC. Changes w.r.t. the - previous report are shown. For each tested library, .svg plots are also provided, showing the trends of the results of each step over time +- **Regression reports and history plots**: regression reports are periodically generated, using the latest development version of OMC. + Changes w.r.t. the previous report are shown. For each tested library, .svg plots are also provided, showing the trends of the + results of each step over time. - [Default settings](https://libraries.openmodelica.org/branches/history/master/): default omc settings, C runtime - [daeMode](https://libraries.openmodelica.org/branches/history/daemode/): simulation with --daeMode - [C++](https://libraries.openmodelica.org/branches/history/cpp/): simulation with C++ runtime From 521b1817b8a7093dc60b65678e381ad369cea139 Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Wed, 13 Apr 2022 20:55:07 +0200 Subject: [PATCH 058/452] Created help file for setting up config.json --- conf-howto.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 conf-howto.md diff --git a/conf-howto.md b/conf-howto.md new file mode 100644 index 0000000..c1fe64c --- /dev/null +++ b/conf-howto.md @@ -0,0 +1,16 @@ +# How to set up the library testing configuration file + +The [conf.json](configs/conf.json) file specifies which versions of the libraries included in the package manager are ran, and with which options. +For each test entry, there are several fields: +- `library`: name of the library +- `libraryVersion`: version of the library; this is the content of the library version annotation for tagged versions, or the name of the branch + as specified in one of the `branches` field of the [repos.json](https://github.com/OpenModelica/OMPackageManager/blob/master/repos.json) file, + in case a non-tagged version needs to be tested. If no version is provided, the latest tagged version is tested automatically +- `libraryVersionNameForTests`: this is appended with an underscore to the name of the library in the test report name +- `ignoreModelPrefix`: skips testing all models that start with that string + +There are many other fields to manage reference results, that can be either stored locally on the server, or fetched from a remote GIT repository, +and for providing extra flags and settings to OMC when running the tests. Please refer to [conf.json](configs/conf.json) for more examples, and to +the [master result directory](https://libraries.openmodelica.org/branches/master/) for an example of the corresponding output. Please +note that some files and/or directory there may be leftovers of old test runs, only consider recent ones if you want to understand what the outcome +of a certain test configuration is. From e6f6f83504df4df348c5802a2018bc33dbfd2b27 Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Wed, 13 Apr 2022 21:00:01 +0200 Subject: [PATCH 059/452] Update README.md --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 857da76..fb9280b 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,11 @@ This repository provides scripts and documentation to run the nightly Modelica library tests for OpenModelica. -## Using the OpenModelica nightly testsuite +## OpenModelica nightly testsuite -Some of the open-source Modelica libraries managed by the [Open Modelica Package Manager](https://github.com/OpenModelica/OMPackageManager) are tested on a daily basis on the OSMC servers. Test results are [publicly available](testresults.md#open-source-modelica-library-testing-using-openmodelica). +Some of the open-source Modelica libraries managed by the [Open Modelica Package Manager](https://github.com/OpenModelica/OMPackageManager) are tested on a daily basis on the OSMC servers. + +[Test results reports](testresults.md#open-source-modelica-library-testing-using-openmodelica) are publicly available. The configuration files for the OSMC nightly testsuite jobs are [conf.json](configs/conf.json) for the regular tests using the C runtime, and [conf-c++.json](configs/conf-c%2B%2B.json) for the tests using the C++ runtime. The setup of the configuration files is discussed in [conf-howto.md](conf-howto.md). From 2980d2d19425a024d1db60e2c2e2b7419d4eda2b Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Wed, 13 Apr 2022 21:01:50 +0200 Subject: [PATCH 060/452] Update testresults.md --- testresults.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testresults.md b/testresults.md index 9ab2ea7..3902e3e 100644 --- a/testresults.md +++ b/testresults.md @@ -1,4 +1,4 @@ -# Open-Source Modelica Library Testing using OpenModelica +# Test Results of Open-Source Modelica Libraries using OpenModelica The library testsuite job is run every night on the OSMC servers, testing open-source Modelica libraries covered by the [Package Manager](https://github.com/OpenModelica/OMPackageManager#readme) with various versions of OpenModelica, From abd3d9e60b29a43ce068832c672023f245e51636 Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Thu, 14 Apr 2022 01:09:09 +0200 Subject: [PATCH 061/452] Update testresults.md --- testresults.md | 43 +++++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/testresults.md b/testresults.md index 3902e3e..56c3056 100644 --- a/testresults.md +++ b/testresults.md @@ -1,22 +1,6 @@ # Test Results of Open-Source Modelica Libraries using OpenModelica -The library testsuite job is run every night on the OSMC servers, testing open-source Modelica libraries covered by the -[Package Manager](https://github.com/OpenModelica/OMPackageManager#readme) with various versions of OpenModelica, -including the development version on the master branch. The simulations are run with the C-runtime, unless specified differently. - -Within each library, all models with an experiment(StopTime) annotations are run. For each tested model, the results of the following steps are reported: -- _parsing_ -- _frontend_: flattening the model -- _backend_: structural analysis, index reduction, causalization, tearing, and all kind of symbolic manipulations and optimization to solve the model efficiently -- _simcode_: intermediate stap towards simulation code generation -- _templates_: generation of the actual C code -- _compilation_: compilation of the C code into a simulation executable -- _simulation_: the simulation is actually run to produce simulation results -- _verification_: if reference results file are available, they are compared with the simulation results - -Clicking on the model name shows the log of phases from parsing to compilation. Clicking on the (sim) link shows the log of the runtime simulation. - -Many different reports are available: +## Test reports - **Overview with library test results across OMC versions**: These reports shows how libraries with full or partial support level (see [here](https://github.com/OpenModelica/OMPackageManager/blob/master/README.md#library-support-levels-in-openmodelica) for more details) @@ -35,6 +19,25 @@ Many different reports are available: - [C++](https://libraries.openmodelica.org/branches/history/cpp/): simulation with C++ runtime - [FMI](https://libraries.openmodelica.org/branches/history/master-fmi/): simulation with FMI, C runtime -If you are actively developing a library, it is recommended to have two tests for it: one testing the latest official release, which can be used -to check if changes to OMC cause regressions to the existing library, another one testing the development version, which also checks regressions -caused by changes to the library code. You can then bookmark the page with regression reports, and the page with the test results with your favourite settings +## How to read the test reports + +The library testsuite job is run every night on the OSMC servers, testing open-source Modelica libraries covered by the +[Package Manager](https://github.com/OpenModelica/OMPackageManager#readme) with various versions of OpenModelica, +including the development version on the master branch. The simulations are run with the C-runtime, unless specified differently. + +Within each library, all models with an experiment(StopTime) annotations are run. For each tested model, the results of the following steps are reported: +- _parsing_ +- _frontend_: flattening the model +- _backend_: structural analysis, index reduction, causalization, tearing, and all kind of symbolic manipulations and optimization to solve the model efficiently +- _simcode_: intermediate stap towards simulation code generation +- _templates_: generation of the actual C code +- _compilation_: compilation of the C code into a simulation executable +- _simulation_: the simulation is actually run to produce simulation results +- _verification_: if reference results file are available, they are compared with the simulation results + +Clicking on the model name shows the log of phases from parsing to compilation. Clicking on the (sim) link shows the log of the runtime simulation. + +## How to get your open-source library in the testsuite + +If you are actively developing an open-source Modelica library using a GIT repository, you can easily get it included in the OpenModelica library testsuite. Please open a request on the [OpenModelica issue tracker](https://github.com/OpenModelica/OpenModelica/issues/new/choose). +Ideally, you should have two tests for it: one testing the latest official release, which can be used to check if changes to OMC cause regressions to the existing library, another one testing the development version, which also checks regressions caused by changes to the library code. You can then bookmark the page with the regression reports and the page with the test results obtained with your favourite settings. From 7d2e2435f7fe98eb9fb1ad5a68921819b892db5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Thu, 28 Apr 2022 08:11:57 +0200 Subject: [PATCH 062/452] Path changed on the server --- .CI/Jenkinsfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index 24076fd..3a7ed3d 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -563,7 +563,7 @@ def installLibraries(boolean removePackageOrder, boolean conversionScript, name, sh """ cd '${WORKSPACE}/OpenModelicaLibraryTesting' OPENMODELICAHOME="${omhomeTestedOMC}" ./conversionscript.py --diff --allowErrorsInDiff '${env.HOME}/saved_omc/libraries/.openmodelica/libraries' - scp converted-libraries/.openmodelica/libraries/*.diff 'libraries.openmodelica.org:/var/www/branches/${name}' + scp converted-libraries/.openmodelica/libraries/*.diff 'libraries.openmodelica.org:/var/www/libraries.openmodelica.org/branches/${name}' """ return "${WORKSPACE}/OpenModelicaLibraryTesting/converted-libraries" } else { @@ -728,7 +728,7 @@ def test(branch, name, extraFlags, omsHash, dbPrefix, sshConfig, omcompiler, ext git fetch git reset --hard origin/master - mkdir -p "/var/www/branches/${name}/" + mkdir -p "/var/www/libraries.openmodelica.org/branches/${name}/" """ def libraryPath = installLibraries(removePackageOrder, conversionScript, name, "${WORKSPACE}/OpenModelica/${OMCPATH}/build") @@ -757,7 +757,7 @@ def test(branch, name, extraFlags, omsHash, dbPrefix, sshConfig, omcompiler, ext export HOME="${libraryPath}" cd OpenModelicaLibraryTesting # Force /usr/bin/omc as being used for generating the mos-files. Ensures consistent behavior among all tested OMC versions - stdbuf -oL -eL time ./test.py --ompython_omhome=/usr ${FMI_TESTING_FLAG} --extraflags='${extraFlags}' --extrasimflags='${extrasimflags}' --branch="${name}" --output="libraries.openmodelica.org:/var/www/branches/${name}/" --libraries='${libraryPath}/.openmodelica/libraries/' configs/conf.json ${params.OLDLIBS ? "configs/conf-old.json configs/conf-nonstandard.json" : ""} || (killall omc ; false) || exit 1 + stdbuf -oL -eL time ./test.py --ompython_omhome=/usr ${FMI_TESTING_FLAG} --extraflags='${extraFlags}' --extrasimflags='${extrasimflags}' --branch="${name}" --output="libraries.openmodelica.org:/var/www/branches/libraries.openmodelica.org/${name}/" --libraries='${libraryPath}/.openmodelica/libraries/' configs/conf.json ${params.OLDLIBS ? "configs/conf-old.json configs/conf-nonstandard.json" : ""} || (killall omc ; false) || exit 1 """ sh 'date' sh "rm -f OpenModelicaLibraryTesting/${dbPrefix}-sqlite3.db.tmp" From 3acdaba70fb6d74fdd5b5db7bd60791e4bae800a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Thu, 12 May 2022 08:01:49 +0200 Subject: [PATCH 063/452] Fix swapped order of directories --- .CI/Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index 3a7ed3d..c36d4b7 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -757,7 +757,7 @@ def test(branch, name, extraFlags, omsHash, dbPrefix, sshConfig, omcompiler, ext export HOME="${libraryPath}" cd OpenModelicaLibraryTesting # Force /usr/bin/omc as being used for generating the mos-files. Ensures consistent behavior among all tested OMC versions - stdbuf -oL -eL time ./test.py --ompython_omhome=/usr ${FMI_TESTING_FLAG} --extraflags='${extraFlags}' --extrasimflags='${extrasimflags}' --branch="${name}" --output="libraries.openmodelica.org:/var/www/branches/libraries.openmodelica.org/${name}/" --libraries='${libraryPath}/.openmodelica/libraries/' configs/conf.json ${params.OLDLIBS ? "configs/conf-old.json configs/conf-nonstandard.json" : ""} || (killall omc ; false) || exit 1 + stdbuf -oL -eL time ./test.py --ompython_omhome=/usr ${FMI_TESTING_FLAG} --extraflags='${extraFlags}' --extrasimflags='${extrasimflags}' --branch="${name}" --output="libraries.openmodelica.org:/var/www/libraries.openmodelica.org/branches/${name}/" --libraries='${libraryPath}/.openmodelica/libraries/' configs/conf.json ${params.OLDLIBS ? "configs/conf-old.json configs/conf-nonstandard.json" : ""} || (killall omc ; false) || exit 1 """ sh 'date' sh "rm -f OpenModelicaLibraryTesting/${dbPrefix}-sqlite3.db.tmp" From 635d758770573817ddee26e785d0e75890d9e536 Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Sat, 21 May 2022 01:08:04 +0200 Subject: [PATCH 064/452] Added IDEAS library --- .CI/installLibraries.mos | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.CI/installLibraries.mos b/.CI/installLibraries.mos index b623814..8929bda 100644 --- a/.CI/installLibraries.mos +++ b/.CI/installLibraries.mos @@ -28,6 +28,8 @@ for l in { {"Annex60", ""}, {"BLDC", ""}, {"ExtendedPetriNets", ""}, + {"IDEAS", ""}, + {"IDEAS", "master"}, {"iPSL", ""}, {"PhotoVoltaics", ""}, {"PhotoVoltaics_TGM", ""}, From dae409735153acb7ae44751bc8232a336999afb3 Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Sat, 21 May 2022 01:10:20 +0200 Subject: [PATCH 065/452] Added reference to installLibraries.mos --- conf-howto.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/conf-howto.md b/conf-howto.md index c1fe64c..6958ba6 100644 --- a/conf-howto.md +++ b/conf-howto.md @@ -14,3 +14,5 @@ and for providing extra flags and settings to OMC when running the tests. Please the [master result directory](https://libraries.openmodelica.org/branches/master/) for an example of the corresponding output. Please note that some files and/or directory there may be leftovers of old test runs, only consider recent ones if you want to understand what the outcome of a certain test configuration is. + +Note that in order to test a library it is also necessary to have it installed by the CI. In order to do that, it needs to be added to the [installLibraries.mos](https://github.com/OpenModelica/OpenModelicaLibraryTesting/blob/master/.CI/installLibraries.mos) file. From e76476acee06c122abf4bd79b45ebb994a8eb1e2 Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Sat, 21 May 2022 01:13:35 +0200 Subject: [PATCH 066/452] Removed ThermoFluidStream OM_adaptions --- configs/conf.json | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/configs/conf.json b/configs/conf.json index 5dda4ef..67f9ef2 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -349,16 +349,6 @@ "allReferenceFilesExist":false, "referenceFiles":"$THERMOFLUIDSTREAMREFS" }, - { - "library":"ThermofluidStream", - "libraryVersion":"OM_adaptions", - "ulimitExe":1200, - "referenceFileExtension":"mat", - "referenceFileNameDelimiter":".", - "referenceFinalDot":"_ref.", - "allReferenceFilesExist":false, - "referenceFiles":"$THERMOFLUIDSTREAMREFSOM" - }, { "library":"ThermalSeparation", "extraCustomCommands":["setCommandLineOptions(\"-d=-NLSanalyticJacobian\")"] From b5e07b726288ea99919394045efe5d3034eaabcf Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Sat, 21 May 2022 01:14:51 +0200 Subject: [PATCH 067/452] Removed ThermoFluidStreams OM_adaptions --- .CI/installLibraries.mos | 1 - 1 file changed, 1 deletion(-) diff --git a/.CI/installLibraries.mos b/.CI/installLibraries.mos index 8929bda..27ad078 100644 --- a/.CI/installLibraries.mos +++ b/.CI/installLibraries.mos @@ -42,7 +42,6 @@ for l in { {"OpenIPSL", ""}, {"Physiomodel", ""}, {"ThermofluidStream", "main"}, - {"ThermofluidStream", "0.4.0-OM_adaptions"}, {"TILMedia", "main"} } loop if not installPackage(stringTypeName(l[1]), l[2]) then From d8ac21fa7c1e67c18ea88c6d3e2fdfc1f4149bf1 Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Mon, 23 May 2022 17:35:06 +0200 Subject: [PATCH 068/452] Update conf-howto.md --- conf-howto.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/conf-howto.md b/conf-howto.md index 6958ba6..e832bbc 100644 --- a/conf-howto.md +++ b/conf-howto.md @@ -4,7 +4,7 @@ The [conf.json](configs/conf.json) file specifies which versions of the librarie For each test entry, there are several fields: - `library`: name of the library - `libraryVersion`: version of the library; this is the content of the library version annotation for tagged versions, or the name of the branch - as specified in one of the `branches` field of the [repos.json](https://github.com/OpenModelica/OMPackageManager/blob/master/repos.json) file, + as specified in one of the `branches` field of the Package Manager server [repos.json](https://github.com/OpenModelica/OMPackageManager/blob/master/repos.json) file, in case a non-tagged version needs to be tested. If no version is provided, the latest tagged version is tested automatically - `libraryVersionNameForTests`: this is appended with an underscore to the name of the library in the test report name - `ignoreModelPrefix`: skips testing all models that start with that string @@ -15,4 +15,6 @@ the [master result directory](https://libraries.openmodelica.org/branches/master note that some files and/or directory there may be leftovers of old test runs, only consider recent ones if you want to understand what the outcome of a certain test configuration is. -Note that in order to test a library it is also necessary to have it installed by the CI. In order to do that, it needs to be added to the [installLibraries.mos](https://github.com/OpenModelica/OpenModelicaLibraryTesting/blob/master/.CI/installLibraries.mos) file. +Note that in order to test a library it is also necessary to +- include it in the package manager (see the [OMPackageManager Instructions](https://github.com/OpenModelica/OMPackageManager#readme)), where it is possible to configure branches that may be tested besides the tagged released versions, e.g. the master branch or some maintenance branch +- have it installed by the CI. In order to do that, it needs to be added to the [installLibraries.mos](https://github.com/OpenModelica/OpenModelicaLibraryTesting/blob/master/.CI/installLibraries.mos) file. From ce208f3faab8a777137ca16400a8b23bb5d6f5a6 Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Wed, 1 Jun 2022 15:57:34 +0200 Subject: [PATCH 069/452] add release 1.19 to the testing --- .CI/Jenkinsfile | 58 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 55 insertions(+), 3 deletions(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index c36d4b7..f378402 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -9,6 +9,7 @@ pipeline { booleanParam(name: 'v1_16', defaultValue: false, description: 'maintenance/v1.16 branch (ryzen-5950x-1)') booleanParam(name: 'v1_17', defaultValue: false, description: 'maintenance/v1.17 branch (ryzen-5950x-1)') booleanParam(name: 'v1_18', defaultValue: false, description: 'maintenance/v1.18 branch (ryzen-5950x-1)') + booleanParam(name: 'v1_19', defaultValue: false, description: 'maintenance/v1.19 branch (ryzen-5950x-1)') booleanParam(name: 'master', defaultValue: false, description: 'master branch (ryzen-5950x-1)') booleanParam(name: 'fmi_v1_12', defaultValue: false, description: 'maintenance/v1.12 branch with FMI (ryzen-5950x-2)') @@ -17,11 +18,13 @@ pipeline { booleanParam(name: 'fmi_v1_16', defaultValue: false, description: 'maintenance/v1.16 branch with FMI (ryzen-5950x-2)') booleanParam(name: 'fmi_v1_17', defaultValue: false, description: 'maintenance/v1.17 branch with FMI (ryzen-5950x-2)') booleanParam(name: 'fmi_v1_18', defaultValue: false, description: 'maintenance/v1.18 branch with FMI (ryzen-5950x-2)') + booleanParam(name: 'fmi_v1_19', defaultValue: false, description: 'maintenance/v1.19 branch with FMI (ryzen-5950x-2)') booleanParam(name: 'fmi_master', defaultValue: false, description: 'master branch with FMI (ryzen-5950x-2)') booleanParam(name: 'newInst_daeMode', defaultValue: false, description: 'master branch, --daeMode with -d=newInst (ryzen-5950x-2)') booleanParam(name: 'newInst_newBackend', defaultValue: false, description: 'master branch, -d=newInst --newBackend, (ryzen-5950x-1)') booleanParam(name: 'oldInst', defaultValue: false, description: 'master branch, with -d=nonewInst (ryzen-5950x-2)') booleanParam(name: 'cpp_v1_18', defaultValue: false, description: 'maintenance/v1.18 branch, with --simCodeTarget=Cpp (ryzen-5950x-2).') + booleanParam(name: 'cpp_v1_19', defaultValue: false, description: 'maintenance/v1.19 branch, with --simCodeTarget=Cpp (ryzen-5950x-2).') booleanParam(name: 'cpp', defaultValue: false, description: 'master branch, with --simCodeTarget=Cpp (ryzen-5950x-2).') booleanParam(name: 'report_ryzen_5950x_1', defaultValue: false, description: 'Generate a report for ryzen-5950x-1 without running the tests') booleanParam(name: 'report_ryzen_5950x_2', defaultValue: false, description: 'Generate a report for ryzen-5950x-2 without running the tests') @@ -136,6 +139,23 @@ pipeline { test('maintenance/v1.18', 'v1.18', '', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', false, false) } } + + stage('v1.19') { + agent { + node { + label 'ryzen-5950x-1' + customWorkspace 'ws/OpenModelicaLibraryTestingWork' + } + } + options { skipDefaultCheckout() } + when { + beforeAgent true + expression { params.v1_19 } + } + steps { + test('maintenance/v1.19', 'v1.19', '', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', false, false) + } + } stage('master') { agent { @@ -284,6 +304,22 @@ pipeline { test('maintenance/v1.18', 'v1.18-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) } } + stage('v1.19 FMI') { + agent { + node { + label 'ryzen-5950x-2-1' + customWorkspace 'ws/OpenModelicaLibraryTestingWork' + } + } + options { skipDefaultCheckout() } + when { + beforeAgent true + expression { params.fmi_v1_19 } + } + steps { + test('maintenance/v1.19', 'v1.19-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) + } + } stage('master FMI') { agent { node { @@ -364,6 +400,22 @@ pipeline { test('maintenance/v1.18', 'v1.18-cpp', 'setCommandLineOptions("--simCodeTarget=Cpp")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) } } + stage('C++ v1.19') { + agent { + node { + label 'ryzen-5950x-2-1' + customWorkspace 'ws/OpenModelicaLibraryTestingWork' + } + } + options { skipDefaultCheckout() } + when { + beforeAgent true + expression { params.cpp_v1_19 } + } + steps { + test('maintenance/v1.19', 'v1.19-cpp', 'setCommandLineOptions("--simCodeTarget=Cpp")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) + } + } stage('C++') { agent { node { @@ -395,7 +447,7 @@ pipeline { expression { params.v1_12 || params.v1_13 || params.v1_14 || params.v1_16 || params.v1_17 || params.master || params.conversion_script || params.report_ryzen_5950x_1 | params.newInst_newBackend} } environment { - GITBRANCHES = 'maintenance/v1.12 maintenance/v1.13 maintenance/v1.14 maintenance/v1.16 maintenance/v1.17 maintenance/v1.18 master' + GITBRANCHES = 'maintenance/v1.12 maintenance/v1.13 maintenance/v1.14 maintenance/v1.16 maintenance/v1.17 maintenance/v1.18 maintenance/v1.19 master' PYTHONIOENCODING = 'utf-8' } steps { @@ -445,10 +497,10 @@ pipeline { expression { params.fmi_v1_12 || params.fmi_v1_13 || params.fmi_v1_14 || params.fmi_v1_16 || params.fmi_v1_17 || params.fmi_master || params.newInst_daeMode || params.oldInst || params.report_ryzen_5950x_2 || params.cvode || params.cpp } } environment { - GITBRANCHES_FMI = 'maintenance/v1.12-fmi maintenance/v1.13-fmi maintenance/v1.14-fmi maintenance/v1.16-fmi maintenance/v1.17-fmi maintenance/v1.18-fmi master-fmi' + GITBRANCHES_FMI = 'maintenance/v1.12-fmi maintenance/v1.13-fmi maintenance/v1.14-fmi maintenance/v1.16-fmi maintenance/v1.17-fmi maintenance/v1.18-fmi maintenance/v1.19-fmi master-fmi' GITBRANCHES_NEWINST = 'oldInst' GITBRANCHES_DAE = 'daemode newInst-daemode' - GITBRANCHES_CPP = 'v1.18-cpp cpp' + GITBRANCHES_CPP = 'v1.18-cpp v1.19-cpp cpp' PYTHONIOENCODING = 'utf-8' } steps { From 98e2725e4ab3d44d5dcc06740e47a92dba1fbf9c Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Sat, 4 Jun 2022 18:57:19 +0200 Subject: [PATCH 070/452] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index fb9280b..2437590 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,9 @@ Some of the open-source Modelica libraries managed by the [Open Modelica Package [Test results reports](testresults.md#open-source-modelica-library-testing-using-openmodelica) are publicly available. -The configuration files for the OSMC nightly testsuite jobs are [conf.json](configs/conf.json) for the regular tests using the C runtime, and [conf-c++.json](configs/conf-c%2B%2B.json) for the tests using the C++ runtime. The setup of the configuration files is discussed in [conf-howto.md](conf-howto.md). +The configuration file for the regular library nightly testsuite is [conf.json](configs/conf.json). Additional old and non-standard libraries are listed in [conf-old.json](configs/conf-old.json) and [conf-nonstandard.json](configs/conf-nonstandard.json), note that failures in those libraries may be due to the fact that they are not fully complying with the Modelica standard, rather than to OpenModelica issues. The setup of the configuration files is discussed in [conf-howto.md](conf-howto.md). + +Test results reports are collected in the https://libraries.openmodelica.org/branches/ directory. The [overview.html](https://libraries.openmodelica.org/branches/overview.html) report gives the results of the regular testsuite with the default C runtime and solvers. Other reports contain the results using the C++ runtime, FMI, daeMode, and the old frontend. Combined reports also include results from the old and nonstandard libraries. The https://libraries.openmodelica.org/branches/history/ directory contains regression reports and plots using different versions (including master) and simulation runtime configurations (C++, daeMode, FMI, old frontend) of OpenModelica. If you want to include your open-source library in the testsuite, please open a pull request on [conf.json](configs/conf.json), or open an issue on the [OpenModelica issue tracker](https://github.com/OpenModelica/OpenModelica/issues/new/choose) and ask us to do it for you. From db73333ae0b5e747faa88196697815be257f372e Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Sat, 4 Jun 2022 19:30:42 +0200 Subject: [PATCH 071/452] Removed obsolete Modelica_Synchronous --- configs/conf.json | 7 ------- 1 file changed, 7 deletions(-) diff --git a/configs/conf.json b/configs/conf.json index 67f9ef2..854947b 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -62,13 +62,6 @@ { "library":"ModelicaTestOverdetermined" }, - { - "library":"Modelica_Synchronous", - "libraryVersion":"master", - "libraryVersionNameForTests":"", - "extraCustomCommands":["if not setCommandLineOptions(\"--std=3.3\") then exit(1); end if;"], - "referenceFiles":"$REFERENCEFILES/Modelica_Synchronous" - }, { "library":"Modelica_DeviceDrivers", "libraryVersion":"master", From ecfea9dc161a64a2697def9ea1b71befde5770be Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Sat, 4 Jun 2022 19:31:58 +0200 Subject: [PATCH 072/452] Added obsolete Modelica_Synchronous Has some issues, but they won't be fixed because the library is superseded by Modelica.Clocked. --- configs/conf-old.json | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/configs/conf-old.json b/configs/conf-old.json index 4483c4a..bf4f448 100644 --- a/configs/conf-old.json +++ b/configs/conf-old.json @@ -31,6 +31,13 @@ "library":"Modelica", "libraryVersion":"3.2.1" }, + { + "library":"Modelica_Synchronous", + "libraryVersion":"master", + "libraryVersionNameForTests":"", + "extraCustomCommands":["if not setCommandLineOptions(\"--std=3.3\") then exit(1); end if;"], + "referenceFiles":"$REFERENCEFILES/Modelica_Synchronous" + }, { "library":"ModelicaTest", "libraryVersion":"3.2.1" From 997566eb972517b4013a252131afda1afbdfd1ae Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Sat, 4 Jun 2022 19:33:44 +0200 Subject: [PATCH 073/452] Removed Buildings 7.0.x As per indication of @mwetter, we should now focus on getting 8.x.y and 9.x.y working on OMC --- configs/conf.json | 6 ------ 1 file changed, 6 deletions(-) diff --git a/configs/conf.json b/configs/conf.json index 854947b..6c099f8 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -118,12 +118,6 @@ "library":"BLDC", "libraryVersionNameForTests":"" }, - { - "library":"Buildings", - "ignoreModelPrefix":"Buildings.Utilities.IO.BCVTB.Examples", - "libraryVersion":"maint.7.0.x", - "libraryVersionLatestInPackageManager":true - }, { "library":"Buildings", "ignoreModelPrefix":"Buildings.Utilities.IO.BCVTB.Examples", From c9ff0d76849c57418023aa28e7db7433f4386f58 Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Sat, 4 Jun 2022 19:35:01 +0200 Subject: [PATCH 074/452] Moved Buildings 7.0.x to old libraries As per indication of @mwetter to focus on 8.x.y and 9.x.y --- configs/conf-old.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/configs/conf-old.json b/configs/conf-old.json index bf4f448..3f9e13c 100644 --- a/configs/conf-old.json +++ b/configs/conf-old.json @@ -11,6 +11,12 @@ "library":"Buildings", "libraryVersion":"3.0.0" }, + { + "library":"Buildings", + "ignoreModelPrefix":"Buildings.Utilities.IO.BCVTB.Examples", + "libraryVersion":"maint.7.0.x", + "libraryVersionLatestInPackageManager":true + }, { "library":"iPSL" }, From dee31439be51bdb30b7702107c7679b4644db6f6 Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Sat, 4 Jun 2022 19:40:45 +0200 Subject: [PATCH 075/452] Removed obsolete libraries --- configs/conf.json | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/configs/conf.json b/configs/conf.json index 6c099f8..e8aad63 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -68,11 +68,6 @@ "libraryVersionNameForTests":"", "extraCustomCommands":["if not setCommandLineOptions(\"--std=3.3\") then exit(1); end if;"] }, - { - "library":"Modelica_Noise", - "libraryVersion":"master", - "libraryVersionNameForTests":"" - }, { "library":"PowerGrids" }, @@ -159,11 +154,6 @@ "referenceFileNameDelimiter":".", "referenceFiles":"/mnt/ReferenceFiles/ExtraLibs/clara_om.git/ReferenceResults" }, - { - "library":"ConPNlib", - "libraryVersion":"master", - "libraryVersionNameForTests":"" - }, { "library":"ElectricalEnergyStorage" }, @@ -173,9 +163,6 @@ { "library":"ExternData" }, - { - "library":"ExternalMemoryLib" - }, { "library":"FastBuildings" }, From 698209cc4a4f4dcb9f86a99fe4364bb50a1d1a48 Mon Sep 17 00:00:00 2001 From: Andreas <38031952+AnHeuermann@users.noreply.github.com> Date: Tue, 14 Jun 2022 14:30:15 +0200 Subject: [PATCH 076/452] How to set simulation flags (#21) --- README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2437590..ab738a9 100644 --- a/README.md +++ b/README.md @@ -67,10 +67,17 @@ The scripts from this repository can be used to run regression tests for public, ``` You can add extra compiler settings + ```json "extraCustomCommands":["setCommandLineOptions(\"--std=3.2\");"] ``` - and more. Check `config/conf.json` for more. + and extra simulation flags + + ```json + "extraSimFlags": "-s=ida -nls=kinsol" + ``` + + Check `config/conf.json` for more. - If you used `.CI/installLibraries.mos` to test all libraries you'll need to install reference results and set environment variables, see [Reference Results](#reference-results). ```bash export MSLREFERENCE="/path/to/ReferenceFiles/" From 77eb84e6fed8c87aacfb0327ce280bf1f37b0d3e Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Wed, 22 Jun 2022 01:14:17 +0200 Subject: [PATCH 077/452] Added FluxTubesExtension library --- configs/conf.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/configs/conf.json b/configs/conf.json index e8aad63..35b73b0 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -165,6 +165,11 @@ }, { "library":"FastBuildings" + }, + { + "library":"FluxTubesExtension", + "libraryVersion":"master", + "libraryVersionNameForTests":"" }, { "library":"HanserModelica" From e2a8c3d2f8fe81d95237457f7cc88e2a0c3b1785 Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Wed, 22 Jun 2022 01:29:41 +0200 Subject: [PATCH 078/452] Added FluxTubesExtension --- .CI/installLibraries.mos | 1 + 1 file changed, 1 insertion(+) diff --git a/.CI/installLibraries.mos b/.CI/installLibraries.mos index 27ad078..4028dd1 100644 --- a/.CI/installLibraries.mos +++ b/.CI/installLibraries.mos @@ -28,6 +28,7 @@ for l in { {"Annex60", ""}, {"BLDC", ""}, {"ExtendedPetriNets", ""}, + {"FluxTubesExtension","master"}, {"IDEAS", ""}, {"IDEAS", "master"}, {"iPSL", ""}, From 493532e03687b9c01e99b97cf94f80d8ecc46a69 Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Wed, 22 Jun 2022 01:51:34 +0200 Subject: [PATCH 079/452] Updated OpenIPSL settings --- configs/conf.json | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/configs/conf.json b/configs/conf.json index 35b73b0..3cd2340 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -215,13 +215,16 @@ }, { "library":"OpenIPSL", - "libraryVersion":"master", - "libraryVersionNameForTests":"" + "libraryVersion":"2.0.0", }, { "library":"OpenIPSL", - "libraryVersion":"", - "libraryVersionNameForTests":"release" + "libraryVersion":"3.0.0", + }, + { + "library":"OpenIPSL", + "libraryVersion":"master", + "libraryVersionNameForTests":"dev" }, { "library":"PhotoVoltaics" From f612817ccf7dfa4c3aff65eceb5ec5edd5b29350 Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Wed, 22 Jun 2022 01:54:21 +0200 Subject: [PATCH 080/452] Updated OpenIPSL --- .CI/installLibraries.mos | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.CI/installLibraries.mos b/.CI/installLibraries.mos index 4028dd1..e5164d6 100644 --- a/.CI/installLibraries.mos +++ b/.CI/installLibraries.mos @@ -15,6 +15,12 @@ for v in {"1.6", "3.0.0", "maint.7.0.x", "maint.8.1.x", "master"} loop exit(1); end if; end for; +for v in {"2.0.0", "3.0.0", "master"} loop + if not installPackage(OpenIPSL, v) then + print("OpenIPSL " + v + " " + getErrorString() + "\n"); + exit(1); + end if; +end for; for lib in {"AdvancedNoise", "AixLib", "BioChem", "BuildingSystems", "BuildSysPro", "Chemical", "ClaRa_Obsolete", "ClaRa", "ConPNlib", "ElectricalEnergyStorage", "ExternData", "ExternalMemoryLib", "FastBuildings", "FCSys", "HanserModelica", "HelmholtzMedia", "IBPSA", "IdealizedContact", "IndustrialControlSystems", "KeyWordIO", "LibRAS", "MEV", "MessagePack", "ModelicaByExample", "ModelicaTestOverdetermined", "Modelica_Synchronous", "Modelica_DeviceDrivers", "Modelica_LinearSystems2", "Modelica_Noise", "ObjectStab", "OpenHydraulics", "OpenIPSL", "PNlib", "Physiolibrary", "PlanarMechanics", "PowerGrids", "PowerSysPro", "ScalableTestGrids", "ScalableTestSuite", "SolarTherm", "Spot", "SystemDynamics", "TAeZoSysPro", "TAeZoSysPro_testsuite", "ThermalSeparation", "ThermoPower", "ThermoSysPro", "VehicleInterfaces"} loop if not installPackage(stringTypeName(lib), "master") then @@ -40,7 +46,6 @@ for l in { {"SiemensPower","OMCtest"}, {"Modelica_LinearSystems2", "dev"}, {"Modelica_StateGraph2", ""}, - {"OpenIPSL", ""}, {"Physiomodel", ""}, {"ThermofluidStream", "main"}, {"TILMedia", "main"} From 7cb2d00fdcfa6668caef71d29b07efb4d462dd7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20=C3=96stlund?= Date: Thu, 23 Jun 2022 13:09:52 +0200 Subject: [PATCH 081/452] Fix FluxTubesExtension branch --- .CI/installLibraries.mos | 2 +- configs/conf.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.CI/installLibraries.mos b/.CI/installLibraries.mos index e5164d6..8034048 100644 --- a/.CI/installLibraries.mos +++ b/.CI/installLibraries.mos @@ -34,7 +34,7 @@ for l in { {"Annex60", ""}, {"BLDC", ""}, {"ExtendedPetriNets", ""}, - {"FluxTubesExtension","master"}, + {"FluxTubesExtension","main"}, {"IDEAS", ""}, {"IDEAS", "master"}, {"iPSL", ""}, diff --git a/configs/conf.json b/configs/conf.json index 3cd2340..8ae71f5 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -168,7 +168,7 @@ }, { "library":"FluxTubesExtension", - "libraryVersion":"master", + "libraryVersion":"main", "libraryVersionNameForTests":"" }, { From cf8d3dd9f9826627b1664726133d812c07e6ac8b Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Thu, 23 Jun 2022 19:01:46 +0200 Subject: [PATCH 082/452] Bumped OpenIPSL patch version And set 3.0.x for the test name --- configs/conf.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/configs/conf.json b/configs/conf.json index 8ae71f5..f069ddd 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -215,11 +215,12 @@ }, { "library":"OpenIPSL", - "libraryVersion":"2.0.0", + "libraryVersion":"2.0.0" }, { "library":"OpenIPSL", - "libraryVersion":"3.0.0", + "libraryVersion":"3.0.1" + "libraryVersionNameForTests":"3.0.x", }, { "library":"OpenIPSL", From fc9637192eb3a0533345ba93517faaf73c0670d7 Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Thu, 23 Jun 2022 19:03:02 +0200 Subject: [PATCH 083/452] Fixed typo in conf.json --- configs/conf.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configs/conf.json b/configs/conf.json index f069ddd..aa80195 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -219,8 +219,8 @@ }, { "library":"OpenIPSL", - "libraryVersion":"3.0.1" - "libraryVersionNameForTests":"3.0.x", + "libraryVersion":"3.0.1", + "libraryVersionNameForTests":"3.0.x" }, { "library":"OpenIPSL", From 9593702dd1556a0a28eea72fa6270a9ebb26eb5e Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Thu, 23 Jun 2022 19:08:14 +0200 Subject: [PATCH 084/452] Changed report config from 3.0.x to latest release --- configs/conf.json | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/configs/conf.json b/configs/conf.json index aa80195..0a2329a 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -218,9 +218,7 @@ "libraryVersion":"2.0.0" }, { - "library":"OpenIPSL", - "libraryVersion":"3.0.1", - "libraryVersionNameForTests":"3.0.x" + "library":"OpenIPSL" }, { "library":"OpenIPSL", From ce61b66309f09cb8bde7c39aa7740dea787b5aff Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Thu, 23 Jun 2022 19:11:16 +0200 Subject: [PATCH 085/452] Changed from 3.0.0 to latest released --- .CI/installLibraries.mos | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/.CI/installLibraries.mos b/.CI/installLibraries.mos index 8034048..132f099 100644 --- a/.CI/installLibraries.mos +++ b/.CI/installLibraries.mos @@ -15,12 +15,6 @@ for v in {"1.6", "3.0.0", "maint.7.0.x", "maint.8.1.x", "master"} loop exit(1); end if; end for; -for v in {"2.0.0", "3.0.0", "master"} loop - if not installPackage(OpenIPSL, v) then - print("OpenIPSL " + v + " " + getErrorString() + "\n"); - exit(1); - end if; -end for; for lib in {"AdvancedNoise", "AixLib", "BioChem", "BuildingSystems", "BuildSysPro", "Chemical", "ClaRa_Obsolete", "ClaRa", "ConPNlib", "ElectricalEnergyStorage", "ExternData", "ExternalMemoryLib", "FastBuildings", "FCSys", "HanserModelica", "HelmholtzMedia", "IBPSA", "IdealizedContact", "IndustrialControlSystems", "KeyWordIO", "LibRAS", "MEV", "MessagePack", "ModelicaByExample", "ModelicaTestOverdetermined", "Modelica_Synchronous", "Modelica_DeviceDrivers", "Modelica_LinearSystems2", "Modelica_Noise", "ObjectStab", "OpenHydraulics", "OpenIPSL", "PNlib", "Physiolibrary", "PlanarMechanics", "PowerGrids", "PowerSysPro", "ScalableTestGrids", "ScalableTestSuite", "SolarTherm", "Spot", "SystemDynamics", "TAeZoSysPro", "TAeZoSysPro_testsuite", "ThermalSeparation", "ThermoPower", "ThermoSysPro", "VehicleInterfaces"} loop if not installPackage(stringTypeName(lib), "master") then @@ -38,6 +32,9 @@ for l in { {"IDEAS", ""}, {"IDEAS", "master"}, {"iPSL", ""}, + {"OpenIPSL, "2.0.0"}, + {"OpenIPSL, ""}, + {"OpenIPSL, "master"}, {"PhotoVoltaics", ""}, {"PhotoVoltaics_TGM", ""}, {"PowerSystems","master"}, From 07d96da7a10fcd619953ddf020e0b08212018634 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20=C3=96stlund?= Date: Thu, 23 Jun 2022 21:48:02 +0200 Subject: [PATCH 086/452] Fix missing quotes --- .CI/installLibraries.mos | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.CI/installLibraries.mos b/.CI/installLibraries.mos index 132f099..e636ffe 100644 --- a/.CI/installLibraries.mos +++ b/.CI/installLibraries.mos @@ -32,9 +32,9 @@ for l in { {"IDEAS", ""}, {"IDEAS", "master"}, {"iPSL", ""}, - {"OpenIPSL, "2.0.0"}, - {"OpenIPSL, ""}, - {"OpenIPSL, "master"}, + {"OpenIPSL", "2.0.0"}, + {"OpenIPSL", ""}, + {"OpenIPSL", "master"}, {"PhotoVoltaics", ""}, {"PhotoVoltaics_TGM", ""}, {"PowerSystems","master"}, From 7e2dfb4f01fad7aadfdec33ad03964b0029afa96 Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Wed, 29 Jun 2022 23:35:54 +0200 Subject: [PATCH 087/452] Updated test of last released OpenIPSL version --- configs/conf.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/configs/conf.json b/configs/conf.json index 0a2329a..18e05c2 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -218,7 +218,10 @@ "libraryVersion":"2.0.0" }, { - "library":"OpenIPSL" + "library":"OpenIPSL", + "libraryVersion":"", + "libraryVersionNameForTests":"", + "libraryVersionLatestInPackageManager":true }, { "library":"OpenIPSL", From db37d5d72ba01fc0549f8debde74cfdc63f510ae Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Mon, 11 Jul 2022 14:30:54 +0300 Subject: [PATCH 088/452] add gbode solver (#22) --- .CI/Jenkinsfile | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index f378402..182ad59 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -31,6 +31,7 @@ pipeline { booleanParam(name: 'conversion_script', defaultValue: false, description: 'master branch with conversion script from MSL 3 to 4 (ryzen-5950x-1). This is an experimental job that does not run on a fixed schedule.') booleanParam(name: 'cvode', defaultValue: false, description: 'master branch, with -d=newInst and -s cvode (ryzen-5950x-2). This is an experimental job that does not run on a fixed schedule.') + booleanParam(name: 'gbode', defaultValue: false, description: 'master branch, with -d=newInst and -s gbode (ryzen-5950x-2). This is an experimental job that does not run on a fixed schedule.') } environment { LC_ALL = 'C.UTF-8' @@ -384,6 +385,22 @@ pipeline { test('master', 'cvode', 'setCommandLineOptions("-d=newInst,-frontEndUnitCheck")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '-s cvode', false, false) } } + stage('gbode') { + agent { + node { + label 'ryzen-5950x-2-1' + customWorkspace 'ws/OpenModelicaLibraryTestingWork' + } + } + options { skipDefaultCheckout() } + when { + beforeAgent true + expression { params.gbode } + } + steps { + test('master', 'gbode', 'setCommandLineOptions("-d=newInst,-frontEndUnitCheck")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '-s gbode', false, false) + } + } stage('C++ v1.18') { agent { node { @@ -494,7 +511,7 @@ pipeline { } when { beforeAgent true - expression { params.fmi_v1_12 || params.fmi_v1_13 || params.fmi_v1_14 || params.fmi_v1_16 || params.fmi_v1_17 || params.fmi_master || params.newInst_daeMode || params.oldInst || params.report_ryzen_5950x_2 || params.cvode || params.cpp } + expression { params.fmi_v1_12 || params.fmi_v1_13 || params.fmi_v1_14 || params.fmi_v1_16 || params.fmi_v1_17 || params.fmi_master || params.newInst_daeMode || params.oldInst || params.report_ryzen_5950x_2 || params.cpp || params.cvode || params.gbode} } environment { GITBRANCHES_FMI = 'maintenance/v1.12-fmi maintenance/v1.13-fmi maintenance/v1.14-fmi maintenance/v1.16-fmi maintenance/v1.17-fmi maintenance/v1.18-fmi maintenance/v1.19-fmi master-fmi' @@ -547,6 +564,9 @@ pipeline { sh "./report.py --branches='cvode' configs/conf.json" sh "mv overview.html overview-cvode.html" + + sh "./report.py --branches='gbode' configs/conf.json" + sh "mv overview.html overview-gbode.html" sh "./report.py --branches='${env.GITBRANCHES_CPP}' configs/conf.json" sh "mv overview.html overview-c++.html" From d096a951f94c0e475ec7191297358bf2fb7db2fd Mon Sep 17 00:00:00 2001 From: phannebohm Date: Tue, 12 Jul 2022 14:45:57 +0200 Subject: [PATCH 089/452] Override solver method Fixes gbode tests, I think. --- .CI/Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index 182ad59..41d5095 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -398,7 +398,7 @@ pipeline { expression { params.gbode } } steps { - test('master', 'gbode', 'setCommandLineOptions("-d=newInst,-frontEndUnitCheck")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '-s gbode', false, false) + test('master', 'gbode', 'setCommandLineOptions("-d=newInst,-frontEndUnitCheck")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '-override="solver=gbode"', false, false) } } stage('C++ v1.18') { From 612f4be9ad7010482bee541d135487711c22f5f3 Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Wed, 13 Jul 2022 20:52:35 +0300 Subject: [PATCH 090/452] Some fixes (#24) - change the order of the flags, the one in the model annotation first, then the ones given by the Jenkins job (so they can override the first ones). - revert previous commit to prepare for supporting: https://github.com/OpenModelica/OpenModelica/issues/9228 --- .CI/Jenkinsfile | 2 +- testmodel.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index 41d5095..182ad59 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -398,7 +398,7 @@ pipeline { expression { params.gbode } } steps { - test('master', 'gbode', 'setCommandLineOptions("-d=newInst,-frontEndUnitCheck")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '-override="solver=gbode"', false, false) + test('master', 'gbode', 'setCommandLineOptions("-d=newInst,-frontEndUnitCheck")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '-s gbode', false, false) } } stage('C++ v1.18') { diff --git a/testmodel.py b/testmodel.py index f46a129..656d5c0 100755 --- a/testmodel.py +++ b/testmodel.py @@ -449,7 +449,7 @@ def sendExpressionOldOrNew(cmd): #res = checkOutputTimeout("%s %s >> %s 2>&1" % (conf["fmisimulator"],cmd,simFile), conf["ulimitExe"]) res = checkOutputTimeout("(rm -f %s.pipe ; mkfifo %s.pipe ; head -c 1048576 < %s.pipe >> %s & %s %s > %s.pipe 2>&1)" % (conf["fileName"],conf["fileName"],conf["fileName"],simFile,conf["fmisimulator"],cmd,conf["fileName"]), 1.05*conf["ulimitExe"]) else: - cmd = ("./%s %s %s %s" % (conf["fileName"],conf["simFlags"],annotationSimFlags,emit_protected)).strip() + cmd = ("./%s %s %s %s" % (conf["fileName"],annotationSimFlags,conf["simFlags"],emit_protected)).strip() if conf["simCodeTarget"]=="C": cmd = cmd + " -lv LOG_STATS" with open(simFile,"w") as fp: From 28426c55fc814c29b2f566475e7ad67bfe5b0b95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Mon, 8 Aug 2022 14:54:38 +0200 Subject: [PATCH 091/452] Use login to send email --- .CI/Jenkinsfile | 2 ++ all-reports.py | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index 182ad59..813b56f 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -466,6 +466,7 @@ pipeline { environment { GITBRANCHES = 'maintenance/v1.12 maintenance/v1.13 maintenance/v1.14 maintenance/v1.16 maintenance/v1.17 maintenance/v1.18 maintenance/v1.19 master' PYTHONIOENCODING = 'utf-8' + IDA_EMAIL = credentials('IDA email') } steps { sh 'rm -rf sqlite3.db *.html history' @@ -519,6 +520,7 @@ pipeline { GITBRANCHES_DAE = 'daemode newInst-daemode' GITBRANCHES_CPP = 'v1.18-cpp v1.19-cpp cpp' PYTHONIOENCODING = 'utf-8' + IDA_EMAIL = credentials('IDA email') } steps { sh 'rm -f sqlite3.db *.html' diff --git a/all-reports.py b/all-reports.py index b56bf80..2eabd3b 100755 --- a/all-reports.py +++ b/all-reports.py @@ -261,5 +261,8 @@ def modelLink(libname, modelname, extension, text): """ % "\n".join(reversed(emails_to_send[email]["html"])), subtype='html') - with smtplib.SMTP('test.openmodelica.org') as s: + with smtplib.SMTP('smtp.office365.com') as s: + s.starttls() + s.ehlo() + s.login(os.environ["$IDA_EMAIL_USR"],os.environ["$IDA_EMAIL_PSW"]) s.send_message(msg) From 9ba7d5a251bbf29019d85c468757127d3e848895 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Wed, 10 Aug 2022 16:23:22 +0200 Subject: [PATCH 092/452] Pass the environment variables through docker --- .CI/Jenkinsfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index 813b56f..41faae3 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -467,6 +467,7 @@ pipeline { GITBRANCHES = 'maintenance/v1.12 maintenance/v1.13 maintenance/v1.14 maintenance/v1.16 maintenance/v1.17 maintenance/v1.18 maintenance/v1.19 master' PYTHONIOENCODING = 'utf-8' IDA_EMAIL = credentials('IDA email') + args '-e IDA_EMAIL_USR=$IDA_EMAIL_USR -e IDA_EMAIL_PSW=$IDA_EMAIL_PSW' } steps { sh 'rm -rf sqlite3.db *.html history' @@ -508,6 +509,7 @@ pipeline { label 'linux' dir '.CI/build-dep' customWorkspace 'ws/OpenModelicaLibraryTestingReport' + args '-e IDA_EMAIL_USR=$IDA_EMAIL_USR -e IDA_EMAIL_PSW=$IDA_EMAIL_PSW' } } when { From 0c4c233e4830fa1ea6831b63f8281f3152b48d10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Thu, 11 Aug 2022 09:13:33 +0200 Subject: [PATCH 093/452] Fix location of docker args --- .CI/Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index 41faae3..e6eb459 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -457,6 +457,7 @@ pipeline { label 'linux' dir '.CI/build-dep' customWorkspace 'ws/OpenModelicaLibraryTestingReport' + args '-e IDA_EMAIL_USR=$IDA_EMAIL_USR -e IDA_EMAIL_PSW=$IDA_EMAIL_PSW' } } when { @@ -467,7 +468,6 @@ pipeline { GITBRANCHES = 'maintenance/v1.12 maintenance/v1.13 maintenance/v1.14 maintenance/v1.16 maintenance/v1.17 maintenance/v1.18 maintenance/v1.19 master' PYTHONIOENCODING = 'utf-8' IDA_EMAIL = credentials('IDA email') - args '-e IDA_EMAIL_USR=$IDA_EMAIL_USR -e IDA_EMAIL_PSW=$IDA_EMAIL_PSW' } steps { sh 'rm -rf sqlite3.db *.html history' From d195e64660c96aaa28188f7486c4fa475593419e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Thu, 11 Aug 2022 09:45:40 +0200 Subject: [PATCH 094/452] There is no $ before env.vars in Python --- all-reports.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/all-reports.py b/all-reports.py index 2eabd3b..c20f341 100755 --- a/all-reports.py +++ b/all-reports.py @@ -264,5 +264,5 @@ def modelLink(libname, modelname, extension, text): with smtplib.SMTP('smtp.office365.com') as s: s.starttls() s.ehlo() - s.login(os.environ["$IDA_EMAIL_USR"],os.environ["$IDA_EMAIL_PSW"]) + s.login(os.environ["IDA_EMAIL_USR"],os.environ["IDA_EMAIL_PSW"]) s.send_message(msg) From ddd4e324c6be306fb062862423286dd774d07bf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Mon, 12 Sep 2022 11:28:53 +0200 Subject: [PATCH 095/452] Better Python errors for conversionscript.py -n=1 --- conversionscript.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/conversionscript.py b/conversionscript.py index 662a89d..e572cf6 100755 --- a/conversionscript.py +++ b/conversionscript.py @@ -164,13 +164,16 @@ def convertPackage(p): diffOutputFile = "converted-libraries/.openmodelica/libraries/%s.diff" % libnameOnFile print("Creating %s" % diffOutputFile) with open(diffOutputFile, "wb") as diffOut: - diffOutput = subprocess.call(["diff", "-ur", os.path.dirname(p), "converted-libraries/.openmodelica/libraries/%s" % libnameOnFile], stdout=diffOut) + diffOutput = subprocess.call(["diff", "-ur", "--exclude", "openmodelica.metadata.json", os.path.dirname(p), "converted-libraries/.openmodelica/libraries/%s" % libnameOnFile], stdout=diffOut) del omc return {"errorsInDiff": errorsInDiff, "path": path, "timeForConversion": timeForConversion, "statsByFile": statsByFile, "gcProfStatsBeforeConversion": gcProfStatsBeforeConversion, "gcProfStatsBefore": gcProfStatsBefore, "gcProfStats": gcProfStats} pat = "%s/*/openmodelica.metadata.json" % libdir -with Pool(processes=numThreads) as pool: - res = pool.map(convertPackage, sorted(glob.glob(pat))) +if numThreads==1: + res = [convertPackage(p) for p in sorted(glob.glob(pat))] +else: + with Pool(processes=numThreads) as pool: + res = pool.map(convertPackage, sorted(glob.glob(pat))) for r in res: if r is None: continue From 6f62a2a13dfb420a98462a42173645fd75c7e48d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Mon, 12 Sep 2022 13:36:29 +0200 Subject: [PATCH 096/452] Test AixLib development instead of master --- .CI/installLibraries.mos | 3 ++- configs/conf.json | 5 ++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.CI/installLibraries.mos b/.CI/installLibraries.mos index e636ffe..07a6535 100644 --- a/.CI/installLibraries.mos +++ b/.CI/installLibraries.mos @@ -16,7 +16,7 @@ for v in {"1.6", "3.0.0", "maint.7.0.x", "maint.8.1.x", "master"} loop end if; end for; -for lib in {"AdvancedNoise", "AixLib", "BioChem", "BuildingSystems", "BuildSysPro", "Chemical", "ClaRa_Obsolete", "ClaRa", "ConPNlib", "ElectricalEnergyStorage", "ExternData", "ExternalMemoryLib", "FastBuildings", "FCSys", "HanserModelica", "HelmholtzMedia", "IBPSA", "IdealizedContact", "IndustrialControlSystems", "KeyWordIO", "LibRAS", "MEV", "MessagePack", "ModelicaByExample", "ModelicaTestOverdetermined", "Modelica_Synchronous", "Modelica_DeviceDrivers", "Modelica_LinearSystems2", "Modelica_Noise", "ObjectStab", "OpenHydraulics", "OpenIPSL", "PNlib", "Physiolibrary", "PlanarMechanics", "PowerGrids", "PowerSysPro", "ScalableTestGrids", "ScalableTestSuite", "SolarTherm", "Spot", "SystemDynamics", "TAeZoSysPro", "TAeZoSysPro_testsuite", "ThermalSeparation", "ThermoPower", "ThermoSysPro", "VehicleInterfaces"} loop +for lib in {"AdvancedNoise", "BioChem", "BuildingSystems", "BuildSysPro", "Chemical", "ClaRa_Obsolete", "ClaRa", "ConPNlib", "ElectricalEnergyStorage", "ExternData", "ExternalMemoryLib", "FastBuildings", "FCSys", "HanserModelica", "HelmholtzMedia", "IBPSA", "IdealizedContact", "IndustrialControlSystems", "KeyWordIO", "LibRAS", "MEV", "MessagePack", "ModelicaByExample", "ModelicaTestOverdetermined", "Modelica_Synchronous", "Modelica_DeviceDrivers", "Modelica_LinearSystems2", "Modelica_Noise", "ObjectStab", "OpenHydraulics", "OpenIPSL", "PNlib", "Physiolibrary", "PlanarMechanics", "PowerGrids", "PowerSysPro", "ScalableTestGrids", "ScalableTestSuite", "SolarTherm", "Spot", "SystemDynamics", "TAeZoSysPro", "TAeZoSysPro_testsuite", "ThermalSeparation", "ThermoPower", "ThermoSysPro", "VehicleInterfaces"} loop if not installPackage(stringTypeName(lib), "master") then print(lib + " " + getErrorString() + "\n"); exit(1); @@ -25,6 +25,7 @@ end for; for l in { {"AES", "main"}, + {"AixLib", "development"}, {"Annex60", ""}, {"BLDC", ""}, {"ExtendedPetriNets", ""}, diff --git a/configs/conf.json b/configs/conf.json index 18e05c2..44829df 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -99,9 +99,8 @@ }, { "library":"AixLib", - "libraryVersion":"master", - "libraryVersionNameForTests":"latest", - "forceNewHash":20210701 + "libraryVersion":"development", + "libraryVersionNameForTests":"latest" }, { "library":"IBPSA", From c39d260da074343e828b7c3d40c247b7e175ce4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Mon, 19 Sep 2022 08:46:54 +0200 Subject: [PATCH 097/452] Test the Credibility library --- .CI/installLibraries.mos | 1 + configs/conf.json | 3 +++ 2 files changed, 4 insertions(+) diff --git a/.CI/installLibraries.mos b/.CI/installLibraries.mos index 07a6535..1d2983e 100644 --- a/.CI/installLibraries.mos +++ b/.CI/installLibraries.mos @@ -28,6 +28,7 @@ for l in { {"AixLib", "development"}, {"Annex60", ""}, {"BLDC", ""}, + {"Credibility", ""}, {"ExtendedPetriNets", ""}, {"FluxTubesExtension","main"}, {"IDEAS", ""}, diff --git a/configs/conf.json b/configs/conf.json index 44829df..1caba06 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -153,6 +153,9 @@ "referenceFileNameDelimiter":".", "referenceFiles":"/mnt/ReferenceFiles/ExtraLibs/clara_om.git/ReferenceResults" }, + { + "library":"Credibility" + }, { "library":"ElectricalEnergyStorage" }, From e8597f3e40db14da8971629afdca728f059d9bb6 Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Tue, 8 Nov 2022 14:16:55 +0100 Subject: [PATCH 098/452] add support for running shell commands before testing (#25) - via JSON key runOnceBeforeTesting - runOnceBeforeTesting is an array of arrays of string, each array is another command + parameters - you can use $resourceLocation in the commands if you need the absolute path of your Library/Resource folder. --- configs/conf.json | 3 ++- shared.py | 1 + test.py | 9 ++++++++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/configs/conf.json b/configs/conf.json index 1caba06..bb3efa1 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -123,7 +123,8 @@ "library":"Buildings", "ignoreModelPrefix":"Buildings.Utilities.IO.BCVTB.Examples", "libraryVersion":"master", - "libraryVersionNameForTests":"latest" + "libraryVersionNameForTests":"latest", + "runOnceBeforeTesting":[["$resourceLocation/src/ThermalZones/install.py", "--binaries-for-os-only"]] }, { "library":"BuildingSystems", diff --git a/shared.py b/shared.py index 2e1d059..4eb5b1b 100644 --- a/shared.py +++ b/shared.py @@ -9,6 +9,7 @@ def fixData(data,abortSimulationFlag,alarmFlag,overrideDefaults,defaultCustomCom if key not in data: data[key] = default try: + data["runOnceBeforeTesting"] = (data.get("runOnceBeforeTesting") or []) data["simCodeTarget"] = data.get("simCodeTarget") or "C" data["referenceFileExtension"] = data.get("referenceFileExtension") or "mat" data["referenceFileNameDelimiter"] = data.get("referenceFileNameDelimiter") or "." diff --git a/test.py b/test.py index fe456b5..120e6db 100755 --- a/test.py +++ b/test.py @@ -474,10 +474,17 @@ def hashReferenceFiles(s): if not (omc.sendExpression('setCommandLineOptions("-g=MetaModelica")') or omc.sendExpression('setCommandLineOptions("+g=Modelica")')): print("Failed to set MetaModelica grammar") sys.exit(1) + try: - conf["resourceLocation"]=omc.sendExpression('uriToFilename("modelica://%s/Resources")' % library)[0] + conf["resourceLocation"]=omc.sendExpression('uriToFilename("modelica://%s/Resources")' % library) except: conf["resourceLocation"]="" + + if "runOnceBeforeTesting" in conf: + for cmd in conf["runOnceBeforeTesting"]: + # replace the resource location in the command if present + cmd = [c.replace("$resourceLocation", conf["resourceLocation"]) for c in cmd] + subprocess.check_call(cmd, stderr=subprocess.STDOUT) conf["libraryVersionRevision"]=omc.sendExpression('getVersion(%s)' % library) librarySourceFile=omc.sendExpression('getSourceFile(%s)' % library) From 18fae7e9c67c076eb7873676d5c5835e01add613 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Tue, 8 Nov 2022 15:15:52 +0100 Subject: [PATCH 099/452] Add a stage for experimental generateSymbolicJacobian --- .CI/Jenkinsfile | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index e6eb459..49b5607 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -32,6 +32,7 @@ pipeline { booleanParam(name: 'conversion_script', defaultValue: false, description: 'master branch with conversion script from MSL 3 to 4 (ryzen-5950x-1). This is an experimental job that does not run on a fixed schedule.') booleanParam(name: 'cvode', defaultValue: false, description: 'master branch, with -d=newInst and -s cvode (ryzen-5950x-2). This is an experimental job that does not run on a fixed schedule.') booleanParam(name: 'gbode', defaultValue: false, description: 'master branch, with -d=newInst and -s gbode (ryzen-5950x-2). This is an experimental job that does not run on a fixed schedule.') + booleanParam(name: 'generateSymbolicJacobian', defaultValue: false, description: 'master branch, with --generateSymbolicJacobian. This is an experimental job that does not run on a fixed schedule.') } environment { LC_ALL = 'C.UTF-8' @@ -401,6 +402,22 @@ pipeline { test('master', 'gbode', 'setCommandLineOptions("-d=newInst,-frontEndUnitCheck")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '-s gbode', false, false) } } + stage('generateSymbolicJacobian') { + agent { + node { + label 'ryzen-5950x-2-1' + customWorkspace 'ws/OpenModelicaLibraryTestingWork' + } + } + options { skipDefaultCheckout() } + when { + beforeAgent true + expression { params.generateSymbolicJacobian } + } + steps { + test('master', 'generateSymbolicJacobian', 'setCommandLineOptions("--generateSymbolicJacobian")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) + } + } stage('C++ v1.18') { agent { node { @@ -514,7 +531,7 @@ pipeline { } when { beforeAgent true - expression { params.fmi_v1_12 || params.fmi_v1_13 || params.fmi_v1_14 || params.fmi_v1_16 || params.fmi_v1_17 || params.fmi_master || params.newInst_daeMode || params.oldInst || params.report_ryzen_5950x_2 || params.cpp || params.cvode || params.gbode} + expression { params.fmi_v1_12 || params.fmi_v1_13 || params.fmi_v1_14 || params.fmi_v1_16 || params.fmi_v1_17 || params.fmi_master || params.newInst_daeMode || params.oldInst || params.report_ryzen_5950x_2 || params.cpp || params.cvode || params.gbode || params.generateSymbolicJacobian} } environment { GITBRANCHES_FMI = 'maintenance/v1.12-fmi maintenance/v1.13-fmi maintenance/v1.14-fmi maintenance/v1.16-fmi maintenance/v1.17-fmi maintenance/v1.18-fmi maintenance/v1.19-fmi master-fmi' @@ -572,6 +589,9 @@ pipeline { sh "./report.py --branches='gbode' configs/conf.json" sh "mv overview.html overview-gbode.html" + sh "./report.py --branches='generateSymbolicJacobian' configs/conf.json" + sh "mv overview.html overview-generateSymbolicJacobian.html" + sh "./report.py --branches='${env.GITBRANCHES_CPP}' configs/conf.json" sh "mv overview.html overview-c++.html" From c1918bd5e69bbafe714c9f9f5801f93e69e78d19 Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Tue, 8 Nov 2022 15:21:41 +0100 Subject: [PATCH 100/452] add 1.20 to the testing, will update Jenkins job later --- .CI/Jenkinsfile | 58 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 55 insertions(+), 3 deletions(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index 49b5607..1878d37 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -10,6 +10,7 @@ pipeline { booleanParam(name: 'v1_17', defaultValue: false, description: 'maintenance/v1.17 branch (ryzen-5950x-1)') booleanParam(name: 'v1_18', defaultValue: false, description: 'maintenance/v1.18 branch (ryzen-5950x-1)') booleanParam(name: 'v1_19', defaultValue: false, description: 'maintenance/v1.19 branch (ryzen-5950x-1)') + booleanParam(name: 'v1_20', defaultValue: false, description: 'maintenance/v1.20 branch (ryzen-5950x-1)') booleanParam(name: 'master', defaultValue: false, description: 'master branch (ryzen-5950x-1)') booleanParam(name: 'fmi_v1_12', defaultValue: false, description: 'maintenance/v1.12 branch with FMI (ryzen-5950x-2)') @@ -19,12 +20,14 @@ pipeline { booleanParam(name: 'fmi_v1_17', defaultValue: false, description: 'maintenance/v1.17 branch with FMI (ryzen-5950x-2)') booleanParam(name: 'fmi_v1_18', defaultValue: false, description: 'maintenance/v1.18 branch with FMI (ryzen-5950x-2)') booleanParam(name: 'fmi_v1_19', defaultValue: false, description: 'maintenance/v1.19 branch with FMI (ryzen-5950x-2)') + booleanParam(name: 'fmi_v1_20', defaultValue: false, description: 'maintenance/v1.20 branch with FMI (ryzen-5950x-2)') booleanParam(name: 'fmi_master', defaultValue: false, description: 'master branch with FMI (ryzen-5950x-2)') booleanParam(name: 'newInst_daeMode', defaultValue: false, description: 'master branch, --daeMode with -d=newInst (ryzen-5950x-2)') booleanParam(name: 'newInst_newBackend', defaultValue: false, description: 'master branch, -d=newInst --newBackend, (ryzen-5950x-1)') booleanParam(name: 'oldInst', defaultValue: false, description: 'master branch, with -d=nonewInst (ryzen-5950x-2)') booleanParam(name: 'cpp_v1_18', defaultValue: false, description: 'maintenance/v1.18 branch, with --simCodeTarget=Cpp (ryzen-5950x-2).') booleanParam(name: 'cpp_v1_19', defaultValue: false, description: 'maintenance/v1.19 branch, with --simCodeTarget=Cpp (ryzen-5950x-2).') + booleanParam(name: 'cpp_v1_20', defaultValue: false, description: 'maintenance/v1.20 branch, with --simCodeTarget=Cpp (ryzen-5950x-2).') booleanParam(name: 'cpp', defaultValue: false, description: 'master branch, with --simCodeTarget=Cpp (ryzen-5950x-2).') booleanParam(name: 'report_ryzen_5950x_1', defaultValue: false, description: 'Generate a report for ryzen-5950x-1 without running the tests') booleanParam(name: 'report_ryzen_5950x_2', defaultValue: false, description: 'Generate a report for ryzen-5950x-2 without running the tests') @@ -159,6 +162,23 @@ pipeline { } } + stage('v1.20') { + agent { + node { + label 'ryzen-5950x-1' + customWorkspace 'ws/OpenModelicaLibraryTestingWork' + } + } + options { skipDefaultCheckout() } + when { + beforeAgent true + expression { params.v1_20 } + } + steps { + test('maintenance/v1.20', 'v1.20', '', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', false, false) + } + } + stage('master') { agent { node { @@ -322,6 +342,22 @@ pipeline { test('maintenance/v1.19', 'v1.19-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) } } + stage('v1.20 FMI') { + agent { + node { + label 'ryzen-5950x-2-1' + customWorkspace 'ws/OpenModelicaLibraryTestingWork' + } + } + options { skipDefaultCheckout() } + when { + beforeAgent true + expression { params.fmi_v1_20 } + } + steps { + test('maintenance/v1.20', 'v1.20-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) + } + } stage('master FMI') { agent { node { @@ -450,6 +486,22 @@ pipeline { test('maintenance/v1.19', 'v1.19-cpp', 'setCommandLineOptions("--simCodeTarget=Cpp")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) } } + stage('C++ v1.20') { + agent { + node { + label 'ryzen-5950x-2-1' + customWorkspace 'ws/OpenModelicaLibraryTestingWork' + } + } + options { skipDefaultCheckout() } + when { + beforeAgent true + expression { params.cpp_v1_20 } + } + steps { + test('maintenance/v1.20', 'v1.20-cpp', 'setCommandLineOptions("--simCodeTarget=Cpp")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) + } + } stage('C++') { agent { node { @@ -482,7 +534,7 @@ pipeline { expression { params.v1_12 || params.v1_13 || params.v1_14 || params.v1_16 || params.v1_17 || params.master || params.conversion_script || params.report_ryzen_5950x_1 | params.newInst_newBackend} } environment { - GITBRANCHES = 'maintenance/v1.12 maintenance/v1.13 maintenance/v1.14 maintenance/v1.16 maintenance/v1.17 maintenance/v1.18 maintenance/v1.19 master' + GITBRANCHES = 'maintenance/v1.12 maintenance/v1.13 maintenance/v1.14 maintenance/v1.16 maintenance/v1.17 maintenance/v1.18 maintenance/v1.19 maintenance/v1.20 master' PYTHONIOENCODING = 'utf-8' IDA_EMAIL = credentials('IDA email') } @@ -534,10 +586,10 @@ pipeline { expression { params.fmi_v1_12 || params.fmi_v1_13 || params.fmi_v1_14 || params.fmi_v1_16 || params.fmi_v1_17 || params.fmi_master || params.newInst_daeMode || params.oldInst || params.report_ryzen_5950x_2 || params.cpp || params.cvode || params.gbode || params.generateSymbolicJacobian} } environment { - GITBRANCHES_FMI = 'maintenance/v1.12-fmi maintenance/v1.13-fmi maintenance/v1.14-fmi maintenance/v1.16-fmi maintenance/v1.17-fmi maintenance/v1.18-fmi maintenance/v1.19-fmi master-fmi' + GITBRANCHES_FMI = 'maintenance/v1.12-fmi maintenance/v1.13-fmi maintenance/v1.14-fmi maintenance/v1.16-fmi maintenance/v1.17-fmi maintenance/v1.18-fmi maintenance/v1.19-fmi maintenance/v1.20-fmi master-fmi' GITBRANCHES_NEWINST = 'oldInst' GITBRANCHES_DAE = 'daemode newInst-daemode' - GITBRANCHES_CPP = 'v1.18-cpp v1.19-cpp cpp' + GITBRANCHES_CPP = 'v1.18-cpp v1.19-cpp v1.20-cpp cpp' PYTHONIOENCODING = 'utf-8' IDA_EMAIL = credentials('IDA email') } From 202b88851994a115112364b5d24d555ec299d8bd Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Tue, 8 Nov 2022 15:26:02 +0100 Subject: [PATCH 101/452] remove 1.18 from cpp tests --- .CI/Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index 1878d37..311fdfd 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -589,7 +589,7 @@ pipeline { GITBRANCHES_FMI = 'maintenance/v1.12-fmi maintenance/v1.13-fmi maintenance/v1.14-fmi maintenance/v1.16-fmi maintenance/v1.17-fmi maintenance/v1.18-fmi maintenance/v1.19-fmi maintenance/v1.20-fmi master-fmi' GITBRANCHES_NEWINST = 'oldInst' GITBRANCHES_DAE = 'daemode newInst-daemode' - GITBRANCHES_CPP = 'v1.18-cpp v1.19-cpp v1.20-cpp cpp' + GITBRANCHES_CPP = 'v1.19-cpp v1.20-cpp cpp' PYTHONIOENCODING = 'utf-8' IDA_EMAIL = credentials('IDA email') } From b3a69876ac50f0acb2cbf82632816ad023dba22e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Wed, 9 Nov 2022 12:15:28 +0100 Subject: [PATCH 102/452] Run generateSymbolicJacobian on ryzen-5950x-1 This gives more consistent time measurements. --- .CI/Jenkinsfile | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index 311fdfd..2de1af7 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -35,7 +35,7 @@ pipeline { booleanParam(name: 'conversion_script', defaultValue: false, description: 'master branch with conversion script from MSL 3 to 4 (ryzen-5950x-1). This is an experimental job that does not run on a fixed schedule.') booleanParam(name: 'cvode', defaultValue: false, description: 'master branch, with -d=newInst and -s cvode (ryzen-5950x-2). This is an experimental job that does not run on a fixed schedule.') booleanParam(name: 'gbode', defaultValue: false, description: 'master branch, with -d=newInst and -s gbode (ryzen-5950x-2). This is an experimental job that does not run on a fixed schedule.') - booleanParam(name: 'generateSymbolicJacobian', defaultValue: false, description: 'master branch, with --generateSymbolicJacobian. This is an experimental job that does not run on a fixed schedule.') + booleanParam(name: 'generateSymbolicJacobian', defaultValue: false, description: 'master branch, with --generateSymbolicJacobian (ryzen-5950x-1). This is an experimental job that does not run on a fixed schedule.') } environment { LC_ALL = 'C.UTF-8' @@ -441,7 +441,7 @@ pipeline { stage('generateSymbolicJacobian') { agent { node { - label 'ryzen-5950x-2-1' + label 'ryzen-5950x-1' customWorkspace 'ws/OpenModelicaLibraryTestingWork' } } @@ -451,7 +451,7 @@ pipeline { expression { params.generateSymbolicJacobian } } steps { - test('master', 'generateSymbolicJacobian', 'setCommandLineOptions("--generateSymbolicJacobian")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) + test('master', 'generateSymbolicJacobian', 'setCommandLineOptions("--generateSymbolicJacobian")', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', false, false) } } stage('C++ v1.18') { @@ -531,7 +531,7 @@ pipeline { } when { beforeAgent true - expression { params.v1_12 || params.v1_13 || params.v1_14 || params.v1_16 || params.v1_17 || params.master || params.conversion_script || params.report_ryzen_5950x_1 | params.newInst_newBackend} + expression { params.v1_12 || params.v1_13 || params.v1_14 || params.v1_16 || params.v1_17 || params.master || params.conversion_script || params.report_ryzen_5950x_1 | params.newInst_newBackend || params.generateSymbolicJacobian} } environment { GITBRANCHES = 'maintenance/v1.12 maintenance/v1.13 maintenance/v1.14 maintenance/v1.16 maintenance/v1.17 maintenance/v1.18 maintenance/v1.19 maintenance/v1.20 master' @@ -561,6 +561,10 @@ pipeline { sh "mv overview.html overview-nonstandard-libs.html" sh "./report.py --branches='master conversion' configs/conf.json" sh "mv overview.html overview-special-jobs.html" + + sh "./report.py --branches='generateSymbolicJacobian' configs/conf.json" + sh "mv overview.html overview-generateSymbolicJacobian.html" + sh "./report.py --branches='${env.GITBRANCHES}' configs/conf.json" sh 'date' @@ -583,7 +587,7 @@ pipeline { } when { beforeAgent true - expression { params.fmi_v1_12 || params.fmi_v1_13 || params.fmi_v1_14 || params.fmi_v1_16 || params.fmi_v1_17 || params.fmi_master || params.newInst_daeMode || params.oldInst || params.report_ryzen_5950x_2 || params.cpp || params.cvode || params.gbode || params.generateSymbolicJacobian} + expression { params.fmi_v1_12 || params.fmi_v1_13 || params.fmi_v1_14 || params.fmi_v1_16 || params.fmi_v1_17 || params.fmi_master || params.newInst_daeMode || params.oldInst || params.report_ryzen_5950x_2 || params.cpp || params.cvode || params.gbode} } environment { GITBRANCHES_FMI = 'maintenance/v1.12-fmi maintenance/v1.13-fmi maintenance/v1.14-fmi maintenance/v1.16-fmi maintenance/v1.17-fmi maintenance/v1.18-fmi maintenance/v1.19-fmi maintenance/v1.20-fmi master-fmi' @@ -641,9 +645,6 @@ pipeline { sh "./report.py --branches='gbode' configs/conf.json" sh "mv overview.html overview-gbode.html" - sh "./report.py --branches='generateSymbolicJacobian' configs/conf.json" - sh "mv overview.html overview-generateSymbolicJacobian.html" - sh "./report.py --branches='${env.GITBRANCHES_CPP}' configs/conf.json" sh "mv overview.html overview-c++.html" @@ -666,7 +667,7 @@ pipeline { } when { beforeAgent true - expression { params.v1_12 || params.v1_13 || params.v1_14 || params.v1_16 || params.v1_17 || params.master || params.report_ripper1 } + expression { params.v1_12 || params.v1_13 || params.v1_14 || params.v1_16 || params.v1_17 || params.v1_18 || params.v1_19 || params.v1_20 || params.master || params.report_ripper1 || params.generateSymbolicJacobian } } steps { sh 'cp ~/TEST_LIBS_BACKUP/ripper1-sqlite3.db sqlite3.db' From a05edcbd8752d4c3ca40eeb55442b4b71ac4d3ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Mon, 5 Dec 2022 13:29:56 +0100 Subject: [PATCH 103/452] Test Buildings vs reference results --- configs/conf-old.json | 5 ++++- configs/conf.json | 10 ++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/configs/conf-old.json b/configs/conf-old.json index 3f9e13c..73686f6 100644 --- a/configs/conf-old.json +++ b/configs/conf-old.json @@ -15,7 +15,10 @@ "library":"Buildings", "ignoreModelPrefix":"Buildings.Utilities.IO.BCVTB.Examples", "libraryVersion":"maint.7.0.x", - "libraryVersionLatestInPackageManager":true + "libraryVersionLatestInPackageManager":true, + "referenceFileExtension":"csv", + "referenceFileNameDelimiter":"_", + "referenceFiles":"/mnt/ReferenceFiles/Buildings/csv" }, { "library":"iPSL" diff --git a/configs/conf.json b/configs/conf.json index bb3efa1..63e7ffb 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -117,14 +117,20 @@ "ignoreModelPrefix":"Buildings.Utilities.IO.BCVTB.Examples", "libraryVersionNameForTests":"8", "libraryVersion":"maint.8.1.x", - "libraryVersionLatestInPackageManager":true + "libraryVersionLatestInPackageManager":true, + "referenceFileExtension":"csv", + "referenceFileNameDelimiter":"_", + "referenceFiles":"/mnt/ReferenceFiles/Buildings/csv" }, { "library":"Buildings", "ignoreModelPrefix":"Buildings.Utilities.IO.BCVTB.Examples", "libraryVersion":"master", "libraryVersionNameForTests":"latest", - "runOnceBeforeTesting":[["$resourceLocation/src/ThermalZones/install.py", "--binaries-for-os-only"]] + "runOnceBeforeTesting":[["$resourceLocation/src/ThermalZones/install.py", "--binaries-for-os-only"]], + "referenceFileExtension":"csv", + "referenceFileNameDelimiter":"_", + "referenceFiles":"/mnt/ReferenceFiles/Buildings/csv" }, { "library":"BuildingSystems", From bee73148d6a616af2e10330a45bb80afaab87914 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Fri, 16 Dec 2022 08:34:37 +0100 Subject: [PATCH 104/452] Buildings reference results are only valid for the master branch --- configs/conf-old.json | 5 +---- configs/conf.json | 5 +---- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/configs/conf-old.json b/configs/conf-old.json index 73686f6..3f9e13c 100644 --- a/configs/conf-old.json +++ b/configs/conf-old.json @@ -15,10 +15,7 @@ "library":"Buildings", "ignoreModelPrefix":"Buildings.Utilities.IO.BCVTB.Examples", "libraryVersion":"maint.7.0.x", - "libraryVersionLatestInPackageManager":true, - "referenceFileExtension":"csv", - "referenceFileNameDelimiter":"_", - "referenceFiles":"/mnt/ReferenceFiles/Buildings/csv" + "libraryVersionLatestInPackageManager":true }, { "library":"iPSL" diff --git a/configs/conf.json b/configs/conf.json index 63e7ffb..99820f3 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -117,10 +117,7 @@ "ignoreModelPrefix":"Buildings.Utilities.IO.BCVTB.Examples", "libraryVersionNameForTests":"8", "libraryVersion":"maint.8.1.x", - "libraryVersionLatestInPackageManager":true, - "referenceFileExtension":"csv", - "referenceFileNameDelimiter":"_", - "referenceFiles":"/mnt/ReferenceFiles/Buildings/csv" + "libraryVersionLatestInPackageManager":true }, { "library":"Buildings", From ab8c7f72dc8f18ca18284c7bf985a6519e822b6e Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Mon, 9 Jan 2023 22:55:46 +0100 Subject: [PATCH 105/452] Added Buildings_9 for testing of the 9.1.x branch --- configs/conf.json | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/configs/conf.json b/configs/conf.json index 99820f3..7dba5d6 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -119,6 +119,13 @@ "libraryVersion":"maint.8.1.x", "libraryVersionLatestInPackageManager":true }, + { + "library":"Buildings", + "ignoreModelPrefix":"Buildings.Utilities.IO.BCVTB.Examples", + "libraryVersionNameForTests":"9", + "libraryVersion":"maint.9.1.x", + "libraryVersionLatestInPackageManager":true + }, { "library":"Buildings", "ignoreModelPrefix":"Buildings.Utilities.IO.BCVTB.Examples", From ce9258a126cf4d1a41e0f030f5eba1f8b88313b6 Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Fri, 13 Jan 2023 20:11:15 +0100 Subject: [PATCH 106/452] Added test of latest released AixLib --- configs/conf.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/configs/conf.json b/configs/conf.json index 7dba5d6..0bf5778 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -97,6 +97,9 @@ "libraryVersion":"main", "libraryVersionNameForTests":"" }, + { + "library":"AixLib", + }, { "library":"AixLib", "libraryVersion":"development", From 407d11af8931a251a659f53d3f3b0c6cb13f5565 Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Fri, 13 Jan 2023 20:12:25 +0100 Subject: [PATCH 107/452] Fixed typo --- configs/conf.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/conf.json b/configs/conf.json index 0bf5778..f4e319b 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -98,7 +98,7 @@ "libraryVersionNameForTests":"" }, { - "library":"AixLib", + "library":"AixLib" }, { "library":"AixLib", From e1e0a61247f35e11a700735332ae3456dd48d9f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Wed, 18 Jan 2023 11:36:37 +0100 Subject: [PATCH 108/452] Install Buildings 9.1.x --- .CI/installLibraries.mos | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.CI/installLibraries.mos b/.CI/installLibraries.mos index 1d2983e..2c69ecc 100644 --- a/.CI/installLibraries.mos +++ b/.CI/installLibraries.mos @@ -9,7 +9,7 @@ for v in {"3.2.1","3.2.2","3.2.3","4.0.0","trunk"} loop exit(1); end if; end for; -for v in {"1.6", "3.0.0", "maint.7.0.x", "maint.8.1.x", "master"} loop +for v in {"1.6", "3.0.0", "maint.7.0.x", "maint.8.1.x", "maint.9.1.x", "master"} loop if not installPackage(Buildings, v) then print("Buildings " + v + " " + getErrorString() + "\n"); exit(1); From 5dbbb3a77ea0c64605a32bb465060eaec341b892 Mon Sep 17 00:00:00 2001 From: Mahder Gebremedhin Date: Sun, 22 Jan 2023 22:04:54 +0100 Subject: [PATCH 109/452] Support for running heavy tests one at a time (#27) * Trim whitespace. * Rename function for clarity. - Rename test() to runRegressionTest(). `test` is too generic and difficult to notice. * Rename option to 'j' instead of 'n'. - `-n` is used by OpenModelica itself to control its own number of threads. - Use `-j (--jobs)` for the python script instead to avoid confusion. * Allow specifying the number of jobs for regression testing. - Add a new parameter `jobs` to the `runRegressiontest` function. By default this is set to 0. This will be passed to the `test.py` script which will use it to determine the number of jobs to use for running tests. * If running on test at a time allow omc multithreading. - If tests jobs are done one at a time, i.e. --jobs=1 is set for the python test script, assume that we are allowed to use multiple threads for each test itself. That is allow omc to run single tests with its own multiple threads when needed. - This should ideally be its own flag/option passed to the test script. However, with the current requirements it is an overkill. * Add a new job 'heavy_tests'. - This job will run test one at a time. That is, it will not launch multiple tests at once. However, for each individual test, omc should be allowed to use multiple threads (e.g. to load libraries, generate and compile C code). - The job is intended to be manually started (no schedule for now). - The name of the job is preliminary and can be changed. --- .CI/Jenkinsfile | 101 ++++++++++++++++++++++++++++++------------------ test.py | 25 +++++++++--- 2 files changed, 83 insertions(+), 43 deletions(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index 2de1af7..e389965 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -10,7 +10,7 @@ pipeline { booleanParam(name: 'v1_17', defaultValue: false, description: 'maintenance/v1.17 branch (ryzen-5950x-1)') booleanParam(name: 'v1_18', defaultValue: false, description: 'maintenance/v1.18 branch (ryzen-5950x-1)') booleanParam(name: 'v1_19', defaultValue: false, description: 'maintenance/v1.19 branch (ryzen-5950x-1)') - booleanParam(name: 'v1_20', defaultValue: false, description: 'maintenance/v1.20 branch (ryzen-5950x-1)') + booleanParam(name: 'v1_20', defaultValue: false, description: 'maintenance/v1.20 branch (ryzen-5950x-1)') booleanParam(name: 'master', defaultValue: false, description: 'master branch (ryzen-5950x-1)') booleanParam(name: 'fmi_v1_12', defaultValue: false, description: 'maintenance/v1.12 branch with FMI (ryzen-5950x-2)') @@ -36,6 +36,7 @@ pipeline { booleanParam(name: 'cvode', defaultValue: false, description: 'master branch, with -d=newInst and -s cvode (ryzen-5950x-2). This is an experimental job that does not run on a fixed schedule.') booleanParam(name: 'gbode', defaultValue: false, description: 'master branch, with -d=newInst and -s gbode (ryzen-5950x-2). This is an experimental job that does not run on a fixed schedule.') booleanParam(name: 'generateSymbolicJacobian', defaultValue: false, description: 'master branch, with --generateSymbolicJacobian (ryzen-5950x-1). This is an experimental job that does not run on a fixed schedule.') + booleanParam(name: 'heavy_tests', defaultValue: false, description: 'master branch, runs one test at a time. That is, no parallel launching of tests. omc will use multiple threads for each test (-n=1 is not set unlike the other regression tests.), (ryzen-5950x-2). This is an experimental job that does not run on a fixed schedule.') } environment { LC_ALL = 'C.UTF-8' @@ -56,7 +57,7 @@ pipeline { expression { params.v1_12 } } steps { - test('maintenance/v1.12', 'v1.12', '', '', 'ripper1', 'LibraryTestingRipper1DB', true, '', true, false) + runRegressiontest('maintenance/v1.12', 'v1.12', '', '', 'ripper1', 'LibraryTestingRipper1DB', true, '', true, false) } } @@ -73,7 +74,7 @@ pipeline { expression { params.v1_13 } } steps { - test('maintenance/v1.13', 'v1.13', '', '', 'ripper1', 'LibraryTestingRipper1DB', true, '', true, false) + runRegressiontest('maintenance/v1.13', 'v1.13', '', '', 'ripper1', 'LibraryTestingRipper1DB', true, '', true, false) } } @@ -90,7 +91,7 @@ pipeline { expression { params.v1_14 } } steps { - test('maintenance/v1.14', 'v1.14', '', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', true, false) + runRegressiontest('maintenance/v1.14', 'v1.14', '', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', true, false) } } @@ -107,7 +108,7 @@ pipeline { expression { params.v1_16 } } steps { - test('maintenance/v1.16', 'v1.16', '', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', false, false) + runRegressiontest('maintenance/v1.16', 'v1.16', '', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', false, false) } } @@ -124,7 +125,7 @@ pipeline { expression { params.v1_17 } } steps { - test('maintenance/v1.17', 'v1.17', '', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', false, false) + runRegressiontest('maintenance/v1.17', 'v1.17', '', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', false, false) } } @@ -141,10 +142,10 @@ pipeline { expression { params.v1_18 } } steps { - test('maintenance/v1.18', 'v1.18', '', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', false, false) + runRegressiontest('maintenance/v1.18', 'v1.18', '', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', false, false) } } - + stage('v1.19') { agent { node { @@ -158,7 +159,7 @@ pipeline { expression { params.v1_19 } } steps { - test('maintenance/v1.19', 'v1.19', '', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', false, false) + runRegressiontest('maintenance/v1.19', 'v1.19', '', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', false, false) } } @@ -175,7 +176,7 @@ pipeline { expression { params.v1_20 } } steps { - test('maintenance/v1.20', 'v1.20', '', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', false, false) + runRegressiontest('maintenance/v1.20', 'v1.20', '', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', false, false) } } @@ -192,7 +193,7 @@ pipeline { expression { params.master } } steps { - test('master', 'master', '', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', false, false) + runRegressiontest('master', 'master', '', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', false, false) } } @@ -209,7 +210,7 @@ pipeline { expression { params.conversion_script } } steps { - test('master', 'conversion', '', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', false, true) + runRegressiontest('master', 'conversion', '', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', false, true) } } @@ -226,7 +227,7 @@ pipeline { expression { params.newInst_newBackend } } steps { - test('master', 'newInst-newBackend', 'setCommandLineOptions("-d=newInst,-frontEndUnitCheck --newBackend")', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', false, false) + runRegressiontest('master', 'newInst-newBackend', 'setCommandLineOptions("-d=newInst,-frontEndUnitCheck --newBackend")', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', false, false) } } @@ -243,7 +244,7 @@ pipeline { expression { params.fmi_v1_12 } } steps { - test('maintenance/v1.12', 'v1.12-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', true, '', true, false) + runRegressiontest('maintenance/v1.12', 'v1.12-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', true, '', true, false) } } stage('v1.13 FMI') { @@ -259,7 +260,7 @@ pipeline { expression { params.fmi_v1_13 } } steps { - test('maintenance/v1.13', 'v1.13-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', true, '', true, false) + runRegressiontest('maintenance/v1.13', 'v1.13-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', true, '', true, false) } } stage('v1.14 FMI') { @@ -275,7 +276,7 @@ pipeline { expression { params.fmi_v1_14 } } steps { - test('maintenance/v1.14', 'v1.14-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', false, '', true, false) + runRegressiontest('maintenance/v1.14', 'v1.14-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', false, '', true, false) } } stage('v1.16 FMI') { @@ -291,7 +292,7 @@ pipeline { expression { params.fmi_v1_16 } } steps { - test('maintenance/v1.16', 'v1.16-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) + runRegressiontest('maintenance/v1.16', 'v1.16-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) } } stage('v1.17 FMI') { @@ -307,7 +308,7 @@ pipeline { expression { params.fmi_v1_17 } } steps { - test('maintenance/v1.17', 'v1.17-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) + runRegressiontest('maintenance/v1.17', 'v1.17-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) } } stage('v1.18 FMI') { @@ -323,7 +324,7 @@ pipeline { expression { params.fmi_v1_18 } } steps { - test('maintenance/v1.18', 'v1.18-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) + runRegressiontest('maintenance/v1.18', 'v1.18-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) } } stage('v1.19 FMI') { @@ -339,7 +340,7 @@ pipeline { expression { params.fmi_v1_19 } } steps { - test('maintenance/v1.19', 'v1.19-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) + runRegressiontest('maintenance/v1.19', 'v1.19-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) } } stage('v1.20 FMI') { @@ -355,7 +356,7 @@ pipeline { expression { params.fmi_v1_20 } } steps { - test('maintenance/v1.20', 'v1.20-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) + runRegressiontest('maintenance/v1.20', 'v1.20-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) } } stage('master FMI') { @@ -371,7 +372,7 @@ pipeline { expression { params.fmi_master } } steps { - test('master', 'master-fmi', '', 'origin/master', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) + runRegressiontest('master', 'master-fmi', '', 'origin/master', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) } } stage('newInst-daeMode') { @@ -387,7 +388,7 @@ pipeline { expression { params.newInst_daeMode } } steps { - test('master', 'newInst-daeMode', 'setCommandLineOptions("-d=newInst,-frontEndUnitCheck --daeMode=true")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) + runRegressiontest('master', 'newInst-daeMode', 'setCommandLineOptions("-d=newInst,-frontEndUnitCheck --daeMode=true")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) } } stage('oldInst') { @@ -403,7 +404,7 @@ pipeline { expression { params.oldInst } } steps { - test('master', 'oldInst', 'setCommandLineOptions("-d=nonewInst")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) + runRegressiontest('master', 'oldInst', 'setCommandLineOptions("-d=nonewInst")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) } } stage('cvode') { @@ -419,7 +420,7 @@ pipeline { expression { params.cvode } } steps { - test('master', 'cvode', 'setCommandLineOptions("-d=newInst,-frontEndUnitCheck")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '-s cvode', false, false) + runRegressiontest('master', 'cvode', 'setCommandLineOptions("-d=newInst,-frontEndUnitCheck")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '-s cvode', false, false) } } stage('gbode') { @@ -435,7 +436,7 @@ pipeline { expression { params.gbode } } steps { - test('master', 'gbode', 'setCommandLineOptions("-d=newInst,-frontEndUnitCheck")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '-s gbode', false, false) + runRegressiontest('master', 'gbode', 'setCommandLineOptions("-d=newInst,-frontEndUnitCheck")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '-s gbode', false, false) } } stage('generateSymbolicJacobian') { @@ -451,7 +452,23 @@ pipeline { expression { params.generateSymbolicJacobian } } steps { - test('master', 'generateSymbolicJacobian', 'setCommandLineOptions("--generateSymbolicJacobian")', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', false, false) + runRegressiontest('master', 'generateSymbolicJacobian', 'setCommandLineOptions("--generateSymbolicJacobian")', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', false, false) + } + } + stage('heavy_tests') { + agent { + node { + label 'ryzen-5950x-2-1' + customWorkspace 'ws/OpenModelicaLibraryTestingWork' + } + } + options { skipDefaultCheckout() } + when { + beforeAgent true + expression { params.heavy_tests } + } + steps { + runRegressiontest('master', 'heavy_tests', '', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false, 1) } } stage('C++ v1.18') { @@ -467,7 +484,7 @@ pipeline { expression { params.cpp_v1_18 } } steps { - test('maintenance/v1.18', 'v1.18-cpp', 'setCommandLineOptions("--simCodeTarget=Cpp")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) + runRegressiontest('maintenance/v1.18', 'v1.18-cpp', 'setCommandLineOptions("--simCodeTarget=Cpp")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) } } stage('C++ v1.19') { @@ -483,7 +500,7 @@ pipeline { expression { params.cpp_v1_19 } } steps { - test('maintenance/v1.19', 'v1.19-cpp', 'setCommandLineOptions("--simCodeTarget=Cpp")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) + runRegressiontest('maintenance/v1.19', 'v1.19-cpp', 'setCommandLineOptions("--simCodeTarget=Cpp")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) } } stage('C++ v1.20') { @@ -499,7 +516,7 @@ pipeline { expression { params.cpp_v1_20 } } steps { - test('maintenance/v1.20', 'v1.20-cpp', 'setCommandLineOptions("--simCodeTarget=Cpp")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) + runRegressiontest('maintenance/v1.20', 'v1.20-cpp', 'setCommandLineOptions("--simCodeTarget=Cpp")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) } } stage('C++') { @@ -515,7 +532,7 @@ pipeline { expression { params.cpp } } steps { - test('master', 'cpp', 'setCommandLineOptions("--simCodeTarget=Cpp")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) + runRegressiontest('master', 'cpp', 'setCommandLineOptions("--simCodeTarget=Cpp")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) } } } } @@ -587,7 +604,7 @@ pipeline { } when { beforeAgent true - expression { params.fmi_v1_12 || params.fmi_v1_13 || params.fmi_v1_14 || params.fmi_v1_16 || params.fmi_v1_17 || params.fmi_master || params.newInst_daeMode || params.oldInst || params.report_ryzen_5950x_2 || params.cpp || params.cvode || params.gbode} + expression { params.fmi_v1_12 || params.fmi_v1_13 || params.fmi_v1_14 || params.fmi_v1_16 || params.fmi_v1_17 || params.fmi_master || params.newInst_daeMode || params.oldInst || params.report_ryzen_5950x_2 || params.cpp || params.cvode || params.gbode || params.heavy_tests} } environment { GITBRANCHES_FMI = 'maintenance/v1.12-fmi maintenance/v1.13-fmi maintenance/v1.14-fmi maintenance/v1.16-fmi maintenance/v1.17-fmi maintenance/v1.18-fmi maintenance/v1.19-fmi maintenance/v1.20-fmi master-fmi' @@ -641,10 +658,13 @@ pipeline { sh "./report.py --branches='cvode' configs/conf.json" sh "mv overview.html overview-cvode.html" - + sh "./report.py --branches='gbode' configs/conf.json" sh "mv overview.html overview-gbode.html" + sh "./report.py --branches='heavy_tests' configs/conf.json" + sh "mv overview.html overview-heavy_tests.html" + sh "./report.py --branches='${env.GITBRANCHES_CPP}' configs/conf.json" sh "mv overview.html overview-c++.html" @@ -719,7 +739,14 @@ def installLibraries(boolean removePackageOrder, boolean conversionScript, name, return "${env.HOME}/saved_omc/libraries" } } -def test(branch, name, extraFlags, omsHash, dbPrefix, sshConfig, omcompiler, extrasimflags, boolean removePackageOrder, boolean conversionScript) { + +/** + * Launches the test.py script with the given options. + * + * @param jobs: The number of tests/jobs to launch in parallel. + By default this is set to 0 which means launch as many tests as there are available physical cpus on the machine'. + */ +def runRegressiontest(branch, name, extraFlags, omsHash, dbPrefix, sshConfig, omcompiler, extrasimflags, boolean removePackageOrder, boolean conversionScript, int jobs=0) { sh ''' find /tmp -name "*openmodelica.hudson*" -exec rm {} ";" || true mkdir -p ~/TEST_LIBS_BACKUP @@ -879,9 +906,9 @@ def test(branch, name, extraFlags, omsHash, dbPrefix, sshConfig, omcompiler, ext mkdir -p "/var/www/libraries.openmodelica.org/branches/${name}/" """ - + def libraryPath = installLibraries(removePackageOrder, conversionScript, name, "${WORKSPACE}/OpenModelica/${OMCPATH}/build") - + sh "test -d '${libraryPath}/.openmodelica/libraries/Modelica trunk'" sh """ @@ -906,7 +933,7 @@ def test(branch, name, extraFlags, omsHash, dbPrefix, sshConfig, omcompiler, ext export HOME="${libraryPath}" cd OpenModelicaLibraryTesting # Force /usr/bin/omc as being used for generating the mos-files. Ensures consistent behavior among all tested OMC versions - stdbuf -oL -eL time ./test.py --ompython_omhome=/usr ${FMI_TESTING_FLAG} --extraflags='${extraFlags}' --extrasimflags='${extrasimflags}' --branch="${name}" --output="libraries.openmodelica.org:/var/www/libraries.openmodelica.org/branches/${name}/" --libraries='${libraryPath}/.openmodelica/libraries/' configs/conf.json ${params.OLDLIBS ? "configs/conf-old.json configs/conf-nonstandard.json" : ""} || (killall omc ; false) || exit 1 + stdbuf -oL -eL time ./test.py --ompython_omhome=/usr ${FMI_TESTING_FLAG} --extraflags='${extraFlags}' --extrasimflags='${extrasimflags}' --branch="${name}" --output="libraries.openmodelica.org:/var/www/libraries.openmodelica.org/branches/${name}/" --libraries='${libraryPath}/.openmodelica/libraries/' --jobs=${jobs} configs/conf.json ${params.OLDLIBS ? "configs/conf-old.json configs/conf-nonstandard.json" : ""} || (killall omc ; false) || exit 1 """ sh 'date' sh "rm -f OpenModelicaLibraryTesting/${dbPrefix}-sqlite3.db.tmp" diff --git a/test.py b/test.py index 120e6db..20afb74 100755 --- a/test.py +++ b/test.py @@ -100,13 +100,13 @@ def target(): parser.add_argument('--fmisimulator', default='') parser.add_argument('--ulimitvmem', help="Virtual memory limit (in kB)", type=int, default=8*1024*1024) parser.add_argument('--default', action='append', help="Add a default value for some configuration key, such as --default=ulimitExe=60. The equals sign is mandatory.", default=[]) -parser.add_argument('-n', default=psutil.cpu_count(logical=False)) +parser.add_argument('-j', '--jobs', default=0) args = parser.parse_args() configs = args.configs branch = args.branch result_location = args.output -n_jobs = int(args.n) +n_jobs = int(args.jobs) clean = not args.noclean extraflags = args.extraflags extrasimflags = args.extrasimflags @@ -117,7 +117,22 @@ def target(): docker = args.docker librariespath = args.libraries overrideDefaults = [arg.split("=", 1) for arg in args.default] + + +# If -j=0 is specified (or -j is not specified, defaults to 0) then use all available physical CPUS. +if n_jobs == 0: + n_jobs = psutil.cpu_count(logical=False) + +# If we are running one test at a time assume that omc is allowed to use multiple +# threads for each individual test. +if n_jobs == 1: + single_thread="" # Alternative: single_thread="-n=0" +else: + single_thread="-n=1" + + print("branch: %s, n_jobs: %d" % (branch, n_jobs)) + if clean: print("Removing temporary files, etc to the best ability of the script") @@ -153,7 +168,6 @@ def target(): from OMPython import OMCSession, OMCSessionZMQ version_cmd = "--version" -single_thread="-n=1" # Try to make the processes a bit nicer... os.environ["GC_MARKERS"]="1" @@ -189,7 +203,6 @@ def timeSeconds(f): # Do feature checks. Handle things like old RML-style arguments... subprocess.check_output(omc_cmd + ["-n=1", version_cmd], stderr=subprocess.STDOUT).strip() -single_thread="-n=1" sys.stdout.flush() @@ -474,12 +487,12 @@ def hashReferenceFiles(s): if not (omc.sendExpression('setCommandLineOptions("-g=MetaModelica")') or omc.sendExpression('setCommandLineOptions("+g=Modelica")')): print("Failed to set MetaModelica grammar") sys.exit(1) - + try: conf["resourceLocation"]=omc.sendExpression('uriToFilename("modelica://%s/Resources")' % library) except: conf["resourceLocation"]="" - + if "runOnceBeforeTesting" in conf: for cmd in conf["runOnceBeforeTesting"]: # replace the resource location in the command if present From 47c9ad3786edd7e0133c0fa4a1c7cc2ed1e9165b Mon Sep 17 00:00:00 2001 From: jato-p <78469684+jato-p@users.noreply.github.com> Date: Tue, 24 Jan 2023 09:13:59 +0100 Subject: [PATCH 110/452] Fix link to reference results used twice --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ab738a9..bf65d63 100644 --- a/README.md +++ b/README.md @@ -111,7 +111,7 @@ defining `MSLREFERENCE` and `REFERENCEFILES`. Some result file locations: - Modelica Association: https://github.com/modelica/MAP-LIB_ReferenceResults - PNLib: https://github.com/AMIT-FHBielefeld/PNlib - - DLR-SR: https://github.com/DLR-SR/ThermoFluidStream-Regression.git and https://github.com/DLR-SR/ThermoFluidStream-Regression.git + - DLR-SR: https://github.com/DLR-SR/ThermoFluidStream-Regression.git and https://github.com/DLR-SR/PlanarMechanics_ReferenceResults.git To download the MSL reference files create a file From 132c090fc30709da7ebe35f207c34a7d8ca46f2e Mon Sep 17 00:00:00 2001 From: Mahder Gebremedhin Date: Tue, 24 Jan 2023 15:00:52 +0100 Subject: [PATCH 111/452] Allow selection of config file. - runRegressionTest() now takes one more parameter specifying which config file to use. By default this is set to 'configs/conf.json'. All testing jobs use the default value right now. It will, at least, be changed for the `heavey_tests` job once the appropriate config file is added. --- .CI/Jenkinsfile | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index e389965..f4dcaf9 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -468,7 +468,18 @@ pipeline { expression { params.heavy_tests } } steps { - runRegressiontest('master', 'heavy_tests', '', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false, 1) + runRegressiontest(branch: 'master', + name: 'heavy_tests', + extraFlags: '', + omsHash: '', + dbPrefix: 'ripper2', + sshConfig: 'LibraryTestingRipper2DB', + omcompiler: false, + extrasimflags: '', + removePackageOrder: false, + conversionScript: false, + libs_config_file: 'configs/conf.json', + jobs: 1) } } stage('C++ v1.18') { @@ -746,7 +757,7 @@ def installLibraries(boolean removePackageOrder, boolean conversionScript, name, * @param jobs: The number of tests/jobs to launch in parallel. By default this is set to 0 which means launch as many tests as there are available physical cpus on the machine'. */ -def runRegressiontest(branch, name, extraFlags, omsHash, dbPrefix, sshConfig, omcompiler, extrasimflags, boolean removePackageOrder, boolean conversionScript, int jobs=0) { +def runRegressiontest(branch, name, extraFlags, omsHash, dbPrefix, sshConfig, omcompiler, extrasimflags, boolean removePackageOrder, boolean conversionScript, String libs_config_file = 'configs/conf.json', int jobs=0) { sh ''' find /tmp -name "*openmodelica.hudson*" -exec rm {} ";" || true mkdir -p ~/TEST_LIBS_BACKUP @@ -933,7 +944,7 @@ def runRegressiontest(branch, name, extraFlags, omsHash, dbPrefix, sshConfig, om export HOME="${libraryPath}" cd OpenModelicaLibraryTesting # Force /usr/bin/omc as being used for generating the mos-files. Ensures consistent behavior among all tested OMC versions - stdbuf -oL -eL time ./test.py --ompython_omhome=/usr ${FMI_TESTING_FLAG} --extraflags='${extraFlags}' --extrasimflags='${extrasimflags}' --branch="${name}" --output="libraries.openmodelica.org:/var/www/libraries.openmodelica.org/branches/${name}/" --libraries='${libraryPath}/.openmodelica/libraries/' --jobs=${jobs} configs/conf.json ${params.OLDLIBS ? "configs/conf-old.json configs/conf-nonstandard.json" : ""} || (killall omc ; false) || exit 1 + stdbuf -oL -eL time ./test.py --ompython_omhome=/usr ${FMI_TESTING_FLAG} --extraflags='${extraFlags}' --extrasimflags='${extrasimflags}' --branch="${name}" --output="libraries.openmodelica.org:/var/www/libraries.openmodelica.org/branches/${name}/" --libraries='${libraryPath}/.openmodelica/libraries/' --jobs=${jobs} ${libs_config_file} ${params.OLDLIBS ? "configs/conf-old.json configs/conf-nonstandard.json" : ""} || (killall omc ; false) || exit 1 """ sh 'date' sh "rm -f OpenModelicaLibraryTesting/${dbPrefix}-sqlite3.db.tmp" From b4a388fc9f1e02140b2c58a7bb3ed474047e939c Mon Sep 17 00:00:00 2001 From: Mahder Gebremedhin Date: Tue, 24 Jan 2023 15:00:52 +0100 Subject: [PATCH 112/452] Refactor and reformat. - Just for readability. --- .CI/Jenkinsfile | 402 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 361 insertions(+), 41 deletions(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index f4dcaf9..b4dd1bb 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -57,7 +57,18 @@ pipeline { expression { params.v1_12 } } steps { - runRegressiontest('maintenance/v1.12', 'v1.12', '', '', 'ripper1', 'LibraryTestingRipper1DB', true, '', true, false) + runRegressiontest(branch: 'maintenance/v1.12', + name: 'v1.12', + extraFlags: '', + omsHash: '', + dbPrefix: 'ripper1', + sshConfig: 'LibraryTestingRipper1DB', + omcompiler: true, + extrasimflags: '', + removePackageOrder: true, + conversionScript: false, + libs_config_file: 'configs/conf.json', + jobs: 0) } } @@ -74,7 +85,18 @@ pipeline { expression { params.v1_13 } } steps { - runRegressiontest('maintenance/v1.13', 'v1.13', '', '', 'ripper1', 'LibraryTestingRipper1DB', true, '', true, false) + runRegressiontest(branch: 'maintenance/v1.13', + name: 'v1.13', + extraFlags: '', + omsHash: '', + dbPrefix: 'ripper1', + sshConfig: 'LibraryTestingRipper1DB', + omcompiler: true, + extrasimflags: '', + removePackageOrder: true, + conversionScript: false, + libs_config_file: 'configs/conf.json', + jobs: 0) } } @@ -91,7 +113,18 @@ pipeline { expression { params.v1_14 } } steps { - runRegressiontest('maintenance/v1.14', 'v1.14', '', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', true, false) + runRegressiontest(branch: 'maintenance/v1.14', + name: 'v1.14', + extraFlags: '', + omsHash: '', + dbPrefix: 'ripper1', + sshConfig: 'LibraryTestingRipper1DB', + omcompiler: false, + extrasimflags: '', + removePackageOrder: true, + conversionScript: false, + libs_config_file: 'configs/conf.json', + jobs: 0) } } @@ -108,7 +141,18 @@ pipeline { expression { params.v1_16 } } steps { - runRegressiontest('maintenance/v1.16', 'v1.16', '', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', false, false) + runRegressiontest(branch: 'maintenance/v1.16', + name: 'v1.16', + extraFlags: '', + omsHash: '', + dbPrefix: 'ripper1', + sshConfig: 'LibraryTestingRipper1DB', + omcompiler: false, + extrasimflags: '', + removePackageOrder: false, + conversionScript: false, + libs_config_file: 'configs/conf.json', + jobs: 0) } } @@ -125,7 +169,18 @@ pipeline { expression { params.v1_17 } } steps { - runRegressiontest('maintenance/v1.17', 'v1.17', '', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', false, false) + runRegressiontest(branch: 'maintenance/v1.17', + name: 'v1.17', + extraFlags: '', + omsHash: '', + dbPrefix: 'ripper1', + sshConfig: 'LibraryTestingRipper1DB', + omcompiler: false, + extrasimflags: '', + removePackageOrder: false, + conversionScript: false, + libs_config_file: 'configs/conf.json', + jobs: 0) } } @@ -142,7 +197,18 @@ pipeline { expression { params.v1_18 } } steps { - runRegressiontest('maintenance/v1.18', 'v1.18', '', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', false, false) + runRegressiontest(branch: 'maintenance/v1.18', + name: 'v1.18', + extraFlags: '', + omsHash: '', + dbPrefix: 'ripper1', + sshConfig: 'LibraryTestingRipper1DB', + omcompiler: false, + extrasimflags: '', + removePackageOrder: false, + conversionScript: false, + libs_config_file: 'configs/conf.json', + jobs: 0) } } @@ -159,7 +225,18 @@ pipeline { expression { params.v1_19 } } steps { - runRegressiontest('maintenance/v1.19', 'v1.19', '', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', false, false) + runRegressiontest(branch: 'maintenance/v1.19', + name: 'v1.19', + extraFlags: '', + omsHash: '', + dbPrefix: 'ripper1', + sshConfig: 'LibraryTestingRipper1DB', + omcompiler: false, + extrasimflags: '', + removePackageOrder: false, + conversionScript: false, + libs_config_file: 'configs/conf.json', + jobs: 0) } } @@ -176,7 +253,18 @@ pipeline { expression { params.v1_20 } } steps { - runRegressiontest('maintenance/v1.20', 'v1.20', '', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', false, false) + runRegressiontest(branch: 'maintenance/v1.20', + name: 'v1.20', + extraFlags: '', + omsHash: '', + dbPrefix: 'ripper1', + sshConfig: 'LibraryTestingRipper1DB', + omcompiler: false, + extrasimflags: '', + removePackageOrder: false, + conversionScript: false, + libs_config_file: 'configs/conf.json', + jobs: 0) } } @@ -193,7 +281,18 @@ pipeline { expression { params.master } } steps { - runRegressiontest('master', 'master', '', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', false, false) + runRegressiontest(branch: 'master', + name: 'master', + extraFlags: '', + omsHash: '', + dbPrefix: 'ripper1', + sshConfig: 'LibraryTestingRipper1DB', + omcompiler: false, + extrasimflags: '', + removePackageOrder: false, + conversionScript: false, + libs_config_file: 'configs/conf.json', + jobs: 0) } } @@ -210,7 +309,18 @@ pipeline { expression { params.conversion_script } } steps { - runRegressiontest('master', 'conversion', '', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', false, true) + runRegressiontest(branch: 'master', + name: 'conversion', + extraFlags: '', + omsHash: '', + dbPrefix: 'ripper1', + sshConfig: 'LibraryTestingRipper1DB', + omcompiler: false, + extrasimflags: '', + removePackageOrder: false, + conversionScript: true, + libs_config_file: 'configs/conf.json', + jobs: 0) } } @@ -227,7 +337,18 @@ pipeline { expression { params.newInst_newBackend } } steps { - runRegressiontest('master', 'newInst-newBackend', 'setCommandLineOptions("-d=newInst,-frontEndUnitCheck --newBackend")', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', false, false) + runRegressiontest(branch: 'master', + name: 'newInst-newBackend', + extraFlags: 'setCommandLineOptions("-d=newInst,-frontEndUnitCheck --newBackend")', + omsHash: '', + dbPrefix: 'ripper1', + sshConfig: 'LibraryTestingRipper1DB', + omcompiler: false, + extrasimflags: '', + removePackageOrder: false, + conversionScript: false, + libs_config_file: 'configs/conf.json', + jobs: 0) } } @@ -244,7 +365,18 @@ pipeline { expression { params.fmi_v1_12 } } steps { - runRegressiontest('maintenance/v1.12', 'v1.12-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', true, '', true, false) + runRegressiontest(branch: 'maintenance/v1.12', + name: 'v1.12-fmi', + extraFlags: '', + omsHash: omsimulatorHash(), + dbPrefix: 'ripper2', + sshConfig: 'LibraryTestingRipper2DB', + omcompiler: true, + extrasimflags: '', + removePackageOrder: true, + conversionScript: false, + libs_config_file: 'configs/conf.json', + jobs: 0) } } stage('v1.13 FMI') { @@ -260,7 +392,18 @@ pipeline { expression { params.fmi_v1_13 } } steps { - runRegressiontest('maintenance/v1.13', 'v1.13-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', true, '', true, false) + runRegressiontest(branch: 'maintenance/v1.13', + name: 'v1.13-fmi', + extraFlags: '', + omsHash: omsimulatorHash(), + dbPrefix: 'ripper2', + sshConfig: 'LibraryTestingRipper2DB', + omcompiler: true, + extrasimflags: '', + removePackageOrder: true, + conversionScript: false, + libs_config_file: 'configs/conf.json', + jobs: 0) } } stage('v1.14 FMI') { @@ -276,7 +419,18 @@ pipeline { expression { params.fmi_v1_14 } } steps { - runRegressiontest('maintenance/v1.14', 'v1.14-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', false, '', true, false) + runRegressiontest(branch: 'maintenance/v1.14', + name: 'v1.14-fmi', + extraFlags: '', + omsHash: omsimulatorHash(), + dbPrefix: 'ripper2', + sshConfig: 'LibraryTestingRipper2DB', + omcompiler: false, + extrasimflags: '', + removePackageOrder: true, + conversionScript: false, + libs_config_file: 'configs/conf.json', + jobs: 0) } } stage('v1.16 FMI') { @@ -292,7 +446,18 @@ pipeline { expression { params.fmi_v1_16 } } steps { - runRegressiontest('maintenance/v1.16', 'v1.16-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) + runRegressiontest(branch: 'maintenance/v1.16', + name: 'v1.16-fmi', + extraFlags: '', + omsHash: omsimulatorHash(), + dbPrefix: 'ripper2', + sshConfig: 'LibraryTestingRipper2DB', + omcompiler: false, + extrasimflags: '', + removePackageOrder: false, + conversionScript: false, + libs_config_file: 'configs/conf.json', + jobs: 0) } } stage('v1.17 FMI') { @@ -308,7 +473,18 @@ pipeline { expression { params.fmi_v1_17 } } steps { - runRegressiontest('maintenance/v1.17', 'v1.17-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) + runRegressiontest(branch: 'maintenance/v1.17', + name: 'v1.17-fmi', + extraFlags: '', + omsHash: omsimulatorHash(), + dbPrefix: 'ripper2', + sshConfig: 'LibraryTestingRipper2DB', + omcompiler: false, + extrasimflags: '', + removePackageOrder: false, + conversionScript: false, + libs_config_file: 'configs/conf.json', + jobs: 0) } } stage('v1.18 FMI') { @@ -324,7 +500,18 @@ pipeline { expression { params.fmi_v1_18 } } steps { - runRegressiontest('maintenance/v1.18', 'v1.18-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) + runRegressiontest(branch: 'maintenance/v1.18', + name: 'v1.18-fmi', + extraFlags: '', + omsHash: omsimulatorHash(), + dbPrefix: 'ripper2', + sshConfig: 'LibraryTestingRipper2DB', + omcompiler: false, + extrasimflags: '', + removePackageOrder: false, + conversionScript: false, + libs_config_file: 'configs/conf.json', + jobs: 0) } } stage('v1.19 FMI') { @@ -340,7 +527,18 @@ pipeline { expression { params.fmi_v1_19 } } steps { - runRegressiontest('maintenance/v1.19', 'v1.19-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) + runRegressiontest(branch: 'maintenance/v1.19', + name: 'v1.19-fmi', + extraFlags: '', + omsHash: omsimulatorHash(), + dbPrefix: 'ripper2', + sshConfig: 'LibraryTestingRipper2DB', + omcompiler: false, + extrasimflags: '', + removePackageOrder: false, + conversionScript: false, + libs_config_file: 'configs/conf.json', + jobs: 0) } } stage('v1.20 FMI') { @@ -356,7 +554,18 @@ pipeline { expression { params.fmi_v1_20 } } steps { - runRegressiontest('maintenance/v1.20', 'v1.20-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) + runRegressiontest(branch: 'maintenance/v1.20', + name: 'v1.20-fmi', + extraFlags: '', + omsHash: omsimulatorHash(), + dbPrefix: 'ripper2', + sshConfig: 'LibraryTestingRipper2DB', + omcompiler: false, + extrasimflags: '', + removePackageOrder: false, + conversionScript: false, + libs_config_file: 'configs/conf.json', + jobs: 0) } } stage('master FMI') { @@ -372,7 +581,18 @@ pipeline { expression { params.fmi_master } } steps { - runRegressiontest('master', 'master-fmi', '', 'origin/master', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) + runRegressiontest(branch: 'master', + name: 'master-fmi', + extraFlags: '', + omsHash: 'origin/master', + dbPrefix: 'ripper2', + sshConfig: 'LibraryTestingRipper2DB', + omcompiler: false, + extrasimflags: '', + removePackageOrder: false, + conversionScript: false, + libs_config_file: 'configs/conf.json', + jobs: 0) } } stage('newInst-daeMode') { @@ -388,7 +608,18 @@ pipeline { expression { params.newInst_daeMode } } steps { - runRegressiontest('master', 'newInst-daeMode', 'setCommandLineOptions("-d=newInst,-frontEndUnitCheck --daeMode=true")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) + runRegressiontest(branch: 'master', + name: 'newInst-daeMode', + extraFlags: 'setCommandLineOptions("-d=newInst,-frontEndUnitCheck --daeMode=true")', + omsHash: '', + dbPrefix: 'ripper2', + sshConfig: 'LibraryTestingRipper2DB', + omcompiler: false, + extrasimflags: '', + removePackageOrder: false, + conversionScript: false, + libs_config_file: 'configs/conf.json', + jobs: 0) } } stage('oldInst') { @@ -404,7 +635,18 @@ pipeline { expression { params.oldInst } } steps { - runRegressiontest('master', 'oldInst', 'setCommandLineOptions("-d=nonewInst")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) + runRegressiontest(branch: 'master', + name: 'oldInst', + extraFlags: 'setCommandLineOptions("-d=nonewInst")', + omsHash: '', + dbPrefix: 'ripper2', + sshConfig: 'LibraryTestingRipper2DB', + omcompiler: false, + extrasimflags: '', + removePackageOrder: false, + conversionScript: false, + libs_config_file: 'configs/conf.json', + jobs: 0) } } stage('cvode') { @@ -420,7 +662,18 @@ pipeline { expression { params.cvode } } steps { - runRegressiontest('master', 'cvode', 'setCommandLineOptions("-d=newInst,-frontEndUnitCheck")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '-s cvode', false, false) + runRegressiontest(branch: 'master', + name: 'cvode', + extraFlags: 'setCommandLineOptions("-d=newInst,-frontEndUnitCheck")', + omsHash: '', + dbPrefix: 'ripper2', + sshConfig: 'LibraryTestingRipper2DB', + omcompiler: false, + extrasimflags: '-s cvode', + removePackageOrder: false, + conversionScript: false, + libs_config_file: 'configs/conf.json', + jobs: 0) } } stage('gbode') { @@ -436,7 +689,18 @@ pipeline { expression { params.gbode } } steps { - runRegressiontest('master', 'gbode', 'setCommandLineOptions("-d=newInst,-frontEndUnitCheck")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '-s gbode', false, false) + runRegressiontest(branch: 'master', + name: 'gbode', + extraFlags: 'setCommandLineOptions("-d=newInst,-frontEndUnitCheck")', + omsHash: '', + dbPrefix: 'ripper2', + sshConfig: 'LibraryTestingRipper2DB', + omcompiler: false, + extrasimflags: '-s gbode', + removePackageOrder: false, + conversionScript: false, + libs_config_file: 'configs/conf.json', + jobs: 0) } } stage('generateSymbolicJacobian') { @@ -452,7 +716,18 @@ pipeline { expression { params.generateSymbolicJacobian } } steps { - runRegressiontest('master', 'generateSymbolicJacobian', 'setCommandLineOptions("--generateSymbolicJacobian")', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', false, false) + runRegressiontest(branch: 'master', + name: 'generateSymbolicJacobian', + extraFlags: 'setCommandLineOptions("--generateSymbolicJacobian")', + omsHash: '', + dbPrefix: 'ripper1', + sshConfig: 'LibraryTestingRipper1DB', + omcompiler: false, + extrasimflags: '', + removePackageOrder: false, + conversionScript: false, + libs_config_file: 'configs/conf.json', + jobs: 0) } } stage('heavy_tests') { @@ -468,18 +743,18 @@ pipeline { expression { params.heavy_tests } } steps { - runRegressiontest(branch: 'master', - name: 'heavy_tests', - extraFlags: '', - omsHash: '', - dbPrefix: 'ripper2', - sshConfig: 'LibraryTestingRipper2DB', - omcompiler: false, - extrasimflags: '', - removePackageOrder: false, - conversionScript: false, - libs_config_file: 'configs/conf.json', - jobs: 1) + runRegressiontest(branch: 'master', + name: 'heavy_tests', + extraFlags: '', + omsHash: '', + dbPrefix: 'ripper2', + sshConfig: 'LibraryTestingRipper2DB', + omcompiler: false, + extrasimflags: '', + removePackageOrder: false, + conversionScript: false, + libs_config_file: 'configs/conf.json', + jobs: 1) } } stage('C++ v1.18') { @@ -495,7 +770,18 @@ pipeline { expression { params.cpp_v1_18 } } steps { - runRegressiontest('maintenance/v1.18', 'v1.18-cpp', 'setCommandLineOptions("--simCodeTarget=Cpp")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) + runRegressiontest(branch: 'maintenance/v1.18', + name: 'v1.18-cpp', + extraFlags: 'setCommandLineOptions("--simCodeTarget=Cpp")', + omsHash: '', + dbPrefix: 'ripper2', + sshConfig: 'LibraryTestingRipper2DB', + omcompiler: false, + extrasimflags: '', + removePackageOrder: false, + conversionScript: false, + libs_config_file: 'configs/conf.json', + jobs: 0) } } stage('C++ v1.19') { @@ -511,7 +797,18 @@ pipeline { expression { params.cpp_v1_19 } } steps { - runRegressiontest('maintenance/v1.19', 'v1.19-cpp', 'setCommandLineOptions("--simCodeTarget=Cpp")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) + runRegressiontest(branch: 'maintenance/v1.19', + name: 'v1.19-cpp', + extraFlags: 'setCommandLineOptions("--simCodeTarget=Cpp")', + omsHash: '', + dbPrefix: 'ripper2', + sshConfig: 'LibraryTestingRipper2DB', + omcompiler: false, + extrasimflags: '', + removePackageOrder: false, + conversionScript: false, + libs_config_file: 'configs/conf.json', + jobs: 0) } } stage('C++ v1.20') { @@ -527,7 +824,18 @@ pipeline { expression { params.cpp_v1_20 } } steps { - runRegressiontest('maintenance/v1.20', 'v1.20-cpp', 'setCommandLineOptions("--simCodeTarget=Cpp")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) + runRegressiontest(branch: 'maintenance/v1.20', + name: 'v1.20-cpp', + extraFlags: 'setCommandLineOptions("--simCodeTarget=Cpp")', + omsHash: '', + dbPrefix: 'ripper2', + sshConfig: 'LibraryTestingRipper2DB', + omcompiler: false, + extrasimflags: '', + removePackageOrder: false, + conversionScript: false, + libs_config_file: 'configs/conf.json', + jobs: 0) } } stage('C++') { @@ -543,7 +851,18 @@ pipeline { expression { params.cpp } } steps { - runRegressiontest('master', 'cpp', 'setCommandLineOptions("--simCodeTarget=Cpp")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) + runRegressiontest(branch: 'master', + name: 'cpp', + extraFlags: 'setCommandLineOptions("--simCodeTarget=Cpp")', + omsHash: '', + dbPrefix: 'ripper2', + sshConfig: 'LibraryTestingRipper2DB', + omcompiler: false, + extrasimflags: '', + removePackageOrder: false, + conversionScript: false, + libs_config_file: 'configs/conf.json', + jobs: 0) } } } } @@ -754,6 +1073,7 @@ def installLibraries(boolean removePackageOrder, boolean conversionScript, name, /** * Launches the test.py script with the given options. * + * @param libs_config_file: The config file to be used for testing. This file specifies which libraries to test and what options to use for them. * @param jobs: The number of tests/jobs to launch in parallel. By default this is set to 0 which means launch as many tests as there are available physical cpus on the machine'. */ From de54fce2869bd40257d359eec030e11bcde4fa00 Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Tue, 24 Jan 2023 18:57:28 +0100 Subject: [PATCH 113/452] Updated location of Buildings reference files --- configs/conf.json | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/configs/conf.json b/configs/conf.json index f4e319b..2fb901d 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -127,7 +127,10 @@ "ignoreModelPrefix":"Buildings.Utilities.IO.BCVTB.Examples", "libraryVersionNameForTests":"9", "libraryVersion":"maint.9.1.x", - "libraryVersionLatestInPackageManager":true + "libraryVersionLatestInPackageManager":true, + "referenceFileExtension":"csv", + "referenceFileNameDelimiter":"_", + "referenceFiles":"/mnt/ReferenceFiles/Buildings/csv/maint_9.1.x" }, { "library":"Buildings", @@ -137,7 +140,7 @@ "runOnceBeforeTesting":[["$resourceLocation/src/ThermalZones/install.py", "--binaries-for-os-only"]], "referenceFileExtension":"csv", "referenceFileNameDelimiter":"_", - "referenceFiles":"/mnt/ReferenceFiles/Buildings/csv" + "referenceFiles":"/mnt/ReferenceFiles/Buildings/csv/master" }, { "library":"BuildingSystems", From 06485722a73f69f8af1275d0930e5c7a7cf2c007 Mon Sep 17 00:00:00 2001 From: Mahder Gebremedhin Date: Wed, 25 Jan 2023 12:31:46 +0100 Subject: [PATCH 114/452] Revert "Refactor and reformat." - This reverts commit b4a388fc9f1e02140b2c58a7bb3ed474047e939c. - There is some syntax error and it is not clear what it is. Let's try this step by step. --- .CI/Jenkinsfile | 402 +++++------------------------------------------- 1 file changed, 41 insertions(+), 361 deletions(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index b4dd1bb..f4dcaf9 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -57,18 +57,7 @@ pipeline { expression { params.v1_12 } } steps { - runRegressiontest(branch: 'maintenance/v1.12', - name: 'v1.12', - extraFlags: '', - omsHash: '', - dbPrefix: 'ripper1', - sshConfig: 'LibraryTestingRipper1DB', - omcompiler: true, - extrasimflags: '', - removePackageOrder: true, - conversionScript: false, - libs_config_file: 'configs/conf.json', - jobs: 0) + runRegressiontest('maintenance/v1.12', 'v1.12', '', '', 'ripper1', 'LibraryTestingRipper1DB', true, '', true, false) } } @@ -85,18 +74,7 @@ pipeline { expression { params.v1_13 } } steps { - runRegressiontest(branch: 'maintenance/v1.13', - name: 'v1.13', - extraFlags: '', - omsHash: '', - dbPrefix: 'ripper1', - sshConfig: 'LibraryTestingRipper1DB', - omcompiler: true, - extrasimflags: '', - removePackageOrder: true, - conversionScript: false, - libs_config_file: 'configs/conf.json', - jobs: 0) + runRegressiontest('maintenance/v1.13', 'v1.13', '', '', 'ripper1', 'LibraryTestingRipper1DB', true, '', true, false) } } @@ -113,18 +91,7 @@ pipeline { expression { params.v1_14 } } steps { - runRegressiontest(branch: 'maintenance/v1.14', - name: 'v1.14', - extraFlags: '', - omsHash: '', - dbPrefix: 'ripper1', - sshConfig: 'LibraryTestingRipper1DB', - omcompiler: false, - extrasimflags: '', - removePackageOrder: true, - conversionScript: false, - libs_config_file: 'configs/conf.json', - jobs: 0) + runRegressiontest('maintenance/v1.14', 'v1.14', '', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', true, false) } } @@ -141,18 +108,7 @@ pipeline { expression { params.v1_16 } } steps { - runRegressiontest(branch: 'maintenance/v1.16', - name: 'v1.16', - extraFlags: '', - omsHash: '', - dbPrefix: 'ripper1', - sshConfig: 'LibraryTestingRipper1DB', - omcompiler: false, - extrasimflags: '', - removePackageOrder: false, - conversionScript: false, - libs_config_file: 'configs/conf.json', - jobs: 0) + runRegressiontest('maintenance/v1.16', 'v1.16', '', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', false, false) } } @@ -169,18 +125,7 @@ pipeline { expression { params.v1_17 } } steps { - runRegressiontest(branch: 'maintenance/v1.17', - name: 'v1.17', - extraFlags: '', - omsHash: '', - dbPrefix: 'ripper1', - sshConfig: 'LibraryTestingRipper1DB', - omcompiler: false, - extrasimflags: '', - removePackageOrder: false, - conversionScript: false, - libs_config_file: 'configs/conf.json', - jobs: 0) + runRegressiontest('maintenance/v1.17', 'v1.17', '', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', false, false) } } @@ -197,18 +142,7 @@ pipeline { expression { params.v1_18 } } steps { - runRegressiontest(branch: 'maintenance/v1.18', - name: 'v1.18', - extraFlags: '', - omsHash: '', - dbPrefix: 'ripper1', - sshConfig: 'LibraryTestingRipper1DB', - omcompiler: false, - extrasimflags: '', - removePackageOrder: false, - conversionScript: false, - libs_config_file: 'configs/conf.json', - jobs: 0) + runRegressiontest('maintenance/v1.18', 'v1.18', '', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', false, false) } } @@ -225,18 +159,7 @@ pipeline { expression { params.v1_19 } } steps { - runRegressiontest(branch: 'maintenance/v1.19', - name: 'v1.19', - extraFlags: '', - omsHash: '', - dbPrefix: 'ripper1', - sshConfig: 'LibraryTestingRipper1DB', - omcompiler: false, - extrasimflags: '', - removePackageOrder: false, - conversionScript: false, - libs_config_file: 'configs/conf.json', - jobs: 0) + runRegressiontest('maintenance/v1.19', 'v1.19', '', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', false, false) } } @@ -253,18 +176,7 @@ pipeline { expression { params.v1_20 } } steps { - runRegressiontest(branch: 'maintenance/v1.20', - name: 'v1.20', - extraFlags: '', - omsHash: '', - dbPrefix: 'ripper1', - sshConfig: 'LibraryTestingRipper1DB', - omcompiler: false, - extrasimflags: '', - removePackageOrder: false, - conversionScript: false, - libs_config_file: 'configs/conf.json', - jobs: 0) + runRegressiontest('maintenance/v1.20', 'v1.20', '', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', false, false) } } @@ -281,18 +193,7 @@ pipeline { expression { params.master } } steps { - runRegressiontest(branch: 'master', - name: 'master', - extraFlags: '', - omsHash: '', - dbPrefix: 'ripper1', - sshConfig: 'LibraryTestingRipper1DB', - omcompiler: false, - extrasimflags: '', - removePackageOrder: false, - conversionScript: false, - libs_config_file: 'configs/conf.json', - jobs: 0) + runRegressiontest('master', 'master', '', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', false, false) } } @@ -309,18 +210,7 @@ pipeline { expression { params.conversion_script } } steps { - runRegressiontest(branch: 'master', - name: 'conversion', - extraFlags: '', - omsHash: '', - dbPrefix: 'ripper1', - sshConfig: 'LibraryTestingRipper1DB', - omcompiler: false, - extrasimflags: '', - removePackageOrder: false, - conversionScript: true, - libs_config_file: 'configs/conf.json', - jobs: 0) + runRegressiontest('master', 'conversion', '', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', false, true) } } @@ -337,18 +227,7 @@ pipeline { expression { params.newInst_newBackend } } steps { - runRegressiontest(branch: 'master', - name: 'newInst-newBackend', - extraFlags: 'setCommandLineOptions("-d=newInst,-frontEndUnitCheck --newBackend")', - omsHash: '', - dbPrefix: 'ripper1', - sshConfig: 'LibraryTestingRipper1DB', - omcompiler: false, - extrasimflags: '', - removePackageOrder: false, - conversionScript: false, - libs_config_file: 'configs/conf.json', - jobs: 0) + runRegressiontest('master', 'newInst-newBackend', 'setCommandLineOptions("-d=newInst,-frontEndUnitCheck --newBackend")', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', false, false) } } @@ -365,18 +244,7 @@ pipeline { expression { params.fmi_v1_12 } } steps { - runRegressiontest(branch: 'maintenance/v1.12', - name: 'v1.12-fmi', - extraFlags: '', - omsHash: omsimulatorHash(), - dbPrefix: 'ripper2', - sshConfig: 'LibraryTestingRipper2DB', - omcompiler: true, - extrasimflags: '', - removePackageOrder: true, - conversionScript: false, - libs_config_file: 'configs/conf.json', - jobs: 0) + runRegressiontest('maintenance/v1.12', 'v1.12-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', true, '', true, false) } } stage('v1.13 FMI') { @@ -392,18 +260,7 @@ pipeline { expression { params.fmi_v1_13 } } steps { - runRegressiontest(branch: 'maintenance/v1.13', - name: 'v1.13-fmi', - extraFlags: '', - omsHash: omsimulatorHash(), - dbPrefix: 'ripper2', - sshConfig: 'LibraryTestingRipper2DB', - omcompiler: true, - extrasimflags: '', - removePackageOrder: true, - conversionScript: false, - libs_config_file: 'configs/conf.json', - jobs: 0) + runRegressiontest('maintenance/v1.13', 'v1.13-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', true, '', true, false) } } stage('v1.14 FMI') { @@ -419,18 +276,7 @@ pipeline { expression { params.fmi_v1_14 } } steps { - runRegressiontest(branch: 'maintenance/v1.14', - name: 'v1.14-fmi', - extraFlags: '', - omsHash: omsimulatorHash(), - dbPrefix: 'ripper2', - sshConfig: 'LibraryTestingRipper2DB', - omcompiler: false, - extrasimflags: '', - removePackageOrder: true, - conversionScript: false, - libs_config_file: 'configs/conf.json', - jobs: 0) + runRegressiontest('maintenance/v1.14', 'v1.14-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', false, '', true, false) } } stage('v1.16 FMI') { @@ -446,18 +292,7 @@ pipeline { expression { params.fmi_v1_16 } } steps { - runRegressiontest(branch: 'maintenance/v1.16', - name: 'v1.16-fmi', - extraFlags: '', - omsHash: omsimulatorHash(), - dbPrefix: 'ripper2', - sshConfig: 'LibraryTestingRipper2DB', - omcompiler: false, - extrasimflags: '', - removePackageOrder: false, - conversionScript: false, - libs_config_file: 'configs/conf.json', - jobs: 0) + runRegressiontest('maintenance/v1.16', 'v1.16-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) } } stage('v1.17 FMI') { @@ -473,18 +308,7 @@ pipeline { expression { params.fmi_v1_17 } } steps { - runRegressiontest(branch: 'maintenance/v1.17', - name: 'v1.17-fmi', - extraFlags: '', - omsHash: omsimulatorHash(), - dbPrefix: 'ripper2', - sshConfig: 'LibraryTestingRipper2DB', - omcompiler: false, - extrasimflags: '', - removePackageOrder: false, - conversionScript: false, - libs_config_file: 'configs/conf.json', - jobs: 0) + runRegressiontest('maintenance/v1.17', 'v1.17-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) } } stage('v1.18 FMI') { @@ -500,18 +324,7 @@ pipeline { expression { params.fmi_v1_18 } } steps { - runRegressiontest(branch: 'maintenance/v1.18', - name: 'v1.18-fmi', - extraFlags: '', - omsHash: omsimulatorHash(), - dbPrefix: 'ripper2', - sshConfig: 'LibraryTestingRipper2DB', - omcompiler: false, - extrasimflags: '', - removePackageOrder: false, - conversionScript: false, - libs_config_file: 'configs/conf.json', - jobs: 0) + runRegressiontest('maintenance/v1.18', 'v1.18-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) } } stage('v1.19 FMI') { @@ -527,18 +340,7 @@ pipeline { expression { params.fmi_v1_19 } } steps { - runRegressiontest(branch: 'maintenance/v1.19', - name: 'v1.19-fmi', - extraFlags: '', - omsHash: omsimulatorHash(), - dbPrefix: 'ripper2', - sshConfig: 'LibraryTestingRipper2DB', - omcompiler: false, - extrasimflags: '', - removePackageOrder: false, - conversionScript: false, - libs_config_file: 'configs/conf.json', - jobs: 0) + runRegressiontest('maintenance/v1.19', 'v1.19-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) } } stage('v1.20 FMI') { @@ -554,18 +356,7 @@ pipeline { expression { params.fmi_v1_20 } } steps { - runRegressiontest(branch: 'maintenance/v1.20', - name: 'v1.20-fmi', - extraFlags: '', - omsHash: omsimulatorHash(), - dbPrefix: 'ripper2', - sshConfig: 'LibraryTestingRipper2DB', - omcompiler: false, - extrasimflags: '', - removePackageOrder: false, - conversionScript: false, - libs_config_file: 'configs/conf.json', - jobs: 0) + runRegressiontest('maintenance/v1.20', 'v1.20-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) } } stage('master FMI') { @@ -581,18 +372,7 @@ pipeline { expression { params.fmi_master } } steps { - runRegressiontest(branch: 'master', - name: 'master-fmi', - extraFlags: '', - omsHash: 'origin/master', - dbPrefix: 'ripper2', - sshConfig: 'LibraryTestingRipper2DB', - omcompiler: false, - extrasimflags: '', - removePackageOrder: false, - conversionScript: false, - libs_config_file: 'configs/conf.json', - jobs: 0) + runRegressiontest('master', 'master-fmi', '', 'origin/master', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) } } stage('newInst-daeMode') { @@ -608,18 +388,7 @@ pipeline { expression { params.newInst_daeMode } } steps { - runRegressiontest(branch: 'master', - name: 'newInst-daeMode', - extraFlags: 'setCommandLineOptions("-d=newInst,-frontEndUnitCheck --daeMode=true")', - omsHash: '', - dbPrefix: 'ripper2', - sshConfig: 'LibraryTestingRipper2DB', - omcompiler: false, - extrasimflags: '', - removePackageOrder: false, - conversionScript: false, - libs_config_file: 'configs/conf.json', - jobs: 0) + runRegressiontest('master', 'newInst-daeMode', 'setCommandLineOptions("-d=newInst,-frontEndUnitCheck --daeMode=true")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) } } stage('oldInst') { @@ -635,18 +404,7 @@ pipeline { expression { params.oldInst } } steps { - runRegressiontest(branch: 'master', - name: 'oldInst', - extraFlags: 'setCommandLineOptions("-d=nonewInst")', - omsHash: '', - dbPrefix: 'ripper2', - sshConfig: 'LibraryTestingRipper2DB', - omcompiler: false, - extrasimflags: '', - removePackageOrder: false, - conversionScript: false, - libs_config_file: 'configs/conf.json', - jobs: 0) + runRegressiontest('master', 'oldInst', 'setCommandLineOptions("-d=nonewInst")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) } } stage('cvode') { @@ -662,18 +420,7 @@ pipeline { expression { params.cvode } } steps { - runRegressiontest(branch: 'master', - name: 'cvode', - extraFlags: 'setCommandLineOptions("-d=newInst,-frontEndUnitCheck")', - omsHash: '', - dbPrefix: 'ripper2', - sshConfig: 'LibraryTestingRipper2DB', - omcompiler: false, - extrasimflags: '-s cvode', - removePackageOrder: false, - conversionScript: false, - libs_config_file: 'configs/conf.json', - jobs: 0) + runRegressiontest('master', 'cvode', 'setCommandLineOptions("-d=newInst,-frontEndUnitCheck")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '-s cvode', false, false) } } stage('gbode') { @@ -689,18 +436,7 @@ pipeline { expression { params.gbode } } steps { - runRegressiontest(branch: 'master', - name: 'gbode', - extraFlags: 'setCommandLineOptions("-d=newInst,-frontEndUnitCheck")', - omsHash: '', - dbPrefix: 'ripper2', - sshConfig: 'LibraryTestingRipper2DB', - omcompiler: false, - extrasimflags: '-s gbode', - removePackageOrder: false, - conversionScript: false, - libs_config_file: 'configs/conf.json', - jobs: 0) + runRegressiontest('master', 'gbode', 'setCommandLineOptions("-d=newInst,-frontEndUnitCheck")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '-s gbode', false, false) } } stage('generateSymbolicJacobian') { @@ -716,18 +452,7 @@ pipeline { expression { params.generateSymbolicJacobian } } steps { - runRegressiontest(branch: 'master', - name: 'generateSymbolicJacobian', - extraFlags: 'setCommandLineOptions("--generateSymbolicJacobian")', - omsHash: '', - dbPrefix: 'ripper1', - sshConfig: 'LibraryTestingRipper1DB', - omcompiler: false, - extrasimflags: '', - removePackageOrder: false, - conversionScript: false, - libs_config_file: 'configs/conf.json', - jobs: 0) + runRegressiontest('master', 'generateSymbolicJacobian', 'setCommandLineOptions("--generateSymbolicJacobian")', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', false, false) } } stage('heavy_tests') { @@ -743,18 +468,18 @@ pipeline { expression { params.heavy_tests } } steps { - runRegressiontest(branch: 'master', - name: 'heavy_tests', - extraFlags: '', - omsHash: '', - dbPrefix: 'ripper2', - sshConfig: 'LibraryTestingRipper2DB', - omcompiler: false, - extrasimflags: '', - removePackageOrder: false, - conversionScript: false, - libs_config_file: 'configs/conf.json', - jobs: 1) + runRegressiontest(branch: 'master', + name: 'heavy_tests', + extraFlags: '', + omsHash: '', + dbPrefix: 'ripper2', + sshConfig: 'LibraryTestingRipper2DB', + omcompiler: false, + extrasimflags: '', + removePackageOrder: false, + conversionScript: false, + libs_config_file: 'configs/conf.json', + jobs: 1) } } stage('C++ v1.18') { @@ -770,18 +495,7 @@ pipeline { expression { params.cpp_v1_18 } } steps { - runRegressiontest(branch: 'maintenance/v1.18', - name: 'v1.18-cpp', - extraFlags: 'setCommandLineOptions("--simCodeTarget=Cpp")', - omsHash: '', - dbPrefix: 'ripper2', - sshConfig: 'LibraryTestingRipper2DB', - omcompiler: false, - extrasimflags: '', - removePackageOrder: false, - conversionScript: false, - libs_config_file: 'configs/conf.json', - jobs: 0) + runRegressiontest('maintenance/v1.18', 'v1.18-cpp', 'setCommandLineOptions("--simCodeTarget=Cpp")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) } } stage('C++ v1.19') { @@ -797,18 +511,7 @@ pipeline { expression { params.cpp_v1_19 } } steps { - runRegressiontest(branch: 'maintenance/v1.19', - name: 'v1.19-cpp', - extraFlags: 'setCommandLineOptions("--simCodeTarget=Cpp")', - omsHash: '', - dbPrefix: 'ripper2', - sshConfig: 'LibraryTestingRipper2DB', - omcompiler: false, - extrasimflags: '', - removePackageOrder: false, - conversionScript: false, - libs_config_file: 'configs/conf.json', - jobs: 0) + runRegressiontest('maintenance/v1.19', 'v1.19-cpp', 'setCommandLineOptions("--simCodeTarget=Cpp")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) } } stage('C++ v1.20') { @@ -824,18 +527,7 @@ pipeline { expression { params.cpp_v1_20 } } steps { - runRegressiontest(branch: 'maintenance/v1.20', - name: 'v1.20-cpp', - extraFlags: 'setCommandLineOptions("--simCodeTarget=Cpp")', - omsHash: '', - dbPrefix: 'ripper2', - sshConfig: 'LibraryTestingRipper2DB', - omcompiler: false, - extrasimflags: '', - removePackageOrder: false, - conversionScript: false, - libs_config_file: 'configs/conf.json', - jobs: 0) + runRegressiontest('maintenance/v1.20', 'v1.20-cpp', 'setCommandLineOptions("--simCodeTarget=Cpp")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) } } stage('C++') { @@ -851,18 +543,7 @@ pipeline { expression { params.cpp } } steps { - runRegressiontest(branch: 'master', - name: 'cpp', - extraFlags: 'setCommandLineOptions("--simCodeTarget=Cpp")', - omsHash: '', - dbPrefix: 'ripper2', - sshConfig: 'LibraryTestingRipper2DB', - omcompiler: false, - extrasimflags: '', - removePackageOrder: false, - conversionScript: false, - libs_config_file: 'configs/conf.json', - jobs: 0) + runRegressiontest('master', 'cpp', 'setCommandLineOptions("--simCodeTarget=Cpp")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) } } } } @@ -1073,7 +754,6 @@ def installLibraries(boolean removePackageOrder, boolean conversionScript, name, /** * Launches the test.py script with the given options. * - * @param libs_config_file: The config file to be used for testing. This file specifies which libraries to test and what options to use for them. * @param jobs: The number of tests/jobs to launch in parallel. By default this is set to 0 which means launch as many tests as there are available physical cpus on the machine'. */ From b81b0b1fdd84aaee2d7173c7be27b226f1216b20 Mon Sep 17 00:00:00 2001 From: Mahder Gebremedhin Date: Wed, 25 Jan 2023 12:37:02 +0100 Subject: [PATCH 115/452] Remove type from parameter. - I am not sure if this is the issue. It is worth a try. --- .CI/Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index f4dcaf9..ad45114 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -757,7 +757,7 @@ def installLibraries(boolean removePackageOrder, boolean conversionScript, name, * @param jobs: The number of tests/jobs to launch in parallel. By default this is set to 0 which means launch as many tests as there are available physical cpus on the machine'. */ -def runRegressiontest(branch, name, extraFlags, omsHash, dbPrefix, sshConfig, omcompiler, extrasimflags, boolean removePackageOrder, boolean conversionScript, String libs_config_file = 'configs/conf.json', int jobs=0) { +def runRegressiontest(branch, name, extraFlags, omsHash, dbPrefix, sshConfig, omcompiler, extrasimflags, boolean removePackageOrder, boolean conversionScript, libs_config_file = 'configs/conf.json', int jobs=0) { sh ''' find /tmp -name "*openmodelica.hudson*" -exec rm {} ";" || true mkdir -p ~/TEST_LIBS_BACKUP From 40372c2d18a194cbf6156defa1e47f3ef1e30aff Mon Sep 17 00:00:00 2001 From: Mahder Gebremedhin Date: Wed, 25 Jan 2023 12:48:00 +0100 Subject: [PATCH 116/452] Remove named parameter calling. (#33) - Maybe this is not possible in Jenkins groovy. It seems we need to access them as a Map (in the called function) in order to use named arguments. --- .CI/Jenkinsfile | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index ad45114..aedfe0b 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -468,18 +468,7 @@ pipeline { expression { params.heavy_tests } } steps { - runRegressiontest(branch: 'master', - name: 'heavy_tests', - extraFlags: '', - omsHash: '', - dbPrefix: 'ripper2', - sshConfig: 'LibraryTestingRipper2DB', - omcompiler: false, - extrasimflags: '', - removePackageOrder: false, - conversionScript: false, - libs_config_file: 'configs/conf.json', - jobs: 1) + runRegressiontest('master', 'heavy_tests', '', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false, 'configs/conf.json', 1) } } stage('C++ v1.18') { From 4c85273e4d8284368e8775267784e5fae69a20b4 Mon Sep 17 00:00:00 2001 From: Mahder Gebremedhin Date: Wed, 25 Jan 2023 12:53:34 +0100 Subject: [PATCH 117/452] Revert every change done for selection of config file. (#34) - Something is broken. Until I figure out what it is remove all changes so we can have a working CI in the meantime. --- .CI/Jenkinsfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index aedfe0b..e1ac2fc 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -468,7 +468,7 @@ pipeline { expression { params.heavy_tests } } steps { - runRegressiontest('master', 'heavy_tests', '', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false, 'configs/conf.json', 1) + runRegressiontest('master', 'heavy_tests', '', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false, 1) } } stage('C++ v1.18') { @@ -746,7 +746,7 @@ def installLibraries(boolean removePackageOrder, boolean conversionScript, name, * @param jobs: The number of tests/jobs to launch in parallel. By default this is set to 0 which means launch as many tests as there are available physical cpus on the machine'. */ -def runRegressiontest(branch, name, extraFlags, omsHash, dbPrefix, sshConfig, omcompiler, extrasimflags, boolean removePackageOrder, boolean conversionScript, libs_config_file = 'configs/conf.json', int jobs=0) { +def runRegressiontest(branch, name, extraFlags, omsHash, dbPrefix, sshConfig, omcompiler, extrasimflags, boolean removePackageOrder, boolean conversionScript, int jobs=0) { sh ''' find /tmp -name "*openmodelica.hudson*" -exec rm {} ";" || true mkdir -p ~/TEST_LIBS_BACKUP @@ -933,7 +933,7 @@ def runRegressiontest(branch, name, extraFlags, omsHash, dbPrefix, sshConfig, om export HOME="${libraryPath}" cd OpenModelicaLibraryTesting # Force /usr/bin/omc as being used for generating the mos-files. Ensures consistent behavior among all tested OMC versions - stdbuf -oL -eL time ./test.py --ompython_omhome=/usr ${FMI_TESTING_FLAG} --extraflags='${extraFlags}' --extrasimflags='${extrasimflags}' --branch="${name}" --output="libraries.openmodelica.org:/var/www/libraries.openmodelica.org/branches/${name}/" --libraries='${libraryPath}/.openmodelica/libraries/' --jobs=${jobs} ${libs_config_file} ${params.OLDLIBS ? "configs/conf-old.json configs/conf-nonstandard.json" : ""} || (killall omc ; false) || exit 1 + stdbuf -oL -eL time ./test.py --ompython_omhome=/usr ${FMI_TESTING_FLAG} --extraflags='${extraFlags}' --extrasimflags='${extrasimflags}' --branch="${name}" --output="libraries.openmodelica.org:/var/www/libraries.openmodelica.org/branches/${name}/" --libraries='${libraryPath}/.openmodelica/libraries/' --jobs=${jobs} configs/conf.json ${params.OLDLIBS ? "configs/conf-old.json configs/conf-nonstandard.json" : ""} || (killall omc ; false) || exit 1 """ sh 'date' sh "rm -f OpenModelicaLibraryTesting/${dbPrefix}-sqlite3.db.tmp" From 07d3bbdc6371b0a4aaaa91e6d46c44baf688107e Mon Sep 17 00:00:00 2001 From: Mahder Gebremedhin Date: Thu, 26 Jan 2023 17:05:35 +0100 Subject: [PATCH 118/452] Allow specifying the config file to use for testing. (#35) - The new parameter has the default value `configs/conf.json`. - This time around we will do it one step at a time. Otherwise it is very difficult to pinpoint what went wrong. --- .CI/Jenkinsfile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index e1ac2fc..059dfcd 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -468,7 +468,7 @@ pipeline { expression { params.heavy_tests } } steps { - runRegressiontest('master', 'heavy_tests', '', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false, 1) + runRegressiontest('master', 'heavy_tests', '', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false, 'configs/conf.json', 1) } } stage('C++ v1.18') { @@ -743,10 +743,11 @@ def installLibraries(boolean removePackageOrder, boolean conversionScript, name, /** * Launches the test.py script with the given options. * + * @param libs_config_file: The config file to be used for testing. This file specifies which libraries to test and what options to use for them. * @param jobs: The number of tests/jobs to launch in parallel. By default this is set to 0 which means launch as many tests as there are available physical cpus on the machine'. */ -def runRegressiontest(branch, name, extraFlags, omsHash, dbPrefix, sshConfig, omcompiler, extrasimflags, boolean removePackageOrder, boolean conversionScript, int jobs=0) { +def runRegressiontest(branch, name, extraFlags, omsHash, dbPrefix, sshConfig, omcompiler, extrasimflags, boolean removePackageOrder, boolean conversionScript, libs_config_file = 'configs/conf.json', int jobs=0) { sh ''' find /tmp -name "*openmodelica.hudson*" -exec rm {} ";" || true mkdir -p ~/TEST_LIBS_BACKUP @@ -933,7 +934,7 @@ def runRegressiontest(branch, name, extraFlags, omsHash, dbPrefix, sshConfig, om export HOME="${libraryPath}" cd OpenModelicaLibraryTesting # Force /usr/bin/omc as being used for generating the mos-files. Ensures consistent behavior among all tested OMC versions - stdbuf -oL -eL time ./test.py --ompython_omhome=/usr ${FMI_TESTING_FLAG} --extraflags='${extraFlags}' --extrasimflags='${extrasimflags}' --branch="${name}" --output="libraries.openmodelica.org:/var/www/libraries.openmodelica.org/branches/${name}/" --libraries='${libraryPath}/.openmodelica/libraries/' --jobs=${jobs} configs/conf.json ${params.OLDLIBS ? "configs/conf-old.json configs/conf-nonstandard.json" : ""} || (killall omc ; false) || exit 1 + stdbuf -oL -eL time ./test.py --ompython_omhome=/usr ${FMI_TESTING_FLAG} --extraflags='${extraFlags}' --extrasimflags='${extrasimflags}' --branch="${name}" --output="libraries.openmodelica.org:/var/www/libraries.openmodelica.org/branches/${name}/" --libraries='${libraryPath}/.openmodelica/libraries/' --jobs=${jobs} ${libs_config_file} ${params.OLDLIBS ? "configs/conf-old.json configs/conf-nonstandard.json" : ""} || (killall omc ; false) || exit 1 """ sh 'date' sh "rm -f OpenModelicaLibraryTesting/${dbPrefix}-sqlite3.db.tmp" From 3d63dbc3fba43f94f9b6ccb962cbe15ee7775f2b Mon Sep 17 00:00:00 2001 From: Mahder Gebremedhin Date: Thu, 26 Jan 2023 17:22:55 +0100 Subject: [PATCH 119/452] Add an initial config for heavy tests. (#36) - This is just experimental to see what else is missing. - For the moment, it is testing the ScalableTestSuite library with the same settings used for the default configuration. --- .CI/Jenkinsfile | 2 +- configs/heavy_tests.json | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 configs/heavy_tests.json diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index 059dfcd..9c0aa5e 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -468,7 +468,7 @@ pipeline { expression { params.heavy_tests } } steps { - runRegressiontest('master', 'heavy_tests', '', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false, 'configs/conf.json', 1) + runRegressiontest('master', 'heavy_tests', '', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false, 'configs/heavy_tests.json', 1) } } stage('C++ v1.18') { diff --git a/configs/heavy_tests.json b/configs/heavy_tests.json new file mode 100644 index 0000000..6eb0fff --- /dev/null +++ b/configs/heavy_tests.json @@ -0,0 +1,18 @@ +[ + { + "library":"ScalableTestSuite", + "libraryVersion":"master", + "libraryVersionNameForTests":"", + "ulimitOmc":300, + "ulimitExe":300, + "ulimitMemory":12582912, + "optlevel":"-Os -march=native", + "referenceFileExtension":"mat", + "referenceFileNameDelimiter":".", + "referenceFinalDot":"_res.", + "referenceFiles":{ + "giturl":"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/casella/ScalableTestSuite-ref", + "destination":"ReferenceFiles/ScalableTestSuite" + } + } +] From e7b9f37efb8bfda878e84775ee9dea4564864334 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Fri, 27 Jan 2023 09:15:56 +0100 Subject: [PATCH 120/452] Fix location of failOnError --- .CI/Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index 9c0aa5e..d7ca56b 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -943,6 +943,6 @@ def runRegressiontest(branch, name, extraFlags, omsHash, dbPrefix, sshConfig, om sh "cp OpenModelicaLibraryTesting/sqlite3.db ~/TEST_LIBS_BACKUP/${dbPrefix}-sqlite3.db" sh "rm -f ~/TEST_LIBS_BACKUP/${dbPrefix}-`date +sqlite3.%Y%m%d.db`" - sshPublisher(publishers: [sshPublisherDesc(configName: sshConfig, transfers: [sshTransfer(removePrefix: 'OpenModelicaLibraryTesting', sourceFiles: 'OpenModelicaLibraryTesting/sqlite3.db', failOnError: true)])]) + sshPublisher(publishers: [sshPublisherDesc(configName: sshConfig, transfers: [sshTransfer(removePrefix: 'OpenModelicaLibraryTesting', sourceFiles: 'OpenModelicaLibraryTesting/sqlite3.db')])], failOnError: true) } From 5ef7bf549536071fed36bbf9d744a2dda4c79ace Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Sat, 28 Jan 2023 15:55:02 +0100 Subject: [PATCH 121/452] Added installation of LargeTestSuite --- .CI/installLibraries.mos | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.CI/installLibraries.mos b/.CI/installLibraries.mos index 2c69ecc..12a2700 100644 --- a/.CI/installLibraries.mos +++ b/.CI/installLibraries.mos @@ -16,7 +16,7 @@ for v in {"1.6", "3.0.0", "maint.7.0.x", "maint.8.1.x", "maint.9.1.x", "master"} end if; end for; -for lib in {"AdvancedNoise", "BioChem", "BuildingSystems", "BuildSysPro", "Chemical", "ClaRa_Obsolete", "ClaRa", "ConPNlib", "ElectricalEnergyStorage", "ExternData", "ExternalMemoryLib", "FastBuildings", "FCSys", "HanserModelica", "HelmholtzMedia", "IBPSA", "IdealizedContact", "IndustrialControlSystems", "KeyWordIO", "LibRAS", "MEV", "MessagePack", "ModelicaByExample", "ModelicaTestOverdetermined", "Modelica_Synchronous", "Modelica_DeviceDrivers", "Modelica_LinearSystems2", "Modelica_Noise", "ObjectStab", "OpenHydraulics", "OpenIPSL", "PNlib", "Physiolibrary", "PlanarMechanics", "PowerGrids", "PowerSysPro", "ScalableTestGrids", "ScalableTestSuite", "SolarTherm", "Spot", "SystemDynamics", "TAeZoSysPro", "TAeZoSysPro_testsuite", "ThermalSeparation", "ThermoPower", "ThermoSysPro", "VehicleInterfaces"} loop +for lib in {"AdvancedNoise", "BioChem", "BuildingSystems", "BuildSysPro", "Chemical", "ClaRa_Obsolete", "ClaRa", "ConPNlib", "ElectricalEnergyStorage", "ExternData", "ExternalMemoryLib", "FastBuildings", "FCSys", "HanserModelica", "HelmholtzMedia", "IBPSA", "IdealizedContact", "IndustrialControlSystems", "KeyWordIO", "LargeTestSuite", "LibRAS", "MEV", "MessagePack", "ModelicaByExample", "ModelicaTestOverdetermined", "Modelica_Synchronous", "Modelica_DeviceDrivers", "Modelica_LinearSystems2", "Modelica_Noise", "ObjectStab", "OpenHydraulics", "OpenIPSL", "PNlib", "Physiolibrary", "PlanarMechanics", "PowerGrids", "PowerSysPro", "ScalableTestGrids", "ScalableTestSuite", "SolarTherm", "Spot", "SystemDynamics", "TAeZoSysPro", "TAeZoSysPro_testsuite", "ThermalSeparation", "ThermoPower", "ThermoSysPro", "VehicleInterfaces"} loop if not installPackage(stringTypeName(lib), "master") then print(lib + " " + getErrorString() + "\n"); exit(1); From 9e38241d76adc5d2c27f3e701527e24d601764e6 Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Sat, 28 Jan 2023 16:34:51 +0100 Subject: [PATCH 122/452] Update heavy_tests.json --- configs/heavy_tests.json | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/configs/heavy_tests.json b/configs/heavy_tests.json index 6eb0fff..da871ce 100644 --- a/configs/heavy_tests.json +++ b/configs/heavy_tests.json @@ -2,11 +2,11 @@ { "library":"ScalableTestSuite", "libraryVersion":"master", - "libraryVersionNameForTests":"", - "ulimitOmc":300, - "ulimitExe":300, - "ulimitMemory":12582912, - "optlevel":"-Os -march=native", + "libraryVersionNameForTests":"OB", + "ulimitOmc":600, + "ulimitExe":600, + "ulimitMemory":62914560, + "optlevel":"-O0 -march=native", "referenceFileExtension":"mat", "referenceFileNameDelimiter":".", "referenceFinalDot":"_res.", @@ -14,5 +14,32 @@ "giturl":"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/casella/ScalableTestSuite-ref", "destination":"ReferenceFiles/ScalableTestSuite" } + }, + { + "library":"ScalableTestSuite", + "libraryVersion":"master", + "libraryVersionNameForTests":"NB", + "ulimitOmc":600, + "ulimitExe":600, + "ulimitMemory":62914560, + "optlevel":"-Ofast -march=native", + "referenceFileExtension":"mat", + "referenceFileNameDelimiter":".", + "referenceFinalDot":"_res.", + "referenceFiles":{ + "giturl":"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/casella/ScalableTestSuite-ref", + "destination":"ReferenceFiles/ScalableTestSuite" + }, + "extraCustomCommands":["setCommandLineOptions(\"--newBackend\")"] + }, + { + "library":"LargeTestSuite", + "libraryVersion":"master", + "libraryVersionNameForTests":"NB", + "ulimitOmc":600, + "ulimitExe":900, + "ulimitMemory":62914560, + "optlevel":"-Ofast -march=native", + "extraCustomCommands":["setCommandLineOptions(\"--newBackend\")"] } ] From a6bdad2d5f3abef59238f311a50424be44e5d3a0 Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Mon, 30 Jan 2023 11:30:31 +0100 Subject: [PATCH 123/452] Only run LargeTestSuite with shorter timeouts, a bit less memory, and -O0 --- configs/heavy_tests.json | 41 ++++---------------------------- configs/heavy_tests.json.bak | 45 ++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 37 deletions(-) create mode 100644 configs/heavy_tests.json.bak diff --git a/configs/heavy_tests.json b/configs/heavy_tests.json index da871ce..9d21f84 100644 --- a/configs/heavy_tests.json +++ b/configs/heavy_tests.json @@ -1,45 +1,12 @@ [ - { - "library":"ScalableTestSuite", - "libraryVersion":"master", - "libraryVersionNameForTests":"OB", - "ulimitOmc":600, - "ulimitExe":600, - "ulimitMemory":62914560, - "optlevel":"-O0 -march=native", - "referenceFileExtension":"mat", - "referenceFileNameDelimiter":".", - "referenceFinalDot":"_res.", - "referenceFiles":{ - "giturl":"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/casella/ScalableTestSuite-ref", - "destination":"ReferenceFiles/ScalableTestSuite" - } - }, - { - "library":"ScalableTestSuite", - "libraryVersion":"master", - "libraryVersionNameForTests":"NB", - "ulimitOmc":600, - "ulimitExe":600, - "ulimitMemory":62914560, - "optlevel":"-Ofast -march=native", - "referenceFileExtension":"mat", - "referenceFileNameDelimiter":".", - "referenceFinalDot":"_res.", - "referenceFiles":{ - "giturl":"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/casella/ScalableTestSuite-ref", - "destination":"ReferenceFiles/ScalableTestSuite" - }, - "extraCustomCommands":["setCommandLineOptions(\"--newBackend\")"] - }, { "library":"LargeTestSuite", "libraryVersion":"master", "libraryVersionNameForTests":"NB", - "ulimitOmc":600, - "ulimitExe":900, - "ulimitMemory":62914560, - "optlevel":"-Ofast -march=native", + "ulimitOmc":300, + "ulimitExe":300, + "ulimitMemory":60000000, + "optlevel":"-O0 -march=native", "extraCustomCommands":["setCommandLineOptions(\"--newBackend\")"] } ] diff --git a/configs/heavy_tests.json.bak b/configs/heavy_tests.json.bak new file mode 100644 index 0000000..da871ce --- /dev/null +++ b/configs/heavy_tests.json.bak @@ -0,0 +1,45 @@ +[ + { + "library":"ScalableTestSuite", + "libraryVersion":"master", + "libraryVersionNameForTests":"OB", + "ulimitOmc":600, + "ulimitExe":600, + "ulimitMemory":62914560, + "optlevel":"-O0 -march=native", + "referenceFileExtension":"mat", + "referenceFileNameDelimiter":".", + "referenceFinalDot":"_res.", + "referenceFiles":{ + "giturl":"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/casella/ScalableTestSuite-ref", + "destination":"ReferenceFiles/ScalableTestSuite" + } + }, + { + "library":"ScalableTestSuite", + "libraryVersion":"master", + "libraryVersionNameForTests":"NB", + "ulimitOmc":600, + "ulimitExe":600, + "ulimitMemory":62914560, + "optlevel":"-Ofast -march=native", + "referenceFileExtension":"mat", + "referenceFileNameDelimiter":".", + "referenceFinalDot":"_res.", + "referenceFiles":{ + "giturl":"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/casella/ScalableTestSuite-ref", + "destination":"ReferenceFiles/ScalableTestSuite" + }, + "extraCustomCommands":["setCommandLineOptions(\"--newBackend\")"] + }, + { + "library":"LargeTestSuite", + "libraryVersion":"master", + "libraryVersionNameForTests":"NB", + "ulimitOmc":600, + "ulimitExe":900, + "ulimitMemory":62914560, + "optlevel":"-Ofast -march=native", + "extraCustomCommands":["setCommandLineOptions(\"--newBackend\")"] + } +] From 07d7dff0c5c5b9fdaa636e40702abf104dcc2db7 Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Mon, 30 Jan 2023 19:02:14 +0100 Subject: [PATCH 124/452] Updated heavy_tests.json configuration file --- configs/heavy_tests.json | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/configs/heavy_tests.json b/configs/heavy_tests.json index 9d21f84..f0dd605 100644 --- a/configs/heavy_tests.json +++ b/configs/heavy_tests.json @@ -1,4 +1,21 @@ [ + { + "library":"ScalableTestSuite", + "libraryVersion":"master", + "libraryVersionNameForTests":"NB", + "ulimitOmc":300, + "ulimitExe":300, + "ulimitMemory":60000000, + "optlevel":"-Ofast -march=native", + "referenceFileExtension":"mat", + "referenceFileNameDelimiter":".", + "referenceFinalDot":"_res.", + "referenceFiles":{ + "giturl":"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/casella/ScalableTestSuite-ref", + "destination":"ReferenceFiles/ScalableTestSuite" + }, + "extraCustomCommands":["setCommandLineOptions(\"--newBackend\")"] + }, { "library":"LargeTestSuite", "libraryVersion":"master", From 215f9bc1b15c97bf4fd331fb6586ded1b1b7e6a3 Mon Sep 17 00:00:00 2001 From: Mahder Gebremedhin Date: Tue, 31 Jan 2023 14:44:03 +0300 Subject: [PATCH 125/452] Change the machine used for the heavy_tests job. (#37) - It should use a non-shared machine. This is to avoid any possibility of another independent job being started on the same machine. We want this job to run tests in exactly similar environments and circumstances from one run to the other. --- .CI/Jenkinsfile | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index d7ca56b..f770686 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -36,7 +36,7 @@ pipeline { booleanParam(name: 'cvode', defaultValue: false, description: 'master branch, with -d=newInst and -s cvode (ryzen-5950x-2). This is an experimental job that does not run on a fixed schedule.') booleanParam(name: 'gbode', defaultValue: false, description: 'master branch, with -d=newInst and -s gbode (ryzen-5950x-2). This is an experimental job that does not run on a fixed schedule.') booleanParam(name: 'generateSymbolicJacobian', defaultValue: false, description: 'master branch, with --generateSymbolicJacobian (ryzen-5950x-1). This is an experimental job that does not run on a fixed schedule.') - booleanParam(name: 'heavy_tests', defaultValue: false, description: 'master branch, runs one test at a time. That is, no parallel launching of tests. omc will use multiple threads for each test (-n=1 is not set unlike the other regression tests.), (ryzen-5950x-2). This is an experimental job that does not run on a fixed schedule.') + booleanParam(name: 'heavy_tests', defaultValue: false, description: 'master branch, runs one test at a time. That is, no parallel launching of tests. omc will use multiple threads for each test (-n=1 is not set unlike the other regression tests.), (ryzen-5950x-1). This is an experimental job that does not run on a fixed schedule.') } environment { LC_ALL = 'C.UTF-8' @@ -458,7 +458,7 @@ pipeline { stage('heavy_tests') { agent { node { - label 'ryzen-5950x-2-1' + label 'ryzen-5950x-1' customWorkspace 'ws/OpenModelicaLibraryTestingWork' } } @@ -468,7 +468,7 @@ pipeline { expression { params.heavy_tests } } steps { - runRegressiontest('master', 'heavy_tests', '', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false, 'configs/heavy_tests.json', 1) + runRegressiontest('master', 'heavy_tests', '', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', false, false, 'configs/heavy_tests.json', 1) } } stage('C++ v1.18') { @@ -548,7 +548,7 @@ pipeline { } when { beforeAgent true - expression { params.v1_12 || params.v1_13 || params.v1_14 || params.v1_16 || params.v1_17 || params.master || params.conversion_script || params.report_ryzen_5950x_1 | params.newInst_newBackend || params.generateSymbolicJacobian} + expression { params.v1_12 || params.v1_13 || params.v1_14 || params.v1_16 || params.v1_17 || params.master || params.conversion_script || params.report_ryzen_5950x_1 | params.newInst_newBackend || params.generateSymbolicJacobian || params.heavy_tests} } environment { GITBRANCHES = 'maintenance/v1.12 maintenance/v1.13 maintenance/v1.14 maintenance/v1.16 maintenance/v1.17 maintenance/v1.18 maintenance/v1.19 maintenance/v1.20 master' @@ -582,6 +582,9 @@ pipeline { sh "./report.py --branches='generateSymbolicJacobian' configs/conf.json" sh "mv overview.html overview-generateSymbolicJacobian.html" + sh "./report.py --branches='heavy_tests' configs/heavy_tests.json" + sh "mv overview.html overview-heavy_tests.html" + sh "./report.py --branches='${env.GITBRANCHES}' configs/conf.json" sh 'date' @@ -604,7 +607,7 @@ pipeline { } when { beforeAgent true - expression { params.fmi_v1_12 || params.fmi_v1_13 || params.fmi_v1_14 || params.fmi_v1_16 || params.fmi_v1_17 || params.fmi_master || params.newInst_daeMode || params.oldInst || params.report_ryzen_5950x_2 || params.cpp || params.cvode || params.gbode || params.heavy_tests} + expression { params.fmi_v1_12 || params.fmi_v1_13 || params.fmi_v1_14 || params.fmi_v1_16 || params.fmi_v1_17 || params.fmi_master || params.newInst_daeMode || params.oldInst || params.report_ryzen_5950x_2 || params.cpp || params.cvode || params.gbode} } environment { GITBRANCHES_FMI = 'maintenance/v1.12-fmi maintenance/v1.13-fmi maintenance/v1.14-fmi maintenance/v1.16-fmi maintenance/v1.17-fmi maintenance/v1.18-fmi maintenance/v1.19-fmi maintenance/v1.20-fmi master-fmi' @@ -662,9 +665,6 @@ pipeline { sh "./report.py --branches='gbode' configs/conf.json" sh "mv overview.html overview-gbode.html" - sh "./report.py --branches='heavy_tests' configs/conf.json" - sh "mv overview.html overview-heavy_tests.html" - sh "./report.py --branches='${env.GITBRANCHES_CPP}' configs/conf.json" sh "mv overview.html overview-c++.html" From c3dad6fe590c33606b59c54209a0b6eec6191972 Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Fri, 3 Feb 2023 01:50:11 +0100 Subject: [PATCH 126/452] Only test LargeTestSuite --- configs/heavy_tests.json | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/configs/heavy_tests.json b/configs/heavy_tests.json index f0dd605..9d21f84 100644 --- a/configs/heavy_tests.json +++ b/configs/heavy_tests.json @@ -1,21 +1,4 @@ [ - { - "library":"ScalableTestSuite", - "libraryVersion":"master", - "libraryVersionNameForTests":"NB", - "ulimitOmc":300, - "ulimitExe":300, - "ulimitMemory":60000000, - "optlevel":"-Ofast -march=native", - "referenceFileExtension":"mat", - "referenceFileNameDelimiter":".", - "referenceFinalDot":"_res.", - "referenceFiles":{ - "giturl":"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/casella/ScalableTestSuite-ref", - "destination":"ReferenceFiles/ScalableTestSuite" - }, - "extraCustomCommands":["setCommandLineOptions(\"--newBackend\")"] - }, { "library":"LargeTestSuite", "libraryVersion":"master", From 56f9e874e97971339cb49d5f4cda8e536e5d5fa5 Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Wed, 8 Feb 2023 18:43:13 +0100 Subject: [PATCH 127/452] Added tests to compare analytic and numerical Jacobians in ScalablePowerGrids --- configs/heavy_tests.json | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/configs/heavy_tests.json b/configs/heavy_tests.json index 9d21f84..71f570e 100644 --- a/configs/heavy_tests.json +++ b/configs/heavy_tests.json @@ -8,5 +8,24 @@ "ulimitMemory":60000000, "optlevel":"-O0 -march=native", "extraCustomCommands":["setCommandLineOptions(\"--newBackend\")"] + }, + { + "library":"ScalableTestGrids", + "libraryVersion":"master", + "libraryVersionNameForTests":"NumericalJacobian", + "ulimitOmc":300, + "ulimitExe":300, + "ulimitMemory":60000000, + "optlevel":"-O0 -march=native" + }, + { + "library":"ScalableTestGrids", + "libraryVersion":"master", + "libraryVersionNameForTests":"AnalyticJacobian", + "ulimitOmc":300, + "ulimitExe":300, + "ulimitMemory":60000000, + "optlevel":"-O0 -march=native", + "extraCustomCommands":["setCommandLineOptions(\"--generateSymbolicJacobian\")"] } ] From 9bc8acbf7acc43fe018421429824798b26e356f9 Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Tue, 14 Feb 2023 17:52:45 +0100 Subject: [PATCH 128/452] Only test LargeTestSuite_NB --- configs/heavy_tests.json | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/configs/heavy_tests.json b/configs/heavy_tests.json index 71f570e..9d21f84 100644 --- a/configs/heavy_tests.json +++ b/configs/heavy_tests.json @@ -8,24 +8,5 @@ "ulimitMemory":60000000, "optlevel":"-O0 -march=native", "extraCustomCommands":["setCommandLineOptions(\"--newBackend\")"] - }, - { - "library":"ScalableTestGrids", - "libraryVersion":"master", - "libraryVersionNameForTests":"NumericalJacobian", - "ulimitOmc":300, - "ulimitExe":300, - "ulimitMemory":60000000, - "optlevel":"-O0 -march=native" - }, - { - "library":"ScalableTestGrids", - "libraryVersion":"master", - "libraryVersionNameForTests":"AnalyticJacobian", - "ulimitOmc":300, - "ulimitExe":300, - "ulimitMemory":60000000, - "optlevel":"-O0 -march=native", - "extraCustomCommands":["setCommandLineOptions(\"--generateSymbolicJacobian\")"] } ] From b3db4ea84dc63a2785719b120a7e9ca9bb982d8f Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Thu, 23 Feb 2023 09:12:41 +0100 Subject: [PATCH 129/452] Updated time limit on LargeTestSuite_NB One more round of ScalableTestSuite_OB and ScalableTestSuite_NB --- configs/heavy_tests.json | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/configs/heavy_tests.json b/configs/heavy_tests.json index 9d21f84..340eff6 100644 --- a/configs/heavy_tests.json +++ b/configs/heavy_tests.json @@ -1,10 +1,43 @@ [ + { + "library":"ScalableTestSuite", + "libraryVersion":"master", + "libraryVersionNameForTests":"OB", + "ulimitOmc":400, + "ulimitExe":600, + "ulimitMemory":62914560, + "optlevel":"-O0 -march=native", + "referenceFileExtension":"mat", + "referenceFileNameDelimiter":".", + "referenceFinalDot":"_res.", + "referenceFiles":{ + "giturl":"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/casella/ScalableTestSuite-ref", + "destination":"ReferenceFiles/ScalableTestSuite" + } + }, + { + "library":"ScalableTestSuite", + "libraryVersion":"master", + "libraryVersionNameForTests":"NB", + "ulimitOmc":400, + "ulimitExe":600, + "ulimitMemory":62914560, + "optlevel":"-Ofast -march=native", + "referenceFileExtension":"mat", + "referenceFileNameDelimiter":".", + "referenceFinalDot":"_res.", + "referenceFiles":{ + "giturl":"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/casella/ScalableTestSuite-ref", + "destination":"ReferenceFiles/ScalableTestSuite" + }, + "extraCustomCommands":["setCommandLineOptions(\"--newBackend\")"] + }, { "library":"LargeTestSuite", "libraryVersion":"master", "libraryVersionNameForTests":"NB", "ulimitOmc":300, - "ulimitExe":300, + "ulimitExe":600, "ulimitMemory":60000000, "optlevel":"-O0 -march=native", "extraCustomCommands":["setCommandLineOptions(\"--newBackend\")"] From 327e302e0a2d1ae9a3cce3523a7ee1319abe0c39 Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Sat, 25 Feb 2023 02:20:06 +0100 Subject: [PATCH 130/452] Set -Ofast also for LargeTestSuite --- configs/heavy_tests.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/heavy_tests.json b/configs/heavy_tests.json index 340eff6..9a44320 100644 --- a/configs/heavy_tests.json +++ b/configs/heavy_tests.json @@ -39,7 +39,7 @@ "ulimitOmc":300, "ulimitExe":600, "ulimitMemory":60000000, - "optlevel":"-O0 -march=native", + "optlevel":"-Ofast -march=native", "extraCustomCommands":["setCommandLineOptions(\"--newBackend\")"] } ] From 4f8623092b7b181dfb9d5e1d799319b91c55b845 Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Mon, 27 Feb 2023 21:57:30 +0100 Subject: [PATCH 131/452] Added DeltaRobot and StewartPlatform libraries --- configs/conf.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/configs/conf.json b/configs/conf.json index 2fb901d..2dfbd30 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -173,6 +173,9 @@ { "library":"Credibility" }, + { + "library":"DeltaRobots" + }, { "library":"ElectricalEnergyStorage" }, @@ -323,6 +326,9 @@ { "library":"SolarTherm" }, + { + "library":"StewartPlatform" + }, { "library":"SystemDynamics", "libraryVersion":"master", From d4d2bab06cb89bda40199961ac1bbe110290c0bd Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Mon, 27 Feb 2023 21:59:06 +0100 Subject: [PATCH 132/452] Fixed typo --- configs/conf.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/conf.json b/configs/conf.json index 2dfbd30..8da0521 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -174,7 +174,7 @@ "library":"Credibility" }, { - "library":"DeltaRobots" + "library":"DeltaRobot" }, { "library":"ElectricalEnergyStorage" From e2420a80958d99be7075f251c472d7f6ae1fac70 Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Mon, 27 Feb 2023 22:00:23 +0100 Subject: [PATCH 133/452] Added DeltaRobot and StewartPlatform libraries --- .CI/installLibraries.mos | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.CI/installLibraries.mos b/.CI/installLibraries.mos index 12a2700..a4ca127 100644 --- a/.CI/installLibraries.mos +++ b/.CI/installLibraries.mos @@ -29,6 +29,7 @@ for l in { {"Annex60", ""}, {"BLDC", ""}, {"Credibility", ""}, + {"DeltaRobot", ""}, {"ExtendedPetriNets", ""}, {"FluxTubesExtension","main"}, {"IDEAS", ""}, @@ -43,6 +44,7 @@ for l in { {"PowerSystems",""}, {"SiemensPower",""}, {"SiemensPower","OMCtest"}, + {"StewartPlatform",""}, {"Modelica_LinearSystems2", "dev"}, {"Modelica_StateGraph2", ""}, {"Physiomodel", ""}, From fecffa7fd1b5490c792bc7b4f8114645b72944fb Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Mon, 27 Feb 2023 23:38:53 +0100 Subject: [PATCH 134/452] Added flag to use symbolic Jacobian to grid tests --- configs/conf.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/configs/conf.json b/configs/conf.json index 8da0521..2a7b35f 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -69,7 +69,8 @@ "extraCustomCommands":["if not setCommandLineOptions(\"--std=3.3\") then exit(1); end if;"] }, { - "library":"PowerGrids" + "library":"PowerGrids", + "extraCustomCommands":["setCommandLineOptions(\"--generateSymbolicJacobian\")"] }, { "library":"PowerSystems", @@ -289,7 +290,8 @@ "ulimitOmc":500, "ulimitExe":500, "ulimitMemory":12582912, - "optlevel":"-O0" + "optlevel":"-O0", + "extraCustomCommands":["setCommandLineOptions(\"--generateSymbolicJacobian\")"] }, { "library":"ScalableTestSuite", From d08103e774dc9994e87f00069cb28a11f05a049d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Wed, 1 Mar 2023 09:53:47 +0100 Subject: [PATCH 135/452] Use autoreconf --install instead of autoconf --- .CI/Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index f770686..dfa0476 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -841,7 +841,7 @@ def runRegressiontest(branch, name, extraFlags, omsHash, dbPrefix, sshConfig, om cat ~/saved_omc/${name}/.githash || true # TODO: Create a docker image for these things instead? if ! (cmp ~/saved_omc/${name}/.githash .newhash || test -f ~/saved_omc/${name}/.nogit); then - autoconf + autoreconf --install ./configure --with-cppruntime --without-omc --disable-modelica3d CC=clang CXX=clang++ FC=gfortran CFLAGS='-O2 -march=native' --with-omlibrary=all --with-omniORB time make -j16 clean if ! time make -j9 omc > log 2>&1; then From d2e5f737b92012b2ad76b259bb4fb18597962941 Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Mon, 13 Mar 2023 11:57:55 +0100 Subject: [PATCH 136/452] ScalableTestGrids_noopt now points to master --- configs/conf.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/configs/conf.json b/configs/conf.json index 2a7b35f..06bb6e9 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -286,7 +286,8 @@ }, { "library":"ScalableTestGrids", - "configExtraName":"noopt", + "libraryVersion":"master", + "libraryVersionNameForTests":"noopt", "ulimitOmc":500, "ulimitExe":500, "ulimitMemory":12582912, From 184381f1bf2b5439560234b14ed08f26c8c5acf2 Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Mon, 13 Mar 2023 12:13:44 +0100 Subject: [PATCH 137/452] Revert "ScalableTestGrids_noopt now points to master" That was not a good idea This reverts commit d2e5f737b92012b2ad76b259bb4fb18597962941. --- configs/conf.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/configs/conf.json b/configs/conf.json index 06bb6e9..2a7b35f 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -286,8 +286,7 @@ }, { "library":"ScalableTestGrids", - "libraryVersion":"master", - "libraryVersionNameForTests":"noopt", + "configExtraName":"noopt", "ulimitOmc":500, "ulimitExe":500, "ulimitMemory":12582912, From a177f63d98296d4bc88208484ccbc95bc12fe106 Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Mon, 13 Mar 2023 19:13:43 +0100 Subject: [PATCH 138/452] Updates for PowerGrids and ScalableTestGrids --- configs/conf.json | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/configs/conf.json b/configs/conf.json index 2a7b35f..61a17ba 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -68,8 +68,12 @@ "libraryVersionNameForTests":"", "extraCustomCommands":["if not setCommandLineOptions(\"--std=3.3\") then exit(1); end if;"] }, + { + "library":"PowerGrids" + }, { "library":"PowerGrids", + "libraryVersionNameForTests":"symb_jac", "extraCustomCommands":["setCommandLineOptions(\"--generateSymbolicJacobian\")"] }, { @@ -287,8 +291,8 @@ { "library":"ScalableTestGrids", "configExtraName":"noopt", - "ulimitOmc":500, - "ulimitExe":500, + "ignoreModelPrefix":"ScalableTestGrids.Models.Type1Large", + "ulimitOmc":600, "ulimitMemory":12582912, "optlevel":"-O0", "extraCustomCommands":["setCommandLineOptions(\"--generateSymbolicJacobian\")"] From a0bc420ded49d50bf346bf7756e72c53f4e73603 Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Mon, 13 Mar 2023 19:35:03 +0100 Subject: [PATCH 139/452] Changed heavy_tests for ScalableTestSuite analytic jacobian comparison update --- configs/heavy_tests.json | 50 ++++++++++-------------------------- configs/heavy_tests.json.bak | 12 ++++----- 2 files changed, 20 insertions(+), 42 deletions(-) diff --git a/configs/heavy_tests.json b/configs/heavy_tests.json index 9a44320..dd4f1e4 100644 --- a/configs/heavy_tests.json +++ b/configs/heavy_tests.json @@ -1,45 +1,23 @@ [ { - "library":"ScalableTestSuite", + "library":"ScalableTestGrids", "libraryVersion":"master", - "libraryVersionNameForTests":"OB", - "ulimitOmc":400, - "ulimitExe":600, - "ulimitMemory":62914560, - "optlevel":"-O0 -march=native", - "referenceFileExtension":"mat", - "referenceFileNameDelimiter":".", - "referenceFinalDot":"_res.", - "referenceFiles":{ - "giturl":"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/casella/ScalableTestSuite-ref", - "destination":"ReferenceFiles/ScalableTestSuite" - } - }, - { - "library":"ScalableTestSuite", - "libraryVersion":"master", - "libraryVersionNameForTests":"NB", - "ulimitOmc":400, - "ulimitExe":600, - "ulimitMemory":62914560, - "optlevel":"-Ofast -march=native", - "referenceFileExtension":"mat", - "referenceFileNameDelimiter":".", - "referenceFinalDot":"_res.", - "referenceFiles":{ - "giturl":"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/casella/ScalableTestSuite-ref", - "destination":"ReferenceFiles/ScalableTestSuite" - }, - "extraCustomCommands":["setCommandLineOptions(\"--newBackend\")"] + "libraryVersionNameForTests":"NumericalJacobian", + "ignoreModelPrefix":"ScalableTestGrids.Models.Type1Large", + "ulimitOmc":800, + "ulimitExe":300, + "ulimitMemory":60000000, + "optlevel":"-O0 -march=native" }, { - "library":"LargeTestSuite", + "library":"ScalableTestGrids", "libraryVersion":"master", - "libraryVersionNameForTests":"NB", - "ulimitOmc":300, - "ulimitExe":600, + "libraryVersionNameForTests":"AnalyticJacobian", + "ignoreModelPrefix":"ScalableTestGrids.Models.Type1Large", + "ulimitOmc":800, + "ulimitExe":300, "ulimitMemory":60000000, - "optlevel":"-Ofast -march=native", - "extraCustomCommands":["setCommandLineOptions(\"--newBackend\")"] + "optlevel":"-O0 -march=native", + "extraCustomCommands":["setCommandLineOptions(\"--generateSymbolicJacobian\")"] } ] diff --git a/configs/heavy_tests.json.bak b/configs/heavy_tests.json.bak index da871ce..9a44320 100644 --- a/configs/heavy_tests.json.bak +++ b/configs/heavy_tests.json.bak @@ -3,7 +3,7 @@ "library":"ScalableTestSuite", "libraryVersion":"master", "libraryVersionNameForTests":"OB", - "ulimitOmc":600, + "ulimitOmc":400, "ulimitExe":600, "ulimitMemory":62914560, "optlevel":"-O0 -march=native", @@ -19,7 +19,7 @@ "library":"ScalableTestSuite", "libraryVersion":"master", "libraryVersionNameForTests":"NB", - "ulimitOmc":600, + "ulimitOmc":400, "ulimitExe":600, "ulimitMemory":62914560, "optlevel":"-Ofast -march=native", @@ -31,14 +31,14 @@ "destination":"ReferenceFiles/ScalableTestSuite" }, "extraCustomCommands":["setCommandLineOptions(\"--newBackend\")"] - }, + }, { "library":"LargeTestSuite", "libraryVersion":"master", "libraryVersionNameForTests":"NB", - "ulimitOmc":600, - "ulimitExe":900, - "ulimitMemory":62914560, + "ulimitOmc":300, + "ulimitExe":600, + "ulimitMemory":60000000, "optlevel":"-Ofast -march=native", "extraCustomCommands":["setCommandLineOptions(\"--newBackend\")"] } From e8b3908bf53b18f32aa592cc584ec93d26fe4f75 Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Wed, 15 Mar 2023 09:34:34 +0100 Subject: [PATCH 140/452] Updated name of test, increased RAM slightly --- configs/heavy_tests.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/configs/heavy_tests.json b/configs/heavy_tests.json index dd4f1e4..55864ce 100644 --- a/configs/heavy_tests.json +++ b/configs/heavy_tests.json @@ -6,17 +6,17 @@ "ignoreModelPrefix":"ScalableTestGrids.Models.Type1Large", "ulimitOmc":800, "ulimitExe":300, - "ulimitMemory":60000000, + "ulimitMemory":62000000, "optlevel":"-O0 -march=native" }, { "library":"ScalableTestGrids", "libraryVersion":"master", - "libraryVersionNameForTests":"AnalyticJacobian", + "libraryVersionNameForTests":"SymbolicJacobian", "ignoreModelPrefix":"ScalableTestGrids.Models.Type1Large", "ulimitOmc":800, "ulimitExe":300, - "ulimitMemory":60000000, + "ulimitMemory":62000000, "optlevel":"-O0 -march=native", "extraCustomCommands":["setCommandLineOptions(\"--generateSymbolicJacobian\")"] } From 219d3149231a15c772c93cd76a874b303033e983 Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Tue, 28 Mar 2023 23:30:17 +0200 Subject: [PATCH 141/452] Reinstated ScalableTestSuite and LargeTestSuite tests --- configs/heavy_tests.json | 52 +++++++++++++++++++++++++----------- configs/heavy_tests.json.bak | 23 +++++++++++++++- 2 files changed, 59 insertions(+), 16 deletions(-) diff --git a/configs/heavy_tests.json b/configs/heavy_tests.json index 55864ce..3f43986 100644 --- a/configs/heavy_tests.json +++ b/configs/heavy_tests.json @@ -1,23 +1,45 @@ [ { - "library":"ScalableTestGrids", + "library":"ScalableTestSuite", "libraryVersion":"master", - "libraryVersionNameForTests":"NumericalJacobian", - "ignoreModelPrefix":"ScalableTestGrids.Models.Type1Large", - "ulimitOmc":800, - "ulimitExe":300, - "ulimitMemory":62000000, - "optlevel":"-O0 -march=native" + "libraryVersionNameForTests":"OB", + "ulimitOmc":400, + "ulimitExe":600, + "ulimitMemory":62914560, + "optlevel":"-O0 -march=native", + "referenceFileExtension":"mat", + "referenceFileNameDelimiter":".", + "referenceFinalDot":"_res.", + "referenceFiles":{ + "giturl":"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/casella/ScalableTestSuite-ref", + "destination":"ReferenceFiles/ScalableTestSuite" + } }, { - "library":"ScalableTestGrids", + "library":"ScalableTestSuite", "libraryVersion":"master", - "libraryVersionNameForTests":"SymbolicJacobian", - "ignoreModelPrefix":"ScalableTestGrids.Models.Type1Large", - "ulimitOmc":800, - "ulimitExe":300, - "ulimitMemory":62000000, - "optlevel":"-O0 -march=native", - "extraCustomCommands":["setCommandLineOptions(\"--generateSymbolicJacobian\")"] + "libraryVersionNameForTests":"NB", + "ulimitOmc":400, + "ulimitExe":600, + "ulimitMemory":62914560, + "optlevel":"-Ofast -march=native", + "referenceFileExtension":"mat", + "referenceFileNameDelimiter":".", + "referenceFinalDot":"_res.", + "referenceFiles":{ + "giturl":"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/casella/ScalableTestSuite-ref", + "destination":"ReferenceFiles/ScalableTestSuite" + }, + "extraCustomCommands":["setCommandLineOptions(\"--newBackend\")"] + }, + { + "library":"LargeTestSuite", + "libraryVersion":"master", + "libraryVersionNameForTests":"NB", + "ulimitOmc":300, + "ulimitExe":600, + "ulimitMemory":62914560, + "optlevel":"-Ofast -march=native", + "extraCustomCommands":["setCommandLineOptions(\"--newBackend\")"] } ] diff --git a/configs/heavy_tests.json.bak b/configs/heavy_tests.json.bak index 9a44320..37796ba 100644 --- a/configs/heavy_tests.json.bak +++ b/configs/heavy_tests.json.bak @@ -38,8 +38,29 @@ "libraryVersionNameForTests":"NB", "ulimitOmc":300, "ulimitExe":600, - "ulimitMemory":60000000, + "ulimitMemory":62914560, "optlevel":"-Ofast -march=native", "extraCustomCommands":["setCommandLineOptions(\"--newBackend\")"] + }, + { + "library":"ScalableTestGrids", + "libraryVersion":"master", + "libraryVersionNameForTests":"NumericalJacobian", + "ignoreModelPrefix":"ScalableTestGrids.Models.Type1Large", + "ulimitOmc":800, + "ulimitExe":300, + "ulimitMemory":62000000, + "optlevel":"-O0 -march=native" + }, + { + "library":"ScalableTestGrids", + "libraryVersion":"master", + "libraryVersionNameForTests":"SymbolicJacobian", + "ignoreModelPrefix":"ScalableTestGrids.Models.Type1Large", + "ulimitOmc":800, + "ulimitExe":300, + "ulimitMemory":62000000, + "optlevel":"-O0 -march=native", + "extraCustomCommands":["setCommandLineOptions(\"--generateSymbolicJacobian\")"] } ] From 49168afe02020f48fd1fb0375e755a83e53200aa Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Thu, 30 Mar 2023 10:00:30 +0200 Subject: [PATCH 142/452] Added test of PowerGrids development version --- configs/conf.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/configs/conf.json b/configs/conf.json index 61a17ba..3b8c527 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -76,6 +76,11 @@ "libraryVersionNameForTests":"symb_jac", "extraCustomCommands":["setCommandLineOptions(\"--generateSymbolicJacobian\")"] }, + { + "library":"PowerGrids", + "libraryVersion":"master", + "libraryVersionNameForTests":"dev" + }, { "library":"PowerSystems", "libraryVersionNameForTests":"", From e1e6ef5eb8757915f5375b83c762baca57be70f5 Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Thu, 30 Mar 2023 15:13:21 +0200 Subject: [PATCH 143/452] Now run the ScalableTestGrids tests again --- configs/heavy_tests.json | 52 ++++++++++++---------------------------- 1 file changed, 15 insertions(+), 37 deletions(-) diff --git a/configs/heavy_tests.json b/configs/heavy_tests.json index 3f43986..55864ce 100644 --- a/configs/heavy_tests.json +++ b/configs/heavy_tests.json @@ -1,45 +1,23 @@ [ { - "library":"ScalableTestSuite", + "library":"ScalableTestGrids", "libraryVersion":"master", - "libraryVersionNameForTests":"OB", - "ulimitOmc":400, - "ulimitExe":600, - "ulimitMemory":62914560, - "optlevel":"-O0 -march=native", - "referenceFileExtension":"mat", - "referenceFileNameDelimiter":".", - "referenceFinalDot":"_res.", - "referenceFiles":{ - "giturl":"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/casella/ScalableTestSuite-ref", - "destination":"ReferenceFiles/ScalableTestSuite" - } + "libraryVersionNameForTests":"NumericalJacobian", + "ignoreModelPrefix":"ScalableTestGrids.Models.Type1Large", + "ulimitOmc":800, + "ulimitExe":300, + "ulimitMemory":62000000, + "optlevel":"-O0 -march=native" }, { - "library":"ScalableTestSuite", + "library":"ScalableTestGrids", "libraryVersion":"master", - "libraryVersionNameForTests":"NB", - "ulimitOmc":400, - "ulimitExe":600, - "ulimitMemory":62914560, - "optlevel":"-Ofast -march=native", - "referenceFileExtension":"mat", - "referenceFileNameDelimiter":".", - "referenceFinalDot":"_res.", - "referenceFiles":{ - "giturl":"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/casella/ScalableTestSuite-ref", - "destination":"ReferenceFiles/ScalableTestSuite" - }, - "extraCustomCommands":["setCommandLineOptions(\"--newBackend\")"] - }, - { - "library":"LargeTestSuite", - "libraryVersion":"master", - "libraryVersionNameForTests":"NB", - "ulimitOmc":300, - "ulimitExe":600, - "ulimitMemory":62914560, - "optlevel":"-Ofast -march=native", - "extraCustomCommands":["setCommandLineOptions(\"--newBackend\")"] + "libraryVersionNameForTests":"SymbolicJacobian", + "ignoreModelPrefix":"ScalableTestGrids.Models.Type1Large", + "ulimitOmc":800, + "ulimitExe":300, + "ulimitMemory":62000000, + "optlevel":"-O0 -march=native", + "extraCustomCommands":["setCommandLineOptions(\"--generateSymbolicJacobian\")"] } ] From db8a6de7ddd5b8e1d47c342706a7072339712826 Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Thu, 20 Apr 2023 15:47:49 +0200 Subject: [PATCH 144/452] Added ExternalMedia (latest released version by default) --- configs/conf.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/configs/conf.json b/configs/conf.json index 3b8c527..24a0cfa 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -192,6 +192,9 @@ { "library":"ExtendedPetriNets" }, + { + "library":"ExternalMedia" + }, { "library":"ExternData" }, From 28a99ee406d6723fc1ca4e8233e5550ee28aded2 Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Thu, 20 Apr 2023 15:49:28 +0200 Subject: [PATCH 145/452] Added ExternalMedia --- .CI/installLibraries.mos | 1 + 1 file changed, 1 insertion(+) diff --git a/.CI/installLibraries.mos b/.CI/installLibraries.mos index a4ca127..1b99dc0 100644 --- a/.CI/installLibraries.mos +++ b/.CI/installLibraries.mos @@ -31,6 +31,7 @@ for l in { {"Credibility", ""}, {"DeltaRobot", ""}, {"ExtendedPetriNets", ""}, + {"ExternalMedia",""}, {"FluxTubesExtension","main"}, {"IDEAS", ""}, {"IDEAS", "master"}, From 1e61f88328fe03917e02ad8838110fabf22e77ca Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Thu, 20 Apr 2023 15:57:06 +0200 Subject: [PATCH 146/452] Updated PowerGrids_dev --- configs/conf.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/conf.json b/configs/conf.json index 24a0cfa..1c95ee4 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -78,7 +78,7 @@ }, { "library":"PowerGrids", - "libraryVersion":"master", + "libraryVersion":"develop", "libraryVersionNameForTests":"dev" }, { From 0b9d4452a0409639a9aa2e3d60f45fc657f7d776 Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Thu, 20 Apr 2023 23:32:48 +0200 Subject: [PATCH 147/452] Test ScalableTestSuite and LargeTestSuite again --- configs/heavy_tests.json | 52 ++++++++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 15 deletions(-) diff --git a/configs/heavy_tests.json b/configs/heavy_tests.json index 55864ce..fec2048 100644 --- a/configs/heavy_tests.json +++ b/configs/heavy_tests.json @@ -1,23 +1,45 @@ [ { - "library":"ScalableTestGrids", + "library":"ScalableTestSuite", "libraryVersion":"master", - "libraryVersionNameForTests":"NumericalJacobian", - "ignoreModelPrefix":"ScalableTestGrids.Models.Type1Large", - "ulimitOmc":800, - "ulimitExe":300, - "ulimitMemory":62000000, - "optlevel":"-O0 -march=native" + "libraryVersionNameForTests":"OB", + "ulimitOmc":400, + "ulimitExe":600, + "ulimitMemory":62914560, + "optlevel":"-O0 -march=native", + "referenceFileExtension":"mat", + "referenceFileNameDelimiter":".", + "referenceFinalDot":"_res.", + "referenceFiles":{ + "giturl":"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/casella/ScalableTestSuite-ref", + "destination":"ReferenceFiles/ScalableTestSuite" + } }, { - "library":"ScalableTestGrids", + "library":"ScalableTestSuite", "libraryVersion":"master", - "libraryVersionNameForTests":"SymbolicJacobian", - "ignoreModelPrefix":"ScalableTestGrids.Models.Type1Large", - "ulimitOmc":800, - "ulimitExe":300, - "ulimitMemory":62000000, - "optlevel":"-O0 -march=native", - "extraCustomCommands":["setCommandLineOptions(\"--generateSymbolicJacobian\")"] + "libraryVersionNameForTests":"NB", + "ulimitOmc":400, + "ulimitExe":600, + "ulimitMemory":62914560, + "optlevel":"-Ofast -march=native", + "referenceFileExtension":"mat", + "referenceFileNameDelimiter":".", + "referenceFinalDot":"_res.", + "referenceFiles":{ + "giturl":"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/casella/ScalableTestSuite-ref", + "destination":"ReferenceFiles/ScalableTestSuite" + }, + "extraCustomCommands":["setCommandLineOptions(\"--newBackend\")"] + }, + { + "library":"LargeTestSuite", + "libraryVersion":"master", + "libraryVersionNameForTests":"NB", + "ulimitOmc":600, + "ulimitExe":800, + "ulimitMemory":62914560, + "optlevel":"-Ofast -march=native", + "extraCustomCommands":["setCommandLineOptions(\"--newBackend\")"] } ] From 20537eb3135e4b0df47f5ca6eda80a21ae3737e7 Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Fri, 21 Apr 2023 11:58:30 +0200 Subject: [PATCH 148/452] Skip ExternalMedia.Test.FluidProp tests (FluiProp not installed) --- configs/conf.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/configs/conf.json b/configs/conf.json index 1c95ee4..62076bb 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -193,7 +193,8 @@ "library":"ExtendedPetriNets" }, { - "library":"ExternalMedia" + "library":"ExternalMedia", + "ignoreModelPrefix":"ExternalMedia.Test.FluidProp" }, { "library":"ExternData" From 80a94c1a4e835b2690e699f03eb903916f43cbd3 Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Fri, 21 Apr 2023 12:07:54 +0200 Subject: [PATCH 149/452] Updated PowerGrids --- .CI/installLibraries.mos | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.CI/installLibraries.mos b/.CI/installLibraries.mos index 1b99dc0..168b7b6 100644 --- a/.CI/installLibraries.mos +++ b/.CI/installLibraries.mos @@ -16,7 +16,7 @@ for v in {"1.6", "3.0.0", "maint.7.0.x", "maint.8.1.x", "maint.9.1.x", "master"} end if; end for; -for lib in {"AdvancedNoise", "BioChem", "BuildingSystems", "BuildSysPro", "Chemical", "ClaRa_Obsolete", "ClaRa", "ConPNlib", "ElectricalEnergyStorage", "ExternData", "ExternalMemoryLib", "FastBuildings", "FCSys", "HanserModelica", "HelmholtzMedia", "IBPSA", "IdealizedContact", "IndustrialControlSystems", "KeyWordIO", "LargeTestSuite", "LibRAS", "MEV", "MessagePack", "ModelicaByExample", "ModelicaTestOverdetermined", "Modelica_Synchronous", "Modelica_DeviceDrivers", "Modelica_LinearSystems2", "Modelica_Noise", "ObjectStab", "OpenHydraulics", "OpenIPSL", "PNlib", "Physiolibrary", "PlanarMechanics", "PowerGrids", "PowerSysPro", "ScalableTestGrids", "ScalableTestSuite", "SolarTherm", "Spot", "SystemDynamics", "TAeZoSysPro", "TAeZoSysPro_testsuite", "ThermalSeparation", "ThermoPower", "ThermoSysPro", "VehicleInterfaces"} loop +for lib in {"AdvancedNoise", "BioChem", "BuildingSystems", "BuildSysPro", "Chemical", "ClaRa_Obsolete", "ClaRa", "ConPNlib", "ElectricalEnergyStorage", "ExternData", "ExternalMemoryLib", "FastBuildings", "FCSys", "HanserModelica", "HelmholtzMedia", "IBPSA", "IdealizedContact", "IndustrialControlSystems", "KeyWordIO", "LargeTestSuite", "LibRAS", "MEV", "MessagePack", "ModelicaByExample", "ModelicaTestOverdetermined", "Modelica_Synchronous", "Modelica_DeviceDrivers", "Modelica_LinearSystems2", "Modelica_Noise", "ObjectStab", "OpenHydraulics", "OpenIPSL", "PNlib", "Physiolibrary", "PlanarMechanics", "PowerSysPro", "ScalableTestGrids", "ScalableTestSuite", "SolarTherm", "Spot", "SystemDynamics", "TAeZoSysPro", "TAeZoSysPro_testsuite", "ThermalSeparation", "ThermoPower", "ThermoSysPro", "VehicleInterfaces"} loop if not installPackage(stringTypeName(lib), "master") then print(lib + " " + getErrorString() + "\n"); exit(1); @@ -43,6 +43,8 @@ for l in { {"PhotoVoltaics_TGM", ""}, {"PowerSystems","master"}, {"PowerSystems",""}, + {"PowerGrids",""}, + {"PowerGrids","develop"}, {"SiemensPower",""}, {"SiemensPower","OMCtest"}, {"StewartPlatform",""}, From 2dbf96962d38cd4706336389650769bba44fff43 Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Wed, 17 May 2023 17:16:22 +0200 Subject: [PATCH 150/452] Updated configuration for released IDEAS --- configs/conf.json | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/configs/conf.json b/configs/conf.json index 62076bb..3a6fa34 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -222,9 +222,7 @@ "library":"KeyWordIO" }, { - "library":"IDEAS", - "libraryVersionNameForTests":"", - "libraryVersionLatestInPackageManager":true + "library":"IDEAS" }, { "library":"IDEAS", From 6c6987382e3f5242059086f742cec2ff9c5d5e3d Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Mon, 22 May 2023 16:24:34 +0200 Subject: [PATCH 151/452] Set up heavy_tests to compare LargeTestSuite OB vs. NB --- configs/heavy_tests.json | 36 ++++++------------------------------ 1 file changed, 6 insertions(+), 30 deletions(-) diff --git a/configs/heavy_tests.json b/configs/heavy_tests.json index fec2048..a57ef97 100644 --- a/configs/heavy_tests.json +++ b/configs/heavy_tests.json @@ -1,45 +1,21 @@ [ { - "library":"ScalableTestSuite", - "libraryVersion":"master", - "libraryVersionNameForTests":"OB", - "ulimitOmc":400, - "ulimitExe":600, - "ulimitMemory":62914560, - "optlevel":"-O0 -march=native", - "referenceFileExtension":"mat", - "referenceFileNameDelimiter":".", - "referenceFinalDot":"_res.", - "referenceFiles":{ - "giturl":"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/casella/ScalableTestSuite-ref", - "destination":"ReferenceFiles/ScalableTestSuite" - } - }, - { - "library":"ScalableTestSuite", + "library":"LargeTestSuite", "libraryVersion":"master", "libraryVersionNameForTests":"NB", - "ulimitOmc":400, - "ulimitExe":600, + "ulimitOmc":1800, + "ulimitExe":800, "ulimitMemory":62914560, "optlevel":"-Ofast -march=native", - "referenceFileExtension":"mat", - "referenceFileNameDelimiter":".", - "referenceFinalDot":"_res.", - "referenceFiles":{ - "giturl":"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/casella/ScalableTestSuite-ref", - "destination":"ReferenceFiles/ScalableTestSuite" - }, "extraCustomCommands":["setCommandLineOptions(\"--newBackend\")"] }, { "library":"LargeTestSuite", "libraryVersion":"master", - "libraryVersionNameForTests":"NB", - "ulimitOmc":600, + "libraryVersionNameForTests":"OB", + "ulimitOmc":1800, "ulimitExe":800, "ulimitMemory":62914560, - "optlevel":"-Ofast -march=native", - "extraCustomCommands":["setCommandLineOptions(\"--newBackend\")"] + "optlevel":"-O0 -march=native" } ] From 0ff8896368649a79b2f6cbee81dcf5b00ed88fa0 Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Mon, 22 May 2023 17:13:25 +0200 Subject: [PATCH 152/452] Updates for version 1.21 --- .CI/Jenkinsfile | 64 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 58 insertions(+), 6 deletions(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index dfa0476..32ced92 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -11,6 +11,7 @@ pipeline { booleanParam(name: 'v1_18', defaultValue: false, description: 'maintenance/v1.18 branch (ryzen-5950x-1)') booleanParam(name: 'v1_19', defaultValue: false, description: 'maintenance/v1.19 branch (ryzen-5950x-1)') booleanParam(name: 'v1_20', defaultValue: false, description: 'maintenance/v1.20 branch (ryzen-5950x-1)') + booleanParam(name: 'v1_21', defaultValue: false, description: 'maintenance/v1.21 branch (ryzen-5950x-1)') booleanParam(name: 'master', defaultValue: false, description: 'master branch (ryzen-5950x-1)') booleanParam(name: 'fmi_v1_12', defaultValue: false, description: 'maintenance/v1.12 branch with FMI (ryzen-5950x-2)') @@ -21,6 +22,7 @@ pipeline { booleanParam(name: 'fmi_v1_18', defaultValue: false, description: 'maintenance/v1.18 branch with FMI (ryzen-5950x-2)') booleanParam(name: 'fmi_v1_19', defaultValue: false, description: 'maintenance/v1.19 branch with FMI (ryzen-5950x-2)') booleanParam(name: 'fmi_v1_20', defaultValue: false, description: 'maintenance/v1.20 branch with FMI (ryzen-5950x-2)') + booleanParam(name: 'fmi_v1_21', defaultValue: false, description: 'maintenance/v1.21 branch with FMI (ryzen-5950x-2)') booleanParam(name: 'fmi_master', defaultValue: false, description: 'master branch with FMI (ryzen-5950x-2)') booleanParam(name: 'newInst_daeMode', defaultValue: false, description: 'master branch, --daeMode with -d=newInst (ryzen-5950x-2)') booleanParam(name: 'newInst_newBackend', defaultValue: false, description: 'master branch, -d=newInst --newBackend, (ryzen-5950x-1)') @@ -28,6 +30,7 @@ pipeline { booleanParam(name: 'cpp_v1_18', defaultValue: false, description: 'maintenance/v1.18 branch, with --simCodeTarget=Cpp (ryzen-5950x-2).') booleanParam(name: 'cpp_v1_19', defaultValue: false, description: 'maintenance/v1.19 branch, with --simCodeTarget=Cpp (ryzen-5950x-2).') booleanParam(name: 'cpp_v1_20', defaultValue: false, description: 'maintenance/v1.20 branch, with --simCodeTarget=Cpp (ryzen-5950x-2).') + booleanParam(name: 'cpp_v1_21', defaultValue: false, description: 'maintenance/v1.21 branch, with --simCodeTarget=Cpp (ryzen-5950x-2).') booleanParam(name: 'cpp', defaultValue: false, description: 'master branch, with --simCodeTarget=Cpp (ryzen-5950x-2).') booleanParam(name: 'report_ryzen_5950x_1', defaultValue: false, description: 'Generate a report for ryzen-5950x-1 without running the tests') booleanParam(name: 'report_ryzen_5950x_2', defaultValue: false, description: 'Generate a report for ryzen-5950x-2 without running the tests') @@ -180,6 +183,23 @@ pipeline { } } + stage('v1.21') { + agent { + node { + label 'ryzen-5950x-1' + customWorkspace 'ws/OpenModelicaLibraryTestingWork' + } + } + options { skipDefaultCheckout() } + when { + beforeAgent true + expression { params.v1_21 } + } + steps { + runRegressiontest('maintenance/v1.21', 'v1.21', '', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', false, false) + } + } + stage('master') { agent { node { @@ -359,6 +379,22 @@ pipeline { runRegressiontest('maintenance/v1.20', 'v1.20-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) } } + stage('v1.21 FMI') { + agent { + node { + label 'ryzen-5950x-2-1' + customWorkspace 'ws/OpenModelicaLibraryTestingWork' + } + } + options { skipDefaultCheckout() } + when { + beforeAgent true + expression { params.fmi_v1_21 } + } + steps { + runRegressiontest('maintenance/v1.21', 'v1.21-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) + } + } stage('master FMI') { agent { node { @@ -519,6 +555,22 @@ pipeline { runRegressiontest('maintenance/v1.20', 'v1.20-cpp', 'setCommandLineOptions("--simCodeTarget=Cpp")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) } } + stage('C++ v1.21') { + agent { + node { + label 'ryzen-5950x-2-1' + customWorkspace 'ws/OpenModelicaLibraryTestingWork' + } + } + options { skipDefaultCheckout() } + when { + beforeAgent true + expression { params.cpp_v1_21 } + } + steps { + runRegressiontest('maintenance/v1.21', 'v1.21-cpp', 'setCommandLineOptions("--simCodeTarget=Cpp")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) + } + } stage('C++') { agent { node { @@ -548,10 +600,10 @@ pipeline { } when { beforeAgent true - expression { params.v1_12 || params.v1_13 || params.v1_14 || params.v1_16 || params.v1_17 || params.master || params.conversion_script || params.report_ryzen_5950x_1 | params.newInst_newBackend || params.generateSymbolicJacobian || params.heavy_tests} + expression { params.v1_12 || params.v1_13 || params.v1_14 || params.v1_16 || params.v1_17 || params.v1_18 || params.v1_19 || params.v1_20 || params.v1_21 || params.master || params.conversion_script || params.report_ryzen_5950x_1 | params.newInst_newBackend || params.generateSymbolicJacobian || params.heavy_tests} } environment { - GITBRANCHES = 'maintenance/v1.12 maintenance/v1.13 maintenance/v1.14 maintenance/v1.16 maintenance/v1.17 maintenance/v1.18 maintenance/v1.19 maintenance/v1.20 master' + GITBRANCHES = 'maintenance/v1.12 maintenance/v1.13 maintenance/v1.14 maintenance/v1.16 maintenance/v1.17 maintenance/v1.18 maintenance/v1.19 maintenance/v1.20 master maintenance/v1.21 master' PYTHONIOENCODING = 'utf-8' IDA_EMAIL = credentials('IDA email') } @@ -607,13 +659,13 @@ pipeline { } when { beforeAgent true - expression { params.fmi_v1_12 || params.fmi_v1_13 || params.fmi_v1_14 || params.fmi_v1_16 || params.fmi_v1_17 || params.fmi_master || params.newInst_daeMode || params.oldInst || params.report_ryzen_5950x_2 || params.cpp || params.cvode || params.gbode} + expression { params.fmi_v1_12 || params.fmi_v1_13 || params.fmi_v1_14 || params.fmi_v1_16 || params.fmi_v1_17 || params.fmi_v1_18 || params.fmi_v1_19 || params.fmi_v1_20 || params.fmi_v1_21 || params.fmi_master || params.newInst_daeMode || params.oldInst || params.report_ryzen_5950x_2 || params.cpp || params.cvode || params.gbode} } environment { - GITBRANCHES_FMI = 'maintenance/v1.12-fmi maintenance/v1.13-fmi maintenance/v1.14-fmi maintenance/v1.16-fmi maintenance/v1.17-fmi maintenance/v1.18-fmi maintenance/v1.19-fmi maintenance/v1.20-fmi master-fmi' + GITBRANCHES_FMI = 'maintenance/v1.12-fmi maintenance/v1.13-fmi maintenance/v1.14-fmi maintenance/v1.16-fmi maintenance/v1.17-fmi maintenance/v1.18-fmi maintenance/v1.19-fmi maintenance/v1.20-fmi maintenance/v1.21-fmi master-fmi' GITBRANCHES_NEWINST = 'oldInst' GITBRANCHES_DAE = 'daemode newInst-daemode' - GITBRANCHES_CPP = 'v1.19-cpp v1.20-cpp cpp' + GITBRANCHES_CPP = 'v1.19-cpp v1.20-cpp v1.21-cpp cpp' PYTHONIOENCODING = 'utf-8' IDA_EMAIL = credentials('IDA email') } @@ -687,7 +739,7 @@ pipeline { } when { beforeAgent true - expression { params.v1_12 || params.v1_13 || params.v1_14 || params.v1_16 || params.v1_17 || params.v1_18 || params.v1_19 || params.v1_20 || params.master || params.report_ripper1 || params.generateSymbolicJacobian } + expression { params.v1_12 || params.v1_13 || params.v1_14 || params.v1_16 || params.v1_17 || params.v1_18 || params.v1_19 || params.v1_20 || params.v1_21 || params.master || params.report_ripper1 || params.generateSymbolicJacobian } } steps { sh 'cp ~/TEST_LIBS_BACKUP/ripper1-sqlite3.db sqlite3.db' From 5bf0b1a3c597dea33235957744ad016116dc3c0c Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Mon, 22 May 2023 17:54:13 +0200 Subject: [PATCH 153/452] Fixed env variables for daeMode testing --- .CI/Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index 32ced92..6e64a3d 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -664,7 +664,7 @@ pipeline { environment { GITBRANCHES_FMI = 'maintenance/v1.12-fmi maintenance/v1.13-fmi maintenance/v1.14-fmi maintenance/v1.16-fmi maintenance/v1.17-fmi maintenance/v1.18-fmi maintenance/v1.19-fmi maintenance/v1.20-fmi maintenance/v1.21-fmi master-fmi' GITBRANCHES_NEWINST = 'oldInst' - GITBRANCHES_DAE = 'daemode newInst-daemode' + GITBRANCHES_DAE = 'newInst-daeMode' GITBRANCHES_CPP = 'v1.19-cpp v1.20-cpp v1.21-cpp cpp' PYTHONIOENCODING = 'utf-8' IDA_EMAIL = credentials('IDA email') From 580e6ab6f97c96680474570f60701634f44950dc Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Sun, 4 Jun 2023 22:18:23 +0200 Subject: [PATCH 154/452] fix copy paste error, remove the first master --- .CI/Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index 6e64a3d..d7469a4 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -603,7 +603,7 @@ pipeline { expression { params.v1_12 || params.v1_13 || params.v1_14 || params.v1_16 || params.v1_17 || params.v1_18 || params.v1_19 || params.v1_20 || params.v1_21 || params.master || params.conversion_script || params.report_ryzen_5950x_1 | params.newInst_newBackend || params.generateSymbolicJacobian || params.heavy_tests} } environment { - GITBRANCHES = 'maintenance/v1.12 maintenance/v1.13 maintenance/v1.14 maintenance/v1.16 maintenance/v1.17 maintenance/v1.18 maintenance/v1.19 maintenance/v1.20 master maintenance/v1.21 master' + GITBRANCHES = 'maintenance/v1.12 maintenance/v1.13 maintenance/v1.14 maintenance/v1.16 maintenance/v1.17 maintenance/v1.18 maintenance/v1.19 maintenance/v1.20 maintenance/v1.21 master' PYTHONIOENCODING = 'utf-8' IDA_EMAIL = credentials('IDA email') } From 8a4d6ca2bda99dba2852886a9c0ab42619e6e31c Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Mon, 5 Jun 2023 13:08:26 +0200 Subject: [PATCH 155/452] skip email if domain does not have a dot in it! --- all-reports.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/all-reports.py b/all-reports.py index c20f341..5ba7385 100755 --- a/all-reports.py +++ b/all-reports.py @@ -119,6 +119,9 @@ def modelLink(libname, modelname, extension, text): for email in [email.strip() for email in subprocess.check_output(["git", "log", '--pretty=%ae', "%s..%s" % (v1,v2)], cwd=omcgitdir).decode("utf-8").split("\n")]: if "@" not in email: continue + # adrpo: if email domain doesn't have "." in it, skip it + if "." not in email[email.find("@"):]: + continue emails_current.add(email) except subprocess.CalledProcessError as e: print(str(e)) From a3dbc1ae66a835d1c7147ffc2ef43c3cd718a771 Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Sun, 18 Jun 2023 19:40:39 +0200 Subject: [PATCH 156/452] add TransiEnt to library testing --- configs/conf.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/configs/conf.json b/configs/conf.json index 3a6fa34..37b777e 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -392,6 +392,14 @@ "libraryVersion":"master", "libraryVersionNameForTests":"" }, + { + "library":"TransiEnt", + "libraryVersion":"master", + "libraryVersionNameForTests":"", + "extraLibraries":[ + ["TILMedia", "ClaRa"] + ] + }, { "library":"VehicleInterfaces" } From be8af97b05828ee4fa6562091f46dabeb3faae00 Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Wed, 21 Jun 2023 14:31:25 +0200 Subject: [PATCH 157/452] add TransiEnt to the testing --- .CI/installLibraries.mos | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.CI/installLibraries.mos b/.CI/installLibraries.mos index 168b7b6..6b39f99 100644 --- a/.CI/installLibraries.mos +++ b/.CI/installLibraries.mos @@ -16,7 +16,7 @@ for v in {"1.6", "3.0.0", "maint.7.0.x", "maint.8.1.x", "maint.9.1.x", "master"} end if; end for; -for lib in {"AdvancedNoise", "BioChem", "BuildingSystems", "BuildSysPro", "Chemical", "ClaRa_Obsolete", "ClaRa", "ConPNlib", "ElectricalEnergyStorage", "ExternData", "ExternalMemoryLib", "FastBuildings", "FCSys", "HanserModelica", "HelmholtzMedia", "IBPSA", "IdealizedContact", "IndustrialControlSystems", "KeyWordIO", "LargeTestSuite", "LibRAS", "MEV", "MessagePack", "ModelicaByExample", "ModelicaTestOverdetermined", "Modelica_Synchronous", "Modelica_DeviceDrivers", "Modelica_LinearSystems2", "Modelica_Noise", "ObjectStab", "OpenHydraulics", "OpenIPSL", "PNlib", "Physiolibrary", "PlanarMechanics", "PowerSysPro", "ScalableTestGrids", "ScalableTestSuite", "SolarTherm", "Spot", "SystemDynamics", "TAeZoSysPro", "TAeZoSysPro_testsuite", "ThermalSeparation", "ThermoPower", "ThermoSysPro", "VehicleInterfaces"} loop +for lib in {"AdvancedNoise", "BioChem", "BuildingSystems", "BuildSysPro", "Chemical", "ClaRa_Obsolete", "ClaRa", "ConPNlib", "ElectricalEnergyStorage", "ExternData", "ExternalMemoryLib", "FastBuildings", "FCSys", "HanserModelica", "HelmholtzMedia", "IBPSA", "IdealizedContact", "IndustrialControlSystems", "KeyWordIO", "LargeTestSuite", "LibRAS", "MEV", "MessagePack", "ModelicaByExample", "ModelicaTestOverdetermined", "Modelica_Synchronous", "Modelica_DeviceDrivers", "Modelica_LinearSystems2", "Modelica_Noise", "ObjectStab", "OpenHydraulics", "OpenIPSL", "PNlib", "Physiolibrary", "PlanarMechanics", "PowerSysPro", "ScalableTestGrids", "ScalableTestSuite", "SolarTherm", "Spot", "SystemDynamics", "TAeZoSysPro", "TAeZoSysPro_testsuite", "ThermalSeparation", "ThermoPower", "ThermoSysPro", "TransiEnt", "VehicleInterfaces"} loop if not installPackage(stringTypeName(lib), "master") then print(lib + " " + getErrorString() + "\n"); exit(1); From 332ff9eb8f1ee2fbc73f7fa5bc6dc0b90680f056 Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Sat, 1 Jul 2023 13:14:38 +0200 Subject: [PATCH 158/452] do NOT sort the top level loaded files! --- configs/conf.json | 5 +---- test.py | 4 +++- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/configs/conf.json b/configs/conf.json index 37b777e..c279810 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -395,10 +395,7 @@ { "library":"TransiEnt", "libraryVersion":"master", - "libraryVersionNameForTests":"", - "extraLibraries":[ - ["TILMedia", "ClaRa"] - ] + "libraryVersionNameForTests":"" }, { "library":"VehicleInterfaces" diff --git a/test.py b/test.py index 20afb74..8ac3e96 100755 --- a/test.py +++ b/test.py @@ -482,7 +482,9 @@ def hashReferenceFiles(s): print("Failed to load library %s %s: %s" % (library,versions,omc.sendExpression('OpenModelica.Scripting.getErrorString()'))) except: print("Failed to load library %s %s. OpenModelica.Scripting.getErrorString() failed..." % (library,conf["libraryVersion"])) - conf["loadFiles"] = sorted(omc.sendExpression("{getSourceFile(cl) for cl in getClassNames()}")) + # adrpo: do not sort the top level names as sometimes that loads a bad MSL version + # conf["loadFiles"] = sorted(omc.sendExpression("{getSourceFile(cl) for cl in getClassNames()}")) + conf["loadFiles"] = omc.sendExpression("{getSourceFile(cl) for cl in getClassNames()}") if not (omc.sendExpression('setCommandLineOptions("-g=MetaModelica")') or omc.sendExpression('setCommandLineOptions("+g=Modelica")')): print("Failed to set MetaModelica grammar") From 05cc926823c148ed6604ed9bbe65be9ddc20976a Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Sat, 1 Jul 2023 21:33:03 +0200 Subject: [PATCH 159/452] sort the list before comparison --- testmodel.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testmodel.py b/testmodel.py index 656d5c0..190acf8 100755 --- a/testmodel.py +++ b/testmodel.py @@ -264,8 +264,8 @@ def loadModels(omc, conf): fp.write(omc.sendExpression('OpenModelica.Scripting.getErrorString()')) writeResultAndExit(0) loadedFiles = sorted(omc.sendExpression("{getSourceFile(cl) for cl in getClassNames()}")) - if conf["loadFiles"] != loadedFiles: - print("Loaded the wrong files. Expected:\n%s\nActual:\n%s", ("\n".join(conf["loadFiles"]), "\n".join(loadedFiles))) + if sorted(conf["loadFiles"]) != loadedFiles: + print("Loaded the wrong files. Expected:\n%s\nActual:\n%s" % ("\n".join(sorted(conf["loadFiles"])), "\n".join(loadedFiles))) sys.exit(1) newOMLoaded = False def loadLibraryInNewOM(): From c3737baf9edb874efbd5d71f83f12660bcf1e690 Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Thu, 6 Jul 2023 17:38:58 +0300 Subject: [PATCH 160/452] allow non-standard enumeration as integer indexes without Integer casting (#38) --- configs/conf.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/configs/conf.json b/configs/conf.json index c279810..a17111e 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -395,7 +395,8 @@ { "library":"TransiEnt", "libraryVersion":"master", - "libraryVersionNameForTests":"" + "libraryVersionNameForTests":"", + "extraCustomCommands": ["setCommandLineOptions(\"--allowNonStandardModelica=nonStdEnumerationAsIntegers\")"] }, { "library":"VehicleInterfaces" From ebba8e1fe6252273101dcf04cb5a37b5448cb0c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Mon, 10 Jul 2023 09:50:34 +0200 Subject: [PATCH 161/452] Test BidiDCDC, DroneLibrary, and MagLev --- .CI/installLibraries.mos | 3 +++ configs/conf.json | 12 ++++++++++++ 2 files changed, 15 insertions(+) diff --git a/.CI/installLibraries.mos b/.CI/installLibraries.mos index 6b39f99..fddfc68 100644 --- a/.CI/installLibraries.mos +++ b/.CI/installLibraries.mos @@ -27,15 +27,18 @@ for l in { {"AES", "main"}, {"AixLib", "development"}, {"Annex60", ""}, + {"BidiDCDC", ""}, {"BLDC", ""}, {"Credibility", ""}, {"DeltaRobot", ""}, + {"DroneLibrary", ""}, {"ExtendedPetriNets", ""}, {"ExternalMedia",""}, {"FluxTubesExtension","main"}, {"IDEAS", ""}, {"IDEAS", "master"}, {"iPSL", ""}, + {"MagLev", ""}, {"OpenIPSL", "2.0.0"}, {"OpenIPSL", ""}, {"OpenIPSL", "master"}, diff --git a/configs/conf.json b/configs/conf.json index a17111e..68d2798 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -121,6 +121,10 @@ "libraryVersionNameForTests":"latest", "extraCustomCommands":["setCommandLineOptions(\"-d=ignoreCycles\")"] }, + { + "library":"BidiDCDC", + "libraryVersionNameForTests":"" + }, { "library":"BLDC", "libraryVersionNameForTests":"" @@ -186,6 +190,10 @@ { "library":"DeltaRobot" }, + { + "library":"DroneLibrary", + "libraryVersionNameForTests":"" + }, { "library":"ElectricalEnergyStorage" }, @@ -233,6 +241,10 @@ "library":"LibRAS", "extraCustomCommands":["if not setCommandLineOptions(\"--std=3.3\") then exit(1); end if;"] }, + { + "library":"MagLev", + "libraryVersionNameForTests":"" + }, { "library":"MEV" }, From c4da69d510fd17924b27cb33073906e91012ba24 Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Mon, 17 Jul 2023 12:30:48 +0200 Subject: [PATCH 162/452] add support for in JSON config 'extraCustomCommands' --- configs/conf.json | 8 +++++++- test.py | 8 ++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/configs/conf.json b/configs/conf.json index 68d2798..f5dd5e6 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -408,7 +408,13 @@ "library":"TransiEnt", "libraryVersion":"master", "libraryVersionNameForTests":"", - "extraCustomCommands": ["setCommandLineOptions(\"--allowNonStandardModelica=nonStdEnumerationAsIntegers\")"] + "extraCustomCommands": + [ + "setCommandLineOptions(\"--allowNonStandardModelica=nonStdEnumerationAsIntegers\")", + "setEnvironmentVar(\"public-data\", \"$libraryLocation/Tables/\"", + "setEnvironmentVar(\"superstructure-tables\", \"$libraryLocation/Tables/superstructure/Tables\"", + "setEnvironmentVar(\"superstructure-input\", \"$libraryLocation/Tables/superstructure/RegionInformation/\"" + ] }, { "library":"VehicleInterfaces" diff --git a/test.py b/test.py index 8ac3e96..8561b2b 100755 --- a/test.py +++ b/test.py @@ -491,8 +491,10 @@ def hashReferenceFiles(s): sys.exit(1) try: + conf["libraryLocation"]=omc.sendExpression('uriToFilename("modelica://%s/")' % library) conf["resourceLocation"]=omc.sendExpression('uriToFilename("modelica://%s/Resources")' % library) except: + conf["libraryLocation"]="" conf["resourceLocation"]="" if "runOnceBeforeTesting" in conf: @@ -501,6 +503,12 @@ def hashReferenceFiles(s): cmd = [c.replace("$resourceLocation", conf["resourceLocation"]) for c in cmd] subprocess.check_call(cmd, stderr=subprocess.STDOUT) + if "customCommands" in conf: + cmd = conf["runOnceBeforeTesting"] + # replace the $libraryLocation in the customCommands if present + cmd = [c.replace("$libraryLocation", conf["libraryLocation"]) for c in cmd] + conf["customCommands"] = cmd + conf["libraryVersionRevision"]=omc.sendExpression('getVersion(%s)' % library) librarySourceFile=omc.sendExpression('getSourceFile(%s)' % library) lastChange=(librarySourceFile[:-3]+".last_change") if not librarySourceFile.endswith("package.mo") else (os.path.dirname(librarySourceFile)+".last_change") From f655013942b447f15caa13e57a7e0a890ac661d6 Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Mon, 17 Jul 2023 12:49:26 +0200 Subject: [PATCH 163/452] add support for $libraryLocation in JSON config 'extraCustomCommands' --- test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test.py b/test.py index 8561b2b..832f291 100755 --- a/test.py +++ b/test.py @@ -504,7 +504,7 @@ def hashReferenceFiles(s): subprocess.check_call(cmd, stderr=subprocess.STDOUT) if "customCommands" in conf: - cmd = conf["runOnceBeforeTesting"] + cmd = conf["customCommands"] # replace the $libraryLocation in the customCommands if present cmd = [c.replace("$libraryLocation", conf["libraryLocation"]) for c in cmd] conf["customCommands"] = cmd From 35bf0ecdc0ce72c3b3e0f41637f1e91858c35c2f Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Mon, 17 Jul 2023 13:52:06 +0200 Subject: [PATCH 164/452] play with TransiEnt settings --- configs/conf.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/configs/conf.json b/configs/conf.json index f5dd5e6..99c85d3 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -412,7 +412,8 @@ [ "setCommandLineOptions(\"--allowNonStandardModelica=nonStdEnumerationAsIntegers\")", "setEnvironmentVar(\"public-data\", \"$libraryLocation/Tables/\"", - "setEnvironmentVar(\"superstructure-tables\", \"$libraryLocation/Tables/superstructure/Tables\"", + "setEnvironmentVar(\"private-data\", \"$libraryLocation/Tables/\"", + "setEnvironmentVar(\"superstructure-tables\", \"$libraryLocation/Tables/superstructure/Tables/\"", "setEnvironmentVar(\"superstructure-input\", \"$libraryLocation/Tables/superstructure/RegionInformation/\"" ] }, From 0daaec5c59030bcc4d08d0b1f89b5296974a2d96 Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Mon, 17 Jul 2023 16:30:21 +0200 Subject: [PATCH 165/452] fix typo in extraCustomCommands for TransiEnt --- configs/conf.json | 8 ++++---- test.py | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/configs/conf.json b/configs/conf.json index 99c85d3..a6c5f01 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -411,10 +411,10 @@ "extraCustomCommands": [ "setCommandLineOptions(\"--allowNonStandardModelica=nonStdEnumerationAsIntegers\")", - "setEnvironmentVar(\"public-data\", \"$libraryLocation/Tables/\"", - "setEnvironmentVar(\"private-data\", \"$libraryLocation/Tables/\"", - "setEnvironmentVar(\"superstructure-tables\", \"$libraryLocation/Tables/superstructure/Tables/\"", - "setEnvironmentVar(\"superstructure-input\", \"$libraryLocation/Tables/superstructure/RegionInformation/\"" + "setEnvironmentVar(\"public-data\", \"$libraryLocation/Tables/\")", + "setEnvironmentVar(\"private-data\", \"$libraryLocation/Tables/\")", + "setEnvironmentVar(\"superstructure-tables\", \"$libraryLocation/Tables/superstructure/Tables/\")", + "setEnvironmentVar(\"superstructure-input\", \"$libraryLocation/Tables/superstructure/RegionInformation/\")" ] }, { diff --git a/test.py b/test.py index 832f291..3193c32 100755 --- a/test.py +++ b/test.py @@ -501,6 +501,7 @@ def hashReferenceFiles(s): for cmd in conf["runOnceBeforeTesting"]: # replace the resource location in the command if present cmd = [c.replace("$resourceLocation", conf["resourceLocation"]) for c in cmd] + cmd = [c.replace("$libraryLocation", conf["libraryLocation"]) for c in cmd] subprocess.check_call(cmd, stderr=subprocess.STDOUT) if "customCommands" in conf: From 133d0873fde6426b1d71824280f85432e80fc6c5 Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Tue, 18 Jul 2023 13:25:35 +0200 Subject: [PATCH 166/452] add support for setting environment variables for simulation Currently we translate the model using OMPython and then run the executable in a different process which has a different environment. This is a problem if the user sets some environment variable in omc that is suppose to be used by the simulation executable. This commit adds support for specifying some environment [variable, value] pairs in environmentSimulation in JSON. We also support $libraryLocation in the value to be replaced by the actual location of the library on the disk. --- configs/conf.json | 7 +++++++ shared.py | 8 +++++--- test.py | 10 ++++++++++ testmodel.py | 8 ++++++-- 4 files changed, 28 insertions(+), 5 deletions(-) diff --git a/configs/conf.json b/configs/conf.json index a6c5f01..1c1ed2e 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -415,6 +415,13 @@ "setEnvironmentVar(\"private-data\", \"$libraryLocation/Tables/\")", "setEnvironmentVar(\"superstructure-tables\", \"$libraryLocation/Tables/superstructure/Tables/\")", "setEnvironmentVar(\"superstructure-input\", \"$libraryLocation/Tables/superstructure/RegionInformation/\")" + ], + "environmentSimulation": + [ + ["public-data", "$libraryLocation/Tables/"], + ["private-data", "$libraryLocation/Tables/"], + ["superstructure-tables", "$libraryLocation/Tables/superstructure/Tables/"], + ["superstructure-input", "$libraryLocation/Tables/superstructure/RegionInformation/"] ] }, { diff --git a/shared.py b/shared.py index 4eb5b1b..f802a2b 100644 --- a/shared.py +++ b/shared.py @@ -3,7 +3,7 @@ import re, os, subprocess import simplejson as json -def fixData(data,abortSimulationFlag,alarmFlag,overrideDefaults,defaultCustomCommands,extrasimflags): +def fixData(data,abortSimulationFlag,alarmFlag,overrideDefaults,defaultCustomCommands,extrasimflags,environmentTranslation,environmentSimulation): data["configFromFile"] = dict(data) for (key,default) in overrideDefaults: if key not in data: @@ -32,6 +32,8 @@ def fixData(data,abortSimulationFlag,alarmFlag,overrideDefaults,defaultCustomCom if extrasimflags: simflags.append(extrasimflags) data["extraSimFlags"] = " ".join(simflags) # no extra sim flags + data["environmentSimulation"] = data.get("environmentSimulation") + environmentSimulation + data["environmentTranslation"] = data.get("environmentTranslation") + environmentTranslation data["libraryVersion"] = data.get("libraryVersion") or "default" data["libraryVersionLatestInPackageManager"] = data.get("libraryVersionLatestInPackageManager") or False data["alarmFlag"] = data.get("alarmFlag") or (alarmFlag if data["simCodeTarget"]=="C" else "") @@ -43,8 +45,8 @@ def fixData(data,abortSimulationFlag,alarmFlag,overrideDefaults,defaultCustomCom print("Failed to fix data for: %s with extra args: %s" % (str(data),str((abortSimulationFlag,alarmFlag,defaultCustomCommands)))) raise -def readConfig(c,abortSimulationFlag="",alarmFlag="",overrideDefaults=[],defaultCustomCommands=[],extrasimflags=""): - return [fixData(data,abortSimulationFlag,alarmFlag,overrideDefaults,defaultCustomCommands,extrasimflags) for data in json.load(open(c))] +def readConfig(c,abortSimulationFlag="",alarmFlag="",overrideDefaults=[],defaultCustomCommands=[],extrasimflags="",environmentTranslation=[],environmentSimulation=[]): + return [fixData(data,abortSimulationFlag,alarmFlag,overrideDefaults,defaultCustomCommands,extrasimflags,environmentTranslation,environmentSimulation) for data in json.load(open(c))] def libname(library, conf): if "libraryVersionNameForTests" in conf: diff --git a/test.py b/test.py index 3193c32..4d113a6 100755 --- a/test.py +++ b/test.py @@ -509,6 +509,16 @@ def hashReferenceFiles(s): # replace the $libraryLocation in the customCommands if present cmd = [c.replace("$libraryLocation", conf["libraryLocation"]) for c in cmd] conf["customCommands"] = cmd + if "environmentSimulation" in conf: + cmd = conf["environmentSimulation"] + # replace the $libraryLocation in the environmentSimulation if present + cmd = [[el.replace("$libraryLocation", conf["libraryLocation"]) for el in c] for c in cmd] + conf["environmentSimulation"] = cmd + if "environmentTranslation" in conf: + cmd = conf["environmentTranslation"] + # replace the $libraryLocation in the environmentTraslation if present + cmd = [[el.replace("$libraryLocation", conf["libraryLocation"]) for el in c] for c in cmd] + conf["environmentTranslation"] = cmd conf["libraryVersionRevision"]=omc.sendExpression('getVersion(%s)' % library) librarySourceFile=omc.sendExpression('getSourceFile(%s)' % library) diff --git a/testmodel.py b/testmodel.py index 190acf8..1f24ea8 100755 --- a/testmodel.py +++ b/testmodel.py @@ -85,12 +85,16 @@ def target(res): raise TimeoutError(res[1]) return res[0] -def checkOutputTimeout(cmd, timeout): +def checkOutputTimeout(cmd, timeout, envSimulation=[]): with open(errFile, 'a+') as fp: fp.write(cmd + "\n") def target(res): try: - res[0] = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT).decode().strip() + env = os.environ.copy() + # add the enviromentSimulation to the environment + for e in envSimulation: + env[e[0]] = e[1] + res[0] = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, env = env).decode().strip() except subprocess.CalledProcessError as e: outputStr = e.output.decode("utf-8","backslashreplace") res[1] = cmd + " " + outputStr From 1043c6c6c943a17e04fe4c1d1948f7c4c7d9b419 Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Tue, 18 Jul 2023 13:41:56 +0200 Subject: [PATCH 167/452] fix None + list handling --- shared.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/shared.py b/shared.py index f802a2b..75a75a4 100644 --- a/shared.py +++ b/shared.py @@ -32,8 +32,14 @@ def fixData(data,abortSimulationFlag,alarmFlag,overrideDefaults,defaultCustomCom if extrasimflags: simflags.append(extrasimflags) data["extraSimFlags"] = " ".join(simflags) # no extra sim flags - data["environmentSimulation"] = data.get("environmentSimulation") + environmentSimulation - data["environmentTranslation"] = data.get("environmentTranslation") + environmentTranslation + if data.get("environmentSimulation"): + data["environmentSimulation"] = data.get("environmentSimulation") + environmentSimulation + else: + data["environmentSimulation"] = environmentSimulation + if data.get("environmentTranslation"): + data["environmentTranslation"] = data.get("environmentTranslation") + environmentTranslation + else: + data["environmentTranslation"] = environmentTranslation data["libraryVersion"] = data.get("libraryVersion") or "default" data["libraryVersionLatestInPackageManager"] = data.get("libraryVersionLatestInPackageManager") or False data["alarmFlag"] = data.get("alarmFlag") or (alarmFlag if data["simCodeTarget"]=="C" else "") From 6df73c4e5bedbb8fa215e348c90dfaa396e60834 Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Wed, 19 Jul 2023 21:30:48 +0200 Subject: [PATCH 168/452] use the proper environmentSimulation from conf --- testmodel.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/testmodel.py b/testmodel.py index 1f24ea8..bc3ae20 100755 --- a/testmodel.py +++ b/testmodel.py @@ -85,14 +85,14 @@ def target(res): raise TimeoutError(res[1]) return res[0] -def checkOutputTimeout(cmd, timeout, envSimulation=[]): +def checkOutputTimeout(cmd, timeout): with open(errFile, 'a+') as fp: fp.write(cmd + "\n") def target(res): try: env = os.environ.copy() - # add the enviromentSimulation to the environment - for e in envSimulation: + # add the environmentSimulation to the environment + for e in conf["environmentSimulation"]: env[e[0]] = e[1] res[0] = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, env = env).decode().strip() except subprocess.CalledProcessError as e: From 603124d4d2f856e64552f5f3e4a4de8f64276fd2 Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Thu, 20 Jul 2023 15:31:52 +0200 Subject: [PATCH 169/452] write the special environment in the sim log file --- testmodel.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/testmodel.py b/testmodel.py index bc3ae20..370160d 100755 --- a/testmodel.py +++ b/testmodel.py @@ -457,7 +457,10 @@ def sendExpressionOldOrNew(cmd): if conf["simCodeTarget"]=="C": cmd = cmd + " -lv LOG_STATS" with open(simFile,"w") as fp: - fp.write("startTime=%g\nstopTime=%g\ntolerance=%g\nnumberOfIntervals=%d\nstepSize=%g\n" % (startTime,stopTime,tolerance,numberOfIntervals,stepSize)) + fp.write("Environment:\n") + for e in conf["environmentSimulation"]: + fp.write("%s = %s\n" % (e[0], e[1])) + fp.write("startTime=%g\nstopTime=%g\ntolerance=%g\nnumberOfIntervals=%d\nstepSize=%g\n" % (startTime,stopTime,tolerance,numberOfIntervals,stepSize)) fp.write("Regular simulation: %s\n" % cmd) res = checkOutputTimeout("(rm -f %s.pipe ; mkfifo %s.pipe ; head -c 1048576 < %s.pipe >> %s & %s > %s.pipe 2>&1)" % (conf["fileName"],conf["fileName"],conf["fileName"],simFile,cmd,conf["fileName"]), conf["ulimitExe"]) execstat["sim"] = monotonic()-start From 05ac1cdb84ded9c38beba4a3fbbc2fa291609df3 Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Fri, 21 Jul 2023 12:09:10 +0200 Subject: [PATCH 170/452] print the environment of the simulation executable before running it --- testmodel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testmodel.py b/testmodel.py index 370160d..460e1a9 100755 --- a/testmodel.py +++ b/testmodel.py @@ -462,7 +462,7 @@ def sendExpressionOldOrNew(cmd): fp.write("%s = %s\n" % (e[0], e[1])) fp.write("startTime=%g\nstopTime=%g\ntolerance=%g\nnumberOfIntervals=%d\nstepSize=%g\n" % (startTime,stopTime,tolerance,numberOfIntervals,stepSize)) fp.write("Regular simulation: %s\n" % cmd) - res = checkOutputTimeout("(rm -f %s.pipe ; mkfifo %s.pipe ; head -c 1048576 < %s.pipe >> %s & %s > %s.pipe 2>&1)" % (conf["fileName"],conf["fileName"],conf["fileName"],simFile,cmd,conf["fileName"]), conf["ulimitExe"]) + res = checkOutputTimeout("(rm -f %s.pipe ; mkfifo %s.pipe ; head -c 1048576 < %s.pipe >> %s & printenv > %s.pipe ; %s > %s.pipe 2>&1)" % (conf["fileName"],conf["fileName"],conf["fileName"],simFile,cmd,conf["fileName"]), conf["ulimitExe"]) execstat["sim"] = monotonic()-start execstat["phase"] = 6 except TimeoutError as e: From 4ca3dcfe4ead53f4eeffd776dfeabd95f4fc658d Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Fri, 21 Jul 2023 12:17:18 +0200 Subject: [PATCH 171/452] provide the proper numbeer of arguments --- testmodel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testmodel.py b/testmodel.py index 460e1a9..231ab6e 100755 --- a/testmodel.py +++ b/testmodel.py @@ -462,7 +462,7 @@ def sendExpressionOldOrNew(cmd): fp.write("%s = %s\n" % (e[0], e[1])) fp.write("startTime=%g\nstopTime=%g\ntolerance=%g\nnumberOfIntervals=%d\nstepSize=%g\n" % (startTime,stopTime,tolerance,numberOfIntervals,stepSize)) fp.write("Regular simulation: %s\n" % cmd) - res = checkOutputTimeout("(rm -f %s.pipe ; mkfifo %s.pipe ; head -c 1048576 < %s.pipe >> %s & printenv > %s.pipe ; %s > %s.pipe 2>&1)" % (conf["fileName"],conf["fileName"],conf["fileName"],simFile,cmd,conf["fileName"]), conf["ulimitExe"]) + res = checkOutputTimeout("(rm -f %s.pipe ; mkfifo %s.pipe ; head -c 1048576 < %s.pipe >> %s & printenv > %s.pipe ; %s > %s.pipe 2>&1)" % (conf["fileName"],conf["fileName"],conf["fileName"],simFile,conf["fileName"],cmd,conf["fileName"]), conf["ulimitExe"]) execstat["sim"] = monotonic()-start execstat["phase"] = 6 except TimeoutError as e: From 084c32eabf8427fc3fe6d8e3730b7f0da52fdbba Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Fri, 21 Jul 2023 15:44:20 +0200 Subject: [PATCH 172/452] send the conf to checkOutputTimeout --- testmodel.py | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/testmodel.py b/testmodel.py index 231ab6e..bd02473 100755 --- a/testmodel.py +++ b/testmodel.py @@ -85,15 +85,20 @@ def target(res): raise TimeoutError(res[1]) return res[0] -def checkOutputTimeout(cmd, timeout): +def checkOutputTimeout(cmd, timeout, conf=None): with open(errFile, 'a+') as fp: fp.write(cmd + "\n") def target(res): try: env = os.environ.copy() # add the environmentSimulation to the environment - for e in conf["environmentSimulation"]: - env[e[0]] = e[1] + if conf: + for e in conf["environmentSimulation"]: + env[e[0]] = e[1] + with open(errFile, 'a+') as fp: + fp.write("Environment - environmentSimulation:") + for e in conf["environmentSimulation"]: + fp.write(env[e[0]] + "\n") res[0] = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, env = env).decode().strip() except subprocess.CalledProcessError as e: outputStr = e.output.decode("utf-8","backslashreplace") @@ -422,7 +427,7 @@ def sendExpressionOldOrNew(cmd): execstat["phase"] = 5 else: - res = checkOutputTimeout("make -j1 -f %s.makefile" % conf["fileName"], conf["ulimitOmc"]) + res = checkOutputTimeout("make -j1 -f %s.makefile" % conf["fileName"], conf["ulimitOmc"], conf) execstat["build"] = monotonic()-start execstat["phase"] = 5 except TimeoutError as e: @@ -450,19 +455,19 @@ def sendExpressionOldOrNew(cmd): cmd = "%s --tempDir=%s --startTime=%g --stopTime=%g --timeout=%g --tolerance=%g %s.fmu" % (("-r=%s" % resFile) if outputFormat != "empty" else "",fmitmpdir,startTime,stopTime,conf["ulimitExe"],tolerance,conf["fileName"].replace(".","_")) with open(simFile,"w") as fp: fp.write("OMSimulator %s\n" % cmd) - #res = checkOutputTimeout("%s %s >> %s 2>&1" % (conf["fmisimulator"],cmd,simFile), conf["ulimitExe"]) - res = checkOutputTimeout("(rm -f %s.pipe ; mkfifo %s.pipe ; head -c 1048576 < %s.pipe >> %s & %s %s > %s.pipe 2>&1)" % (conf["fileName"],conf["fileName"],conf["fileName"],simFile,conf["fmisimulator"],cmd,conf["fileName"]), 1.05*conf["ulimitExe"]) + #res = checkOutputTimeout("%s %s >> %s 2>&1" % (conf["fmisimulator"],cmd,simFile), conf["ulimitExe"], conf) + res = checkOutputTimeout("(rm -f %s.pipe ; mkfifo %s.pipe ; head -c 1048576 < %s.pipe >> %s & %s %s > %s.pipe 2>&1)" % (conf["fileName"],conf["fileName"],conf["fileName"],simFile,conf["fmisimulator"],cmd,conf["fileName"]), 1.05*conf["ulimitExe"], conf) else: cmd = ("./%s %s %s %s" % (conf["fileName"],annotationSimFlags,conf["simFlags"],emit_protected)).strip() if conf["simCodeTarget"]=="C": cmd = cmd + " -lv LOG_STATS" with open(simFile,"w") as fp: - fp.write("Environment:\n") + fp.write("Environment - simulationEnvironment:\n") for e in conf["environmentSimulation"]: fp.write("%s = %s\n" % (e[0], e[1])) fp.write("startTime=%g\nstopTime=%g\ntolerance=%g\nnumberOfIntervals=%d\nstepSize=%g\n" % (startTime,stopTime,tolerance,numberOfIntervals,stepSize)) fp.write("Regular simulation: %s\n" % cmd) - res = checkOutputTimeout("(rm -f %s.pipe ; mkfifo %s.pipe ; head -c 1048576 < %s.pipe >> %s & printenv > %s.pipe ; %s > %s.pipe 2>&1)" % (conf["fileName"],conf["fileName"],conf["fileName"],simFile,conf["fileName"],cmd,conf["fileName"]), conf["ulimitExe"]) + res = checkOutputTimeout("(rm -f %s.pipe ; mkfifo %s.pipe ; head -c 1048576 < %s.pipe >> %s & printenv > %s.pipe ; %s > %s.pipe 2>&1)" % (conf["fileName"],conf["fileName"],conf["fileName"],simFile,conf["fileName"],cmd,conf["fileName"]), conf["ulimitExe"], conf) execstat["sim"] = monotonic()-start execstat["phase"] = 6 except TimeoutError as e: From fb4147be7c0a9ca404314e1b306d0fc0fdbb1078 Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Sat, 22 Jul 2023 15:42:21 +0200 Subject: [PATCH 173/452] remove the debugging printenv --- testmodel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testmodel.py b/testmodel.py index bd02473..6c5a144 100755 --- a/testmodel.py +++ b/testmodel.py @@ -467,7 +467,7 @@ def sendExpressionOldOrNew(cmd): fp.write("%s = %s\n" % (e[0], e[1])) fp.write("startTime=%g\nstopTime=%g\ntolerance=%g\nnumberOfIntervals=%d\nstepSize=%g\n" % (startTime,stopTime,tolerance,numberOfIntervals,stepSize)) fp.write("Regular simulation: %s\n" % cmd) - res = checkOutputTimeout("(rm -f %s.pipe ; mkfifo %s.pipe ; head -c 1048576 < %s.pipe >> %s & printenv > %s.pipe ; %s > %s.pipe 2>&1)" % (conf["fileName"],conf["fileName"],conf["fileName"],simFile,conf["fileName"],cmd,conf["fileName"]), conf["ulimitExe"], conf) + res = checkOutputTimeout("(rm -f %s.pipe ; mkfifo %s.pipe ; head -c 1048576 < %s.pipe >> %s & %s > %s.pipe 2>&1)" % (conf["fileName"],conf["fileName"],conf["fileName"],simFile,cmd,conf["fileName"]), conf["ulimitExe"], conf) execstat["sim"] = monotonic()-start execstat["phase"] = 6 except TimeoutError as e: From 7ddfb6d5cdaea0e96425a12da9a1c0b5336822aa Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Tue, 25 Jul 2023 15:13:03 +0200 Subject: [PATCH 174/452] environment variable cannot contain dash in POSIX --- configs/conf.json | 16 ++++++++-------- testmodel.py | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/configs/conf.json b/configs/conf.json index 1c1ed2e..b3f479d 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -411,17 +411,17 @@ "extraCustomCommands": [ "setCommandLineOptions(\"--allowNonStandardModelica=nonStdEnumerationAsIntegers\")", - "setEnvironmentVar(\"public-data\", \"$libraryLocation/Tables/\")", - "setEnvironmentVar(\"private-data\", \"$libraryLocation/Tables/\")", - "setEnvironmentVar(\"superstructure-tables\", \"$libraryLocation/Tables/superstructure/Tables/\")", - "setEnvironmentVar(\"superstructure-input\", \"$libraryLocation/Tables/superstructure/RegionInformation/\")" + "setEnvironmentVar(\"publicData\", \"$libraryLocation/Tables/\")", + "setEnvironmentVar(\"privateData\", \"$libraryLocation/Tables/\")", + "setEnvironmentVar(\"superstructureTables\", \"$libraryLocation/Tables/superstructure/Tables/\")", + "setEnvironmentVar(\"superstructureInput\", \"$libraryLocation/Tables/superstructure/RegionInformation/\")" ], "environmentSimulation": [ - ["public-data", "$libraryLocation/Tables/"], - ["private-data", "$libraryLocation/Tables/"], - ["superstructure-tables", "$libraryLocation/Tables/superstructure/Tables/"], - ["superstructure-input", "$libraryLocation/Tables/superstructure/RegionInformation/"] + ["publicData", "$libraryLocation/Tables/"], + ["privateData", "$libraryLocation/Tables/"], + ["superstructureTables", "$libraryLocation/Tables/superstructure/Tables/"], + ["superstructureInput", "$libraryLocation/Tables/superstructure/RegionInformation/"] ] }, { diff --git a/testmodel.py b/testmodel.py index 6c5a144..75140b7 100755 --- a/testmodel.py +++ b/testmodel.py @@ -96,9 +96,9 @@ def target(res): for e in conf["environmentSimulation"]: env[e[0]] = e[1] with open(errFile, 'a+') as fp: - fp.write("Environment - environmentSimulation:") + fp.write("Environment - environmentSimulation:\n") for e in conf["environmentSimulation"]: - fp.write(env[e[0]] + "\n") + fp.write("%s = %s\n " % (e[0], env[e[0]])) res[0] = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, env = env).decode().strip() except subprocess.CalledProcessError as e: outputStr = e.output.decode("utf-8","backslashreplace") From 9aa10d5f1091bb6d6eafb7f5e3cf6c9cfb164acd Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Sat, 29 Jul 2023 16:49:12 +0200 Subject: [PATCH 175/452] remove debug info --- testmodel.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/testmodel.py b/testmodel.py index 75140b7..64f7893 100755 --- a/testmodel.py +++ b/testmodel.py @@ -95,10 +95,6 @@ def target(res): if conf: for e in conf["environmentSimulation"]: env[e[0]] = e[1] - with open(errFile, 'a+') as fp: - fp.write("Environment - environmentSimulation:\n") - for e in conf["environmentSimulation"]: - fp.write("%s = %s\n " % (e[0], env[e[0]])) res[0] = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT, env = env).decode().strip() except subprocess.CalledProcessError as e: outputStr = e.output.decode("utf-8","backslashreplace") From 2936f22a5e9eb27c5a169ad2e77715d15fa0d6bc Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Fri, 11 Aug 2023 14:36:42 +0200 Subject: [PATCH 176/452] allow non standard top level outer in Transient --- configs/conf.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/conf.json b/configs/conf.json index b3f479d..5c40ca3 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -410,7 +410,7 @@ "libraryVersionNameForTests":"", "extraCustomCommands": [ - "setCommandLineOptions(\"--allowNonStandardModelica=nonStdEnumerationAsIntegers\")", + "setCommandLineOptions(\"--allowNonStandardModelica=nonStdEnumerationAsIntegers,nonStdTopLevelOuter\")", "setEnvironmentVar(\"publicData\", \"$libraryLocation/Tables/\")", "setEnvironmentVar(\"privateData\", \"$libraryLocation/Tables/\")", "setEnvironmentVar(\"superstructureTables\", \"$libraryLocation/Tables/superstructure/Tables/\")", From edcf74f06850a5ec77d08515339913b7cd264c30 Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Mon, 14 Aug 2023 10:25:05 +0200 Subject: [PATCH 177/452] add Greenhouses library to the testing --- configs/conf.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/configs/conf.json b/configs/conf.json index 5c40ca3..e4acf67 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -210,11 +210,16 @@ { "library":"FastBuildings" }, - { + { "library":"FluxTubesExtension", "libraryVersion":"main", "libraryVersionNameForTests":"" }, + { + "library":"Greenhouses", + "libraryVersion":"master", + "libraryVersionNameForTests":"" + }, { "library":"HanserModelica" }, From 3cc82eb4cf8d922e610cec5da07009dd0aefe733 Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Mon, 14 Aug 2023 13:30:46 +0200 Subject: [PATCH 178/452] install Greenhouses library for testing --- .CI/installLibraries.mos | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.CI/installLibraries.mos b/.CI/installLibraries.mos index fddfc68..ac70a41 100644 --- a/.CI/installLibraries.mos +++ b/.CI/installLibraries.mos @@ -16,7 +16,7 @@ for v in {"1.6", "3.0.0", "maint.7.0.x", "maint.8.1.x", "maint.9.1.x", "master"} end if; end for; -for lib in {"AdvancedNoise", "BioChem", "BuildingSystems", "BuildSysPro", "Chemical", "ClaRa_Obsolete", "ClaRa", "ConPNlib", "ElectricalEnergyStorage", "ExternData", "ExternalMemoryLib", "FastBuildings", "FCSys", "HanserModelica", "HelmholtzMedia", "IBPSA", "IdealizedContact", "IndustrialControlSystems", "KeyWordIO", "LargeTestSuite", "LibRAS", "MEV", "MessagePack", "ModelicaByExample", "ModelicaTestOverdetermined", "Modelica_Synchronous", "Modelica_DeviceDrivers", "Modelica_LinearSystems2", "Modelica_Noise", "ObjectStab", "OpenHydraulics", "OpenIPSL", "PNlib", "Physiolibrary", "PlanarMechanics", "PowerSysPro", "ScalableTestGrids", "ScalableTestSuite", "SolarTherm", "Spot", "SystemDynamics", "TAeZoSysPro", "TAeZoSysPro_testsuite", "ThermalSeparation", "ThermoPower", "ThermoSysPro", "TransiEnt", "VehicleInterfaces"} loop +for lib in {"AdvancedNoise", "BioChem", "BuildingSystems", "BuildSysPro", "Chemical", "ClaRa_Obsolete", "ClaRa", "ConPNlib", "ElectricalEnergyStorage", "ExternData", "ExternalMemoryLib", "FastBuildings", "FCSys", "Greenhouses", "HanserModelica", "HelmholtzMedia", "IBPSA", "IdealizedContact", "IndustrialControlSystems", "KeyWordIO", "LargeTestSuite", "LibRAS", "MEV", "MessagePack", "ModelicaByExample", "ModelicaTestOverdetermined", "Modelica_Synchronous", "Modelica_DeviceDrivers", "Modelica_LinearSystems2", "Modelica_Noise", "ObjectStab", "OpenHydraulics", "OpenIPSL", "PNlib", "Physiolibrary", "PlanarMechanics", "PowerSysPro", "ScalableTestGrids", "ScalableTestSuite", "SolarTherm", "Spot", "SystemDynamics", "TAeZoSysPro", "TAeZoSysPro_testsuite", "ThermalSeparation", "ThermoPower", "ThermoSysPro", "TransiEnt", "VehicleInterfaces"} loop if not installPackage(stringTypeName(lib), "master") then print(lib + " " + getErrorString() + "\n"); exit(1); From ba2db2a5233b5980a4323ee7907b61fe364cef52 Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Tue, 15 Aug 2023 10:50:09 +0200 Subject: [PATCH 179/452] update the way OMSimulator is built --- .CI/Jenkinsfile | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index d7469a4..4e61922 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -831,16 +831,15 @@ def runRegressiontest(branch, name, extraFlags, omsHash, dbPrefix, sshConfig, om git submodule update || exit 1 git clean -fdx || exit 1 git submodule foreach --recursive "git fetch --tags && git reset --hard && git clean -fdxq -e /git -e /svn" || exit 1 - make config-3rdParty || exit 1 - make config-OMSimulator || exit 1 - make OMSimulator || exit 1 + cmake --build build/ --target install || exit 1 + ./install/OMSimulator --version || exit 1 mkdir -p ~/saved_omc/OMSimulator || exit 1 cp -a * ~/saved_omc/OMSimulator/ || exit 1 git rev-parse HEAD > ~/saved_omc/OMSimulator/.githash || exit 1 fi """ - FMI_TESTING_FLAG="--fmi=true --fmisimulator=${env.HOME}/saved_omc/OMSimulator/install/linux/bin/OMSimulator --default=ulimitExe=50" + FMI_TESTING_FLAG="--fmi=true --fmisimulator=${env.HOME}/saved_omc/OMSimulator/install/OMSimulator --default=ulimitExe=50" } OMCPATH = "${omcompiler ? '../' : './'}OMCompiler" From a234b1d4c83845846e2fe40f1280743785d20d47 Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Tue, 15 Aug 2023 10:59:28 +0200 Subject: [PATCH 180/452] create the ./build directory for cmake as it is shy and cannot do it itself --- .CI/Jenkinsfile | 1 + 1 file changed, 1 insertion(+) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index 4e61922..c4520a9 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -831,6 +831,7 @@ def runRegressiontest(branch, name, extraFlags, omsHash, dbPrefix, sshConfig, om git submodule update || exit 1 git clean -fdx || exit 1 git submodule foreach --recursive "git fetch --tags && git reset --hard && git clean -fdxq -e /git -e /svn" || exit 1 + mkdir -p build || exit 1 cmake --build build/ --target install || exit 1 ./install/OMSimulator --version || exit 1 mkdir -p ~/saved_omc/OMSimulator || exit 1 From 142e33cd4cb289585ceef24287dd63dd8bb404e3 Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Tue, 15 Aug 2023 11:13:52 +0200 Subject: [PATCH 181/452] forgot to configure OMSimulator fist, nevermind my previous commit --- .CI/Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index c4520a9..e252fc3 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -831,7 +831,7 @@ def runRegressiontest(branch, name, extraFlags, omsHash, dbPrefix, sshConfig, om git submodule update || exit 1 git clean -fdx || exit 1 git submodule foreach --recursive "git fetch --tags && git reset --hard && git clean -fdxq -e /git -e /svn" || exit 1 - mkdir -p build || exit 1 + cmake -S . -B build/ -DCMAKE_INSTALL_PREFIX=install/ cmake --build build/ --target install || exit 1 ./install/OMSimulator --version || exit 1 mkdir -p ~/saved_omc/OMSimulator || exit 1 From 66735435f673e4ebc55a7a6408dfc7d15e544f20 Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Tue, 15 Aug 2023 11:19:52 +0200 Subject: [PATCH 182/452] cmake installs OMSimulator in ./install/bin --- .CI/Jenkinsfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index e252fc3..26680a6 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -833,14 +833,14 @@ def runRegressiontest(branch, name, extraFlags, omsHash, dbPrefix, sshConfig, om git submodule foreach --recursive "git fetch --tags && git reset --hard && git clean -fdxq -e /git -e /svn" || exit 1 cmake -S . -B build/ -DCMAKE_INSTALL_PREFIX=install/ cmake --build build/ --target install || exit 1 - ./install/OMSimulator --version || exit 1 + ./install/biin/OMSimulator --version || exit 1 mkdir -p ~/saved_omc/OMSimulator || exit 1 cp -a * ~/saved_omc/OMSimulator/ || exit 1 git rev-parse HEAD > ~/saved_omc/OMSimulator/.githash || exit 1 fi """ - FMI_TESTING_FLAG="--fmi=true --fmisimulator=${env.HOME}/saved_omc/OMSimulator/install/OMSimulator --default=ulimitExe=50" + FMI_TESTING_FLAG="--fmi=true --fmisimulator=${env.HOME}/saved_omc/OMSimulator/install/bin/OMSimulator --default=ulimitExe=50" } OMCPATH = "${omcompiler ? '../' : './'}OMCompiler" From 0032bca1ffde674989c7cb99472e3b4f4190ba95 Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Tue, 15 Aug 2023 11:22:32 +0200 Subject: [PATCH 183/452] fix typo --- .CI/Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index 26680a6..466f833 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -833,7 +833,7 @@ def runRegressiontest(branch, name, extraFlags, omsHash, dbPrefix, sshConfig, om git submodule foreach --recursive "git fetch --tags && git reset --hard && git clean -fdxq -e /git -e /svn" || exit 1 cmake -S . -B build/ -DCMAKE_INSTALL_PREFIX=install/ cmake --build build/ --target install || exit 1 - ./install/biin/OMSimulator --version || exit 1 + ./install/bin/OMSimulator --version || exit 1 mkdir -p ~/saved_omc/OMSimulator || exit 1 cp -a * ~/saved_omc/OMSimulator/ || exit 1 git rev-parse HEAD > ~/saved_omc/OMSimulator/.githash || exit 1 From 680d9f69aa2e9a12d3ec9a2ef677cc2370bd4540 Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Wed, 30 Aug 2023 22:05:17 +0200 Subject: [PATCH 184/452] add OpenIMDML library for testing --- .CI/installLibraries.mos | 1 + configs/conf.json | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/.CI/installLibraries.mos b/.CI/installLibraries.mos index ac70a41..1fac2f4 100644 --- a/.CI/installLibraries.mos +++ b/.CI/installLibraries.mos @@ -39,6 +39,7 @@ for l in { {"IDEAS", "master"}, {"iPSL", ""}, {"MagLev", ""}, + {"OpenIMDML", "main"}, {"OpenIPSL", "2.0.0"}, {"OpenIPSL", ""}, {"OpenIPSL", "master"}, diff --git a/configs/conf.json b/configs/conf.json index e4acf67..2a1ed02 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -264,6 +264,10 @@ "libraryVersion":"master", "libraryVersionNameForTests":"" }, + { + "library":"OpenIMDML", + "libraryVersion":"main" + }, { "library":"OpenIPSL", "libraryVersion":"2.0.0" From beeb45c3d425f28e64d50b81dac4e31ea7b23ffd Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Fri, 15 Sep 2023 18:17:15 +0200 Subject: [PATCH 185/452] Update conf.json Added EHPT libraries by Massimo Ceraolo --- configs/conf.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/configs/conf.json b/configs/conf.json index 2a1ed02..952b608 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -194,6 +194,14 @@ "library":"DroneLibrary", "libraryVersionNameForTests":"" }, + { + "library":"EHPTexamples", + "libraryVersion":"main" + }, + { + "library":"EHPTlib", + "libraryVersion":"main" + }, { "library":"ElectricalEnergyStorage" }, From 0a0cd8d8b5bb5db82ff44b4dd924ee9570542ca7 Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Fri, 15 Sep 2023 18:19:13 +0200 Subject: [PATCH 186/452] Update installLibraries.mos Added EHPT libraries by Massimo Ceraolo --- .CI/installLibraries.mos | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.CI/installLibraries.mos b/.CI/installLibraries.mos index 1fac2f4..cc54017 100644 --- a/.CI/installLibraries.mos +++ b/.CI/installLibraries.mos @@ -32,6 +32,8 @@ for l in { {"Credibility", ""}, {"DeltaRobot", ""}, {"DroneLibrary", ""}, + {"EHTPexamples", "main"}, + {"EHTPlib", "main"}, {"ExtendedPetriNets", ""}, {"ExternalMedia",""}, {"FluxTubesExtension","main"}, From 601e692a6e13b05f7bc0d97b3fa6cd4335b81133 Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Sat, 16 Sep 2023 14:36:01 +0200 Subject: [PATCH 187/452] update ClaRa and ClaRa_Obsolete --- .CI/installLibraries.mos | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.CI/installLibraries.mos b/.CI/installLibraries.mos index cc54017..b89a40d 100644 --- a/.CI/installLibraries.mos +++ b/.CI/installLibraries.mos @@ -16,7 +16,7 @@ for v in {"1.6", "3.0.0", "maint.7.0.x", "maint.8.1.x", "maint.9.1.x", "master"} end if; end for; -for lib in {"AdvancedNoise", "BioChem", "BuildingSystems", "BuildSysPro", "Chemical", "ClaRa_Obsolete", "ClaRa", "ConPNlib", "ElectricalEnergyStorage", "ExternData", "ExternalMemoryLib", "FastBuildings", "FCSys", "Greenhouses", "HanserModelica", "HelmholtzMedia", "IBPSA", "IdealizedContact", "IndustrialControlSystems", "KeyWordIO", "LargeTestSuite", "LibRAS", "MEV", "MessagePack", "ModelicaByExample", "ModelicaTestOverdetermined", "Modelica_Synchronous", "Modelica_DeviceDrivers", "Modelica_LinearSystems2", "Modelica_Noise", "ObjectStab", "OpenHydraulics", "OpenIPSL", "PNlib", "Physiolibrary", "PlanarMechanics", "PowerSysPro", "ScalableTestGrids", "ScalableTestSuite", "SolarTherm", "Spot", "SystemDynamics", "TAeZoSysPro", "TAeZoSysPro_testsuite", "ThermalSeparation", "ThermoPower", "ThermoSysPro", "TransiEnt", "VehicleInterfaces"} loop +for lib in {"AdvancedNoise", "BioChem", "BuildingSystems", "BuildSysPro", "Chemical", "ConPNlib", "ElectricalEnergyStorage", "ExternData", "ExternalMemoryLib", "FastBuildings", "FCSys", "Greenhouses", "HanserModelica", "HelmholtzMedia", "IBPSA", "IdealizedContact", "IndustrialControlSystems", "KeyWordIO", "LargeTestSuite", "LibRAS", "MEV", "MessagePack", "ModelicaByExample", "ModelicaTestOverdetermined", "Modelica_Synchronous", "Modelica_DeviceDrivers", "Modelica_LinearSystems2", "Modelica_Noise", "ObjectStab", "OpenHydraulics", "OpenIPSL", "PNlib", "Physiolibrary", "PlanarMechanics", "PowerSysPro", "ScalableTestGrids", "ScalableTestSuite", "SolarTherm", "Spot", "SystemDynamics", "TAeZoSysPro", "TAeZoSysPro_testsuite", "ThermalSeparation", "ThermoPower", "ThermoSysPro", "TransiEnt", "VehicleInterfaces"} loop if not installPackage(stringTypeName(lib), "master") then print(lib + " " + getErrorString() + "\n"); exit(1); @@ -58,7 +58,9 @@ for l in { {"Modelica_StateGraph2", ""}, {"Physiomodel", ""}, {"ThermofluidStream", "main"}, - {"TILMedia", "main"} + {"TILMedia", "main"}, + {"ClaRa_Obsolete", "main"}, + {"ClaRa", "main"} } loop if not installPackage(stringTypeName(l[1]), l[2]) then print(l[1] + " " + l[2] + getErrorString() + "\n"); From 814bf245d528d4b38245cf76034fa8728516be8e Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Sat, 16 Sep 2023 16:40:42 +0200 Subject: [PATCH 188/452] remove the special loading for ClaRa --- configs/conf.json | 4 ---- 1 file changed, 4 deletions(-) diff --git a/configs/conf.json b/configs/conf.json index 952b608..dde8a2e 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -176,10 +176,6 @@ { "library":"ClaRa", "libraryVersionNameForTests":"dev", - "loadFileCommands":[ - "loadModel(TILMedia, {\"main\"})", - "loadFile(\"/mnt/ReferenceFiles/ExtraLibs/packaged/ClaRa/package.mo\")" - ], "referenceFileExtension":"mat", "referenceFileNameDelimiter":".", "referenceFiles":"/mnt/ReferenceFiles/ExtraLibs/clara_om.git/ReferenceResults" From 5a71cc63211d9363eefea6a8cd816739af540d2f Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Sat, 16 Sep 2023 17:45:39 +0200 Subject: [PATCH 189/452] fix typo: is PT not TP --- .CI/installLibraries.mos | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.CI/installLibraries.mos b/.CI/installLibraries.mos index b89a40d..95d927b 100644 --- a/.CI/installLibraries.mos +++ b/.CI/installLibraries.mos @@ -32,8 +32,8 @@ for l in { {"Credibility", ""}, {"DeltaRobot", ""}, {"DroneLibrary", ""}, - {"EHTPexamples", "main"}, - {"EHTPlib", "main"}, + {"EHPTexamples", "main"}, + {"EHPTlib", "main"}, {"ExtendedPetriNets", ""}, {"ExternalMedia",""}, {"FluxTubesExtension","main"}, From d651fd239b52ece015e71457b3387b99b4f0c2e8 Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Thu, 28 Sep 2023 10:22:20 +0200 Subject: [PATCH 190/452] add v1.22 for testing --- .CI/Jenkinsfile | 64 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 58 insertions(+), 6 deletions(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index 466f833..2732d40 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -12,6 +12,7 @@ pipeline { booleanParam(name: 'v1_19', defaultValue: false, description: 'maintenance/v1.19 branch (ryzen-5950x-1)') booleanParam(name: 'v1_20', defaultValue: false, description: 'maintenance/v1.20 branch (ryzen-5950x-1)') booleanParam(name: 'v1_21', defaultValue: false, description: 'maintenance/v1.21 branch (ryzen-5950x-1)') + booleanParam(name: 'v1_22', defaultValue: false, description: 'maintenance/v1.22 branch (ryzen-5950x-1)') booleanParam(name: 'master', defaultValue: false, description: 'master branch (ryzen-5950x-1)') booleanParam(name: 'fmi_v1_12', defaultValue: false, description: 'maintenance/v1.12 branch with FMI (ryzen-5950x-2)') @@ -23,6 +24,7 @@ pipeline { booleanParam(name: 'fmi_v1_19', defaultValue: false, description: 'maintenance/v1.19 branch with FMI (ryzen-5950x-2)') booleanParam(name: 'fmi_v1_20', defaultValue: false, description: 'maintenance/v1.20 branch with FMI (ryzen-5950x-2)') booleanParam(name: 'fmi_v1_21', defaultValue: false, description: 'maintenance/v1.21 branch with FMI (ryzen-5950x-2)') + booleanParam(name: 'fmi_v1_22', defaultValue: false, description: 'maintenance/v1.22 branch with FMI (ryzen-5950x-2)') booleanParam(name: 'fmi_master', defaultValue: false, description: 'master branch with FMI (ryzen-5950x-2)') booleanParam(name: 'newInst_daeMode', defaultValue: false, description: 'master branch, --daeMode with -d=newInst (ryzen-5950x-2)') booleanParam(name: 'newInst_newBackend', defaultValue: false, description: 'master branch, -d=newInst --newBackend, (ryzen-5950x-1)') @@ -31,6 +33,7 @@ pipeline { booleanParam(name: 'cpp_v1_19', defaultValue: false, description: 'maintenance/v1.19 branch, with --simCodeTarget=Cpp (ryzen-5950x-2).') booleanParam(name: 'cpp_v1_20', defaultValue: false, description: 'maintenance/v1.20 branch, with --simCodeTarget=Cpp (ryzen-5950x-2).') booleanParam(name: 'cpp_v1_21', defaultValue: false, description: 'maintenance/v1.21 branch, with --simCodeTarget=Cpp (ryzen-5950x-2).') + booleanParam(name: 'cpp_v1_22', defaultValue: false, description: 'maintenance/v1.22 branch, with --simCodeTarget=Cpp (ryzen-5950x-2).') booleanParam(name: 'cpp', defaultValue: false, description: 'master branch, with --simCodeTarget=Cpp (ryzen-5950x-2).') booleanParam(name: 'report_ryzen_5950x_1', defaultValue: false, description: 'Generate a report for ryzen-5950x-1 without running the tests') booleanParam(name: 'report_ryzen_5950x_2', defaultValue: false, description: 'Generate a report for ryzen-5950x-2 without running the tests') @@ -200,6 +203,23 @@ pipeline { } } + stage('v1.22') { + agent { + node { + label 'ryzen-5950x-1' + customWorkspace 'ws/OpenModelicaLibraryTestingWork' + } + } + options { skipDefaultCheckout() } + when { + beforeAgent true + expression { params.v1_22 } + } + steps { + runRegressiontest('maintenance/v1.22', 'v1.22', '', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', false, false) + } + } + stage('master') { agent { node { @@ -395,6 +415,22 @@ pipeline { runRegressiontest('maintenance/v1.21', 'v1.21-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) } } + stage('v1.22 FMI') { + agent { + node { + label 'ryzen-5950x-2-1' + customWorkspace 'ws/OpenModelicaLibraryTestingWork' + } + } + options { skipDefaultCheckout() } + when { + beforeAgent true + expression { params.fmi_v1_22 } + } + steps { + runRegressiontest('maintenance/v1.22', 'v1.22-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) + } + } stage('master FMI') { agent { node { @@ -571,6 +607,22 @@ pipeline { runRegressiontest('maintenance/v1.21', 'v1.21-cpp', 'setCommandLineOptions("--simCodeTarget=Cpp")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) } } + stage('C++ v1.22') { + agent { + node { + label 'ryzen-5950x-2-1' + customWorkspace 'ws/OpenModelicaLibraryTestingWork' + } + } + options { skipDefaultCheckout() } + when { + beforeAgent true + expression { params.cpp_v1_22 } + } + steps { + runRegressiontest('maintenance/v1.22', 'v1.22-cpp', 'setCommandLineOptions("--simCodeTarget=Cpp")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) + } + } stage('C++') { agent { node { @@ -600,10 +652,10 @@ pipeline { } when { beforeAgent true - expression { params.v1_12 || params.v1_13 || params.v1_14 || params.v1_16 || params.v1_17 || params.v1_18 || params.v1_19 || params.v1_20 || params.v1_21 || params.master || params.conversion_script || params.report_ryzen_5950x_1 | params.newInst_newBackend || params.generateSymbolicJacobian || params.heavy_tests} + expression { params.v1_12 || params.v1_13 || params.v1_14 || params.v1_16 || params.v1_17 || params.v1_18 || params.v1_19 || params.v1_20 || params.v1_21 || params.v1_22 || params.master || params.conversion_script || params.report_ryzen_5950x_1 | params.newInst_newBackend || params.generateSymbolicJacobian || params.heavy_tests} } environment { - GITBRANCHES = 'maintenance/v1.12 maintenance/v1.13 maintenance/v1.14 maintenance/v1.16 maintenance/v1.17 maintenance/v1.18 maintenance/v1.19 maintenance/v1.20 maintenance/v1.21 master' + GITBRANCHES = 'maintenance/v1.12 maintenance/v1.13 maintenance/v1.14 maintenance/v1.16 maintenance/v1.17 maintenance/v1.18 maintenance/v1.19 maintenance/v1.20 maintenance/v1.21 maintenance/v1.22 master' PYTHONIOENCODING = 'utf-8' IDA_EMAIL = credentials('IDA email') } @@ -659,13 +711,13 @@ pipeline { } when { beforeAgent true - expression { params.fmi_v1_12 || params.fmi_v1_13 || params.fmi_v1_14 || params.fmi_v1_16 || params.fmi_v1_17 || params.fmi_v1_18 || params.fmi_v1_19 || params.fmi_v1_20 || params.fmi_v1_21 || params.fmi_master || params.newInst_daeMode || params.oldInst || params.report_ryzen_5950x_2 || params.cpp || params.cvode || params.gbode} + expression { params.fmi_v1_12 || params.fmi_v1_13 || params.fmi_v1_14 || params.fmi_v1_16 || params.fmi_v1_17 || params.fmi_v1_18 || params.fmi_v1_19 || params.fmi_v1_20 || params.fmi_v1_21 || params.fmi_v1_22 ||params.fmi_master || params.newInst_daeMode || params.oldInst || params.report_ryzen_5950x_2 || params.cpp || params.cvode || params.gbode} } environment { - GITBRANCHES_FMI = 'maintenance/v1.12-fmi maintenance/v1.13-fmi maintenance/v1.14-fmi maintenance/v1.16-fmi maintenance/v1.17-fmi maintenance/v1.18-fmi maintenance/v1.19-fmi maintenance/v1.20-fmi maintenance/v1.21-fmi master-fmi' + GITBRANCHES_FMI = 'maintenance/v1.12-fmi maintenance/v1.13-fmi maintenance/v1.14-fmi maintenance/v1.16-fmi maintenance/v1.17-fmi maintenance/v1.18-fmi maintenance/v1.19-fmi maintenance/v1.20-fmi maintenance/v1.21-fmi maintenance/v1.22-fmi master-fmi' GITBRANCHES_NEWINST = 'oldInst' GITBRANCHES_DAE = 'newInst-daeMode' - GITBRANCHES_CPP = 'v1.19-cpp v1.20-cpp v1.21-cpp cpp' + GITBRANCHES_CPP = 'v1.19-cpp v1.20-cpp v1.21-cpp v1.22-cpp cpp' PYTHONIOENCODING = 'utf-8' IDA_EMAIL = credentials('IDA email') } @@ -739,7 +791,7 @@ pipeline { } when { beforeAgent true - expression { params.v1_12 || params.v1_13 || params.v1_14 || params.v1_16 || params.v1_17 || params.v1_18 || params.v1_19 || params.v1_20 || params.v1_21 || params.master || params.report_ripper1 || params.generateSymbolicJacobian } + expression { params.v1_12 || params.v1_13 || params.v1_14 || params.v1_16 || params.v1_17 || params.v1_18 || params.v1_19 || params.v1_20 || params.v1_21 || params.v1_22 ||params.master || params.report_ripper1 || params.generateSymbolicJacobian } } steps { sh 'cp ~/TEST_LIBS_BACKUP/ripper1-sqlite3.db sqlite3.db' From f1b2023f0e86492fc793696935effcdbd4bd8c4e Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Sat, 30 Sep 2023 00:02:10 +0200 Subject: [PATCH 191/452] ScalableTestSuite and LargeTestSuite again --- configs/heavy_tests.json | 38 +++++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/configs/heavy_tests.json b/configs/heavy_tests.json index a57ef97..3f43986 100644 --- a/configs/heavy_tests.json +++ b/configs/heavy_tests.json @@ -1,21 +1,45 @@ [ { - "library":"LargeTestSuite", + "library":"ScalableTestSuite", + "libraryVersion":"master", + "libraryVersionNameForTests":"OB", + "ulimitOmc":400, + "ulimitExe":600, + "ulimitMemory":62914560, + "optlevel":"-O0 -march=native", + "referenceFileExtension":"mat", + "referenceFileNameDelimiter":".", + "referenceFinalDot":"_res.", + "referenceFiles":{ + "giturl":"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/casella/ScalableTestSuite-ref", + "destination":"ReferenceFiles/ScalableTestSuite" + } + }, + { + "library":"ScalableTestSuite", "libraryVersion":"master", "libraryVersionNameForTests":"NB", - "ulimitOmc":1800, - "ulimitExe":800, + "ulimitOmc":400, + "ulimitExe":600, "ulimitMemory":62914560, "optlevel":"-Ofast -march=native", + "referenceFileExtension":"mat", + "referenceFileNameDelimiter":".", + "referenceFinalDot":"_res.", + "referenceFiles":{ + "giturl":"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/casella/ScalableTestSuite-ref", + "destination":"ReferenceFiles/ScalableTestSuite" + }, "extraCustomCommands":["setCommandLineOptions(\"--newBackend\")"] }, { "library":"LargeTestSuite", "libraryVersion":"master", - "libraryVersionNameForTests":"OB", - "ulimitOmc":1800, - "ulimitExe":800, + "libraryVersionNameForTests":"NB", + "ulimitOmc":300, + "ulimitExe":600, "ulimitMemory":62914560, - "optlevel":"-O0 -march=native" + "optlevel":"-Ofast -march=native", + "extraCustomCommands":["setCommandLineOptions(\"--newBackend\")"] } ] From 34ed05b2c4aa3b3001cf3b560df49254e50d24a5 Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Sat, 4 Nov 2023 17:02:08 +0100 Subject: [PATCH 192/452] update the omsimulatorHash() to build with the new docker images --- .CI/Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index 2732d40..de16af6 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -819,7 +819,7 @@ pipeline { } } def omsimulatorHash() { - return '1552061d5fe27ecfa51f5289909717192b102263' + return '634b0193a3eb14e75622a8e720bf0fb6dab77487' } def installLibraries(boolean removePackageOrder, boolean conversionScript, name, String omhomeTestedOMC) { sh "rm -rf '${env.HOME}/saved_omc/libraries/.openmodelica/libraries'" From bd8d50e5cfc2fe6f9eb6b563b3bd321b1b48930f Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Wed, 8 Nov 2023 23:20:54 +0100 Subject: [PATCH 193/452] Split EHPT testing --- configs/conf.json | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/configs/conf.json b/configs/conf.json index dde8a2e..fa402b9 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -190,13 +190,21 @@ "library":"DroneLibrary", "libraryVersionNameForTests":"" }, + { + "library":"EHPTexamples" + }, { "library":"EHPTexamples", - "libraryVersion":"main" + "libraryVersion":"main", + "libraryVersionNameForTests":"latest" + }, + { + "library":"EHPTlib" }, { "library":"EHPTlib", - "libraryVersion":"main" + "libraryVersion":"main", + "libraryVersionNameForTests":"latest" }, { "library":"ElectricalEnergyStorage" From d7e798e194ae9faabcad6b96ac04adfa57d7ce59 Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Wed, 8 Nov 2023 23:24:58 +0100 Subject: [PATCH 194/452] Split EHPT libraries --- .CI/installLibraries.mos | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.CI/installLibraries.mos b/.CI/installLibraries.mos index 95d927b..3567619 100644 --- a/.CI/installLibraries.mos +++ b/.CI/installLibraries.mos @@ -32,7 +32,9 @@ for l in { {"Credibility", ""}, {"DeltaRobot", ""}, {"DroneLibrary", ""}, + {"EHPTexamples", ""}, {"EHPTexamples", "main"}, + {"EHPTlib", ""}, {"EHPTlib", "main"}, {"ExtendedPetriNets", ""}, {"ExternalMedia",""}, From f7924bad3ec02b89fa7d6f51dc44b2ec1b3ba58f Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Mon, 20 Nov 2023 13:03:42 +0100 Subject: [PATCH 195/452] Fixed ClaRa testing --- configs/conf.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/configs/conf.json b/configs/conf.json index fa402b9..6870107 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -171,10 +171,14 @@ "library":"Chemical" }, { - "library":"ClaRa" + "library":"ClaRa", + "referenceFileExtension":"mat", + "referenceFileNameDelimiter":".", + "referenceFiles":"/mnt/ReferenceFiles/ExtraLibs/clara_om.git/ReferenceResults" }, { "library":"ClaRa", + "libraryVersion":"main", "libraryVersionNameForTests":"dev", "referenceFileExtension":"mat", "referenceFileNameDelimiter":".", From 99cf38136ae0731bc41b88b614b6e9bcf0f07239 Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Tue, 21 Nov 2023 13:04:00 +0200 Subject: [PATCH 196/452] add support to test with FMPy instead of OMSimulator (#48) --- .CI/Jenkinsfile | 71 +++++++++++++++++++++++++++++++--------- .CI/build-dep/Dockerfile | 2 +- shared.py | 5 +++ test.py | 8 +++-- testmodel.py | 13 +++++--- 5 files changed, 77 insertions(+), 22 deletions(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index de16af6..7d2ee79 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -25,7 +25,9 @@ pipeline { booleanParam(name: 'fmi_v1_20', defaultValue: false, description: 'maintenance/v1.20 branch with FMI (ryzen-5950x-2)') booleanParam(name: 'fmi_v1_21', defaultValue: false, description: 'maintenance/v1.21 branch with FMI (ryzen-5950x-2)') booleanParam(name: 'fmi_v1_22', defaultValue: false, description: 'maintenance/v1.22 branch with FMI (ryzen-5950x-2)') - booleanParam(name: 'fmi_master', defaultValue: false, description: 'master branch with FMI (ryzen-5950x-2)') + booleanParam(name: 'fmi_master', defaultValue: false, description: 'master branch with FMI running OMSimulator (ryzen-5950x-2)') + booleanParam(name: 'fmpy_fmi_v1_22', defaultValue: false, description: 'maintenance/v1.22 branch with FMI (ryzen-5950x-2)') + booleanParam(name: 'fmpy_fmi_master', defaultValue: false, description: 'master branch with FMI running FMPy (ryzen-5950x-2)') booleanParam(name: 'newInst_daeMode', defaultValue: false, description: 'master branch, --daeMode with -d=newInst (ryzen-5950x-2)') booleanParam(name: 'newInst_newBackend', defaultValue: false, description: 'master branch, -d=newInst --newBackend, (ryzen-5950x-1)') booleanParam(name: 'oldInst', defaultValue: false, description: 'master branch, with -d=nonewInst (ryzen-5950x-2)') @@ -271,7 +273,7 @@ pipeline { } } - stage('v1.12 FMI') { + stage('v1.12 FMI with OMSimulator') { agent { node { label 'ryzen-5950x-2-1' @@ -287,7 +289,7 @@ pipeline { runRegressiontest('maintenance/v1.12', 'v1.12-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', true, '', true, false) } } - stage('v1.13 FMI') { + stage('v1.13 FMI with OMSimulator') { agent { node { label 'ryzen-5950x-2-1' @@ -303,7 +305,7 @@ pipeline { runRegressiontest('maintenance/v1.13', 'v1.13-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', true, '', true, false) } } - stage('v1.14 FMI') { + stage('v1.14 FMI with OMSimulator') { agent { node { label 'ryzen-5950x-2-1' @@ -319,7 +321,7 @@ pipeline { runRegressiontest('maintenance/v1.14', 'v1.14-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', false, '', true, false) } } - stage('v1.16 FMI') { + stage('v1.16 FMI with OMSimulator') { agent { node { label 'ryzen-5950x-2-1' @@ -335,7 +337,7 @@ pipeline { runRegressiontest('maintenance/v1.16', 'v1.16-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) } } - stage('v1.17 FMI') { + stage('v1.17 FMI with OMSimulator') { agent { node { label 'ryzen-5950x-2-1' @@ -351,7 +353,7 @@ pipeline { runRegressiontest('maintenance/v1.17', 'v1.17-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) } } - stage('v1.18 FMI') { + stage('v1.18 FMI with OMSimulator') { agent { node { label 'ryzen-5950x-2-1' @@ -367,7 +369,7 @@ pipeline { runRegressiontest('maintenance/v1.18', 'v1.18-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) } } - stage('v1.19 FMI') { + stage('v1.19 FMI with OMSimulator') { agent { node { label 'ryzen-5950x-2-1' @@ -383,7 +385,7 @@ pipeline { runRegressiontest('maintenance/v1.19', 'v1.19-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) } } - stage('v1.20 FMI') { + stage('v1.20 FMI with OMSimulator') { agent { node { label 'ryzen-5950x-2-1' @@ -399,7 +401,7 @@ pipeline { runRegressiontest('maintenance/v1.20', 'v1.20-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) } } - stage('v1.21 FMI') { + stage('v1.21 FMI with OMSimulator') { agent { node { label 'ryzen-5950x-2-1' @@ -415,7 +417,7 @@ pipeline { runRegressiontest('maintenance/v1.21', 'v1.21-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) } } - stage('v1.22 FMI') { + stage('v1.22 FMI with OMSimulator') { agent { node { label 'ryzen-5950x-2-1' @@ -431,7 +433,7 @@ pipeline { runRegressiontest('maintenance/v1.22', 'v1.22-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) } } - stage('master FMI') { + stage('master FMI with OMSimulator') { agent { node { label 'ryzen-5950x-2-1' @@ -447,6 +449,38 @@ pipeline { runRegressiontest('master', 'master-fmi', '', 'origin/master', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) } } + stage('v1.22 FMI with FMPy') { + agent { + node { + label 'ryzen-5950x-2-1' + customWorkspace 'ws/OpenModelicaLibraryTestingWork' + } + } + options { skipDefaultCheckout() } + when { + beforeAgent true + expression { params.fmpy_fmi_v1_22 } + } + steps { + runRegressiontest('maintenance/v1.22', 'v1.22-fmi-fmpy', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) + } + } + stage('master FMI with OMSimulator') { + agent { + node { + label 'ryzen-5950x-2-1' + customWorkspace 'ws/OpenModelicaLibraryTestingWork' + } + } + options { skipDefaultCheckout() } + when { + beforeAgent true + expression { params.fmpy_fmi_master } + } + steps { + runRegressiontest('master', 'master-fmi-fmpy', '', 'origin/master', 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) + } + } stage('newInst-daeMode') { agent { node { @@ -714,7 +748,7 @@ pipeline { expression { params.fmi_v1_12 || params.fmi_v1_13 || params.fmi_v1_14 || params.fmi_v1_16 || params.fmi_v1_17 || params.fmi_v1_18 || params.fmi_v1_19 || params.fmi_v1_20 || params.fmi_v1_21 || params.fmi_v1_22 ||params.fmi_master || params.newInst_daeMode || params.oldInst || params.report_ryzen_5950x_2 || params.cpp || params.cvode || params.gbode} } environment { - GITBRANCHES_FMI = 'maintenance/v1.12-fmi maintenance/v1.13-fmi maintenance/v1.14-fmi maintenance/v1.16-fmi maintenance/v1.17-fmi maintenance/v1.18-fmi maintenance/v1.19-fmi maintenance/v1.20-fmi maintenance/v1.21-fmi maintenance/v1.22-fmi master-fmi' + GITBRANCHES_FMI = 'maintenance/v1.12-fmi maintenance/v1.13-fmi maintenance/v1.14-fmi maintenance/v1.16-fmi maintenance/v1.17-fmi maintenance/v1.18-fmi maintenance/v1.19-fmi maintenance/v1.20-fmi maintenance/v1.21-fmi maintenance/v1.22-fmi master-fmi maintenance/v1.22-fmi-fmpy master-fmi-fmpy' GITBRANCHES_NEWINST = 'oldInst' GITBRANCHES_DAE = 'newInst-daeMode' GITBRANCHES_CPP = 'v1.19-cpp v1.20-cpp v1.21-cpp v1.22-cpp cpp' @@ -807,7 +841,7 @@ pipeline { } when { beforeAgent true - expression { params.fmi_v1_12 || params.fmi_v1_13 || params.fmi_v1_14 || params.fmi_v1_16 || params.fmi_v1_17 || params.fmi_master || params.newInst_daeMode || params.oldInst || params.report_ripper2 } + expression { params.fmi_v1_12 || params.fmi_v1_13 || params.fmi_v1_14 || params.fmi_v1_16 || params.fmi_v1_17 || params.fmi_v1_18 || params.fmi_v1_18 || params.fmi_v1_19 || params.fmi_v1_20 || params.fmi_v1_21 || params.fmi_v1_22 || params.fmi_master || params.fmpy_fmi_v1_22 || params.fmpy_fmi_master || params.newInst_daeMode || params.oldInst || params.report_ripper2 } } steps { sh 'cp ~/TEST_LIBS_BACKUP/ripper2-sqlite3.db sqlite3.db' @@ -863,7 +897,7 @@ def runRegressiontest(branch, name, extraFlags, omsHash, dbPrefix, sshConfig, om fi ''' FMI_TESTING_FLAG="" - if (omsHash) { + if (!name.contains('fmpy') && omsHash) { sh """ if ! test -d OMSimulator; then git clone --recursive https://openmodelica.org/git-readonly/OMSimulator.git || exit 1 @@ -894,6 +928,13 @@ def runRegressiontest(branch, name, extraFlags, omsHash, dbPrefix, sshConfig, om """ FMI_TESTING_FLAG="--fmi=true --fmisimulator=${env.HOME}/saved_omc/OMSimulator/install/bin/OMSimulator --default=ulimitExe=50" } + if (name.contains('fmpy')) { + sh """ + fmpy -h || exit 1 + """ + FMI_TESTING_FLAG="--fmi=true --fmisimulator='fmpy' --default=ulimitExe=50" + } + OMCPATH = "${omcompiler ? '../' : './'}OMCompiler" sh ''' diff --git a/.CI/build-dep/Dockerfile b/.CI/build-dep/Dockerfile index 93e3bb9..933394b 100644 --- a/.CI/build-dep/Dockerfile +++ b/.CI/build-dep/Dockerfile @@ -1,3 +1,3 @@ FROM docker.openmodelica.org/build-deps:v1.16.3 -RUN pip3 install matplotlib +RUN pip3 install matplotlib FMPy diff --git a/shared.py b/shared.py index 75a75a4..cd2eeb8 100644 --- a/shared.py +++ b/shared.py @@ -93,3 +93,8 @@ def simulationAcceptsFlag(f, checkOutput=True, cwd=None): except subprocess.CalledProcessError as e: pass return False + +def isFMPy(fmisimulator): + return 'fmpy' in fmisimulator + + diff --git a/test.py b/test.py index 4d113a6..e6a2ce2 100755 --- a/test.py +++ b/test.py @@ -97,7 +97,7 @@ def target(): parser.add_argument('--extrasimflags', default='') parser.add_argument('--ompython_omhome', default='') parser.add_argument('--noclean', action="store_true", default=False) -parser.add_argument('--fmisimulator', default='') +parser.add_argument('--fmisimulator', default='OMSimulator', help="'OMSimulator' is default but you can use 'fmpy' also") parser.add_argument('--ulimitvmem', help="Virtual memory limit (in kB)", type=int, default=8*1024*1024) parser.add_argument('--default', action='append', help="Add a default value for some configuration key, such as --default=ulimitExe=60. The equals sign is mandatory.", default=[]) parser.add_argument('-j', '--jobs', default=0) @@ -208,7 +208,11 @@ def timeSeconds(f): fmisimulatorversion = None if fmisimulator: - fmisimulatorversion = subprocess.check_output([fmisimulator, "-v"], stderr=subprocess.STDOUT).strip() + if not isFMPy(fmisimulator) + fmisimulatorversion = subprocess.check_output([fmisimulator, "-v"], stderr=subprocess.STDOUT).strip() + else + fmisimulatorversion = subprocess.check_output([fmisimulator, "-h"], stderr=subprocess.STDOUT).strip() + print(fmisimulatorversion) else: if allTestsFmi: diff --git a/testmodel.py b/testmodel.py index 64f7893..0739f11 100755 --- a/testmodel.py +++ b/testmodel.py @@ -435,7 +435,8 @@ def sendExpressionOldOrNew(cmd): writeResult() # Do the simulation -resFile = "%s_res.%s" % (conf["fileName"], outputFormat) +# FMPy generates csv, OMSimulator generates mat (outputFormat) +resFile = "%s_res.%s" % (conf["fileName"], outputFormat if not isFMPy(fmisimulator) else 'csv') start=monotonic() try: @@ -448,11 +449,15 @@ def sendExpressionOldOrNew(cmd): fmitmpdir = "temp_%s_fmu" % conf["fileName"].replace(".","_") with open("%s.tmpfiles" % conf["fileName"], "a+") as fp: fp.write("%s\n" % fmitmpdir) - cmd = "%s --tempDir=%s --startTime=%g --stopTime=%g --timeout=%g --tolerance=%g %s.fmu" % (("-r=%s" % resFile) if outputFormat != "empty" else "",fmitmpdir,startTime,stopTime,conf["ulimitExe"],tolerance,conf["fileName"].replace(".","_")) + fmisimulator = conf.get("fmisimulator") + if isFMpy(fmisimulator): + fmisimulator = "%s simulate " % fmisimulator + cmd = "%s --start-time %g --stop-time %g --timeout %g --tolerance %g %s.fmu" % ("--output-file %s" % resFile),startTime,stopTime,conf["ulimitExe"],tolerance,conf["fileName"].replace(".","_")) + else # OMSimulator + cmd = "%s --tempDir=%s --startTime=%g --stopTime=%g --timeout=%g --tolerance=%g %s.fmu" % (("-r=%s" % resFile) if outputFormat != "empty" else "",fmitmpdir,startTime,stopTime,conf["ulimitExe"],tolerance,conf["fileName"].replace(".","_")) with open(simFile,"w") as fp: fp.write("OMSimulator %s\n" % cmd) - #res = checkOutputTimeout("%s %s >> %s 2>&1" % (conf["fmisimulator"],cmd,simFile), conf["ulimitExe"], conf) - res = checkOutputTimeout("(rm -f %s.pipe ; mkfifo %s.pipe ; head -c 1048576 < %s.pipe >> %s & %s %s > %s.pipe 2>&1)" % (conf["fileName"],conf["fileName"],conf["fileName"],simFile,conf["fmisimulator"],cmd,conf["fileName"]), 1.05*conf["ulimitExe"], conf) + res = checkOutputTimeout("(rm -f %s.pipe ; mkfifo %s.pipe ; head -c 1048576 < %s.pipe >> %s & %s %s > %s.pipe 2>&1)" % (conf["fileName"],conf["fileName"],conf["fileName"],simFile,fmisimulator,cmd,conf["fileName"]), 1.05*conf["ulimitExe"], conf) else: cmd = ("./%s %s %s %s" % (conf["fileName"],annotationSimFlags,conf["simFlags"],emit_protected)).strip() if conf["simCodeTarget"]=="C": From 91c257439ee66e9a01609e5149a6856569a5614b Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Tue, 21 Nov 2023 12:52:15 +0100 Subject: [PATCH 197/452] fix copy paste error --- .CI/Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index 7d2ee79..989211b 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -465,7 +465,7 @@ pipeline { runRegressiontest('maintenance/v1.22', 'v1.22-fmi-fmpy', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', false, '', false, false) } } - stage('master FMI with OMSimulator') { + stage('master FMI with FMPy') { agent { node { label 'ryzen-5950x-2-1' From 124113e9e29298fab17f642f9d6648939e829acb Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Tue, 21 Nov 2023 18:47:07 +0100 Subject: [PATCH 198/452] fix syntax and FMPy install --- .CI/Jenkinsfile | 1 + test.py | 4 ++-- testmodel.py | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index 989211b..44d0136 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -930,6 +930,7 @@ def runRegressiontest(branch, name, extraFlags, omsHash, dbPrefix, sshConfig, om } if (name.contains('fmpy')) { sh """ + python -m pip install FMPy fmpy -h || exit 1 """ FMI_TESTING_FLAG="--fmi=true --fmisimulator='fmpy' --default=ulimitExe=50" diff --git a/test.py b/test.py index e6a2ce2..59af1d7 100755 --- a/test.py +++ b/test.py @@ -208,9 +208,9 @@ def timeSeconds(f): fmisimulatorversion = None if fmisimulator: - if not isFMPy(fmisimulator) + if not isFMPy(fmisimulator): fmisimulatorversion = subprocess.check_output([fmisimulator, "-v"], stderr=subprocess.STDOUT).strip() - else + else: fmisimulatorversion = subprocess.check_output([fmisimulator, "-h"], stderr=subprocess.STDOUT).strip() print(fmisimulatorversion) diff --git a/testmodel.py b/testmodel.py index 0739f11..0f0dcd4 100755 --- a/testmodel.py +++ b/testmodel.py @@ -453,7 +453,7 @@ def sendExpressionOldOrNew(cmd): if isFMpy(fmisimulator): fmisimulator = "%s simulate " % fmisimulator cmd = "%s --start-time %g --stop-time %g --timeout %g --tolerance %g %s.fmu" % ("--output-file %s" % resFile),startTime,stopTime,conf["ulimitExe"],tolerance,conf["fileName"].replace(".","_")) - else # OMSimulator + else: # OMSimulator cmd = "%s --tempDir=%s --startTime=%g --stopTime=%g --timeout=%g --tolerance=%g %s.fmu" % (("-r=%s" % resFile) if outputFormat != "empty" else "",fmitmpdir,startTime,stopTime,conf["ulimitExe"],tolerance,conf["fileName"].replace(".","_")) with open(simFile,"w") as fp: fp.write("OMSimulator %s\n" % cmd) From 5f78ff852d718ba713ed4184d547cffd7bd9baed Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Tue, 21 Nov 2023 18:57:30 +0100 Subject: [PATCH 199/452] fix missing parenthesis and use python3 --- .CI/Jenkinsfile | 2 +- testmodel.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index 44d0136..f342687 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -930,7 +930,7 @@ def runRegressiontest(branch, name, extraFlags, omsHash, dbPrefix, sshConfig, om } if (name.contains('fmpy')) { sh """ - python -m pip install FMPy + python3 -m pip install FMPy fmpy -h || exit 1 """ FMI_TESTING_FLAG="--fmi=true --fmisimulator='fmpy' --default=ulimitExe=50" diff --git a/testmodel.py b/testmodel.py index 0f0dcd4..bb734d0 100755 --- a/testmodel.py +++ b/testmodel.py @@ -452,7 +452,7 @@ def sendExpressionOldOrNew(cmd): fmisimulator = conf.get("fmisimulator") if isFMpy(fmisimulator): fmisimulator = "%s simulate " % fmisimulator - cmd = "%s --start-time %g --stop-time %g --timeout %g --tolerance %g %s.fmu" % ("--output-file %s" % resFile),startTime,stopTime,conf["ulimitExe"],tolerance,conf["fileName"].replace(".","_")) + cmd = "%s --start-time %g --stop-time %g --timeout %g --tolerance %g %s.fmu" % (("--output-file %s" % resFile),startTime,stopTime,conf["ulimitExe"],tolerance,conf["fileName"].replace(".","_")) else: # OMSimulator cmd = "%s --tempDir=%s --startTime=%g --stopTime=%g --timeout=%g --tolerance=%g %s.fmu" % (("-r=%s" % resFile) if outputFormat != "empty" else "",fmitmpdir,startTime,stopTime,conf["ulimitExe"],tolerance,conf["fileName"].replace(".","_")) with open(simFile,"w") as fp: From d8fe51a22e9be5700dab11bda3799f02e41652e2 Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Tue, 21 Nov 2023 22:27:47 +0100 Subject: [PATCH 200/452] fix imports --- test.py | 2 +- testmodel.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test.py b/test.py index 59af1d7..5c6df0e 100755 --- a/test.py +++ b/test.py @@ -16,7 +16,7 @@ from monotonic import monotonic from omcommon import friendlyStr, multiple_replace from natsort import natsorted -from shared import readConfig, getReferenceFileName, simulationAcceptsFlag +from shared import readConfig, getReferenceFileName, simulationAcceptsFlag, isFMPy import shared import signal diff --git a/testmodel.py b/testmodel.py index bb734d0..ce8ec82 100755 --- a/testmodel.py +++ b/testmodel.py @@ -436,7 +436,7 @@ def sendExpressionOldOrNew(cmd): # Do the simulation # FMPy generates csv, OMSimulator generates mat (outputFormat) -resFile = "%s_res.%s" % (conf["fileName"], outputFormat if not isFMPy(fmisimulator) else 'csv') +resFile = "%s_res.%s" % (conf["fileName"], outputFormat if not shared.isFMPy(fmisimulator) else 'csv') start=monotonic() try: @@ -450,7 +450,7 @@ def sendExpressionOldOrNew(cmd): with open("%s.tmpfiles" % conf["fileName"], "a+") as fp: fp.write("%s\n" % fmitmpdir) fmisimulator = conf.get("fmisimulator") - if isFMpy(fmisimulator): + if shared.isFMpy(fmisimulator): fmisimulator = "%s simulate " % fmisimulator cmd = "%s --start-time %g --stop-time %g --timeout %g --tolerance %g %s.fmu" % (("--output-file %s" % resFile),startTime,stopTime,conf["ulimitExe"],tolerance,conf["fileName"].replace(".","_")) else: # OMSimulator From c7a0848f8755c9b83901f65c5c9a6a2d7952e4b0 Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Wed, 22 Nov 2023 10:11:48 +0100 Subject: [PATCH 201/452] Update installLibraries.mos Also load the latest released ClaRa lib --- .CI/installLibraries.mos | 1 + 1 file changed, 1 insertion(+) diff --git a/.CI/installLibraries.mos b/.CI/installLibraries.mos index 3567619..a85cef5 100644 --- a/.CI/installLibraries.mos +++ b/.CI/installLibraries.mos @@ -62,6 +62,7 @@ for l in { {"ThermofluidStream", "main"}, {"TILMedia", "main"}, {"ClaRa_Obsolete", "main"}, + {"ClaRa", ""}, {"ClaRa", "main"} } loop if not installPackage(stringTypeName(l[1]), l[2]) then From ccaf2660613ea203d827c6119fc6285ff34f5c2f Mon Sep 17 00:00:00 2001 From: Francesco Casella Date: Wed, 22 Nov 2023 10:14:05 +0100 Subject: [PATCH 202/452] Update installLibraries.mos --- .CI/installLibraries.mos | 1 - 1 file changed, 1 deletion(-) diff --git a/.CI/installLibraries.mos b/.CI/installLibraries.mos index a85cef5..05fe0ea 100644 --- a/.CI/installLibraries.mos +++ b/.CI/installLibraries.mos @@ -61,7 +61,6 @@ for l in { {"Physiomodel", ""}, {"ThermofluidStream", "main"}, {"TILMedia", "main"}, - {"ClaRa_Obsolete", "main"}, {"ClaRa", ""}, {"ClaRa", "main"} } loop From f819660dd8f9af95ffb40ad282d4c3ed46f658a6 Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Wed, 22 Nov 2023 14:11:51 +0100 Subject: [PATCH 203/452] don't use OMSimulator as default because we check for empty when no FMI is used --- test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test.py b/test.py index 5c6df0e..1bc83cc 100755 --- a/test.py +++ b/test.py @@ -97,7 +97,7 @@ def target(): parser.add_argument('--extrasimflags', default='') parser.add_argument('--ompython_omhome', default='') parser.add_argument('--noclean', action="store_true", default=False) -parser.add_argument('--fmisimulator', default='OMSimulator', help="'OMSimulator' is default but you can use 'fmpy' also") +parser.add_argument('--fmisimulator', default='', help="The default is nothing but you can use the path to OMSimulator executable or 'fmpy'") parser.add_argument('--ulimitvmem', help="Virtual memory limit (in kB)", type=int, default=8*1024*1024) parser.add_argument('--default', action='append', help="Add a default value for some configuration key, such as --default=ulimitExe=60. The equals sign is mandatory.", default=[]) parser.add_argument('-j', '--jobs', default=0) From 5cee5e76c50fb27a14cf7f88e3d1fc3e1a638446 Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Wed, 22 Nov 2023 14:16:40 +0100 Subject: [PATCH 204/452] use python3 -m fmpy instead of fmpy --- .CI/Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index f342687..53465df 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -933,7 +933,7 @@ def runRegressiontest(branch, name, extraFlags, omsHash, dbPrefix, sshConfig, om python3 -m pip install FMPy fmpy -h || exit 1 """ - FMI_TESTING_FLAG="--fmi=true --fmisimulator='fmpy' --default=ulimitExe=50" + FMI_TESTING_FLAG="--fmi=true --fmisimulator='python3 -m fmpy' --default=ulimitExe=50" } OMCPATH = "${omcompiler ? '../' : './'}OMCompiler" From 441c8b0bdfd861ce5cf6870fd4c0a3233d768edb Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Thu, 23 Nov 2023 11:55:01 +0100 Subject: [PATCH 205/452] another instance --- .CI/Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index 53465df..8a2dedb 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -931,7 +931,7 @@ def runRegressiontest(branch, name, extraFlags, omsHash, dbPrefix, sshConfig, om if (name.contains('fmpy')) { sh """ python3 -m pip install FMPy - fmpy -h || exit 1 + python3 -m fmpy -h || exit 1 """ FMI_TESTING_FLAG="--fmi=true --fmisimulator='python3 -m fmpy' --default=ulimitExe=50" } From 8ca8a42e0c4524937892a7b964c38d8aba7af6b9 Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Thu, 23 Nov 2023 14:25:03 +0100 Subject: [PATCH 206/452] Don't run fmpy to get the version --- test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test.py b/test.py index 1bc83cc..c539b87 100755 --- a/test.py +++ b/test.py @@ -209,7 +209,7 @@ def timeSeconds(f): fmisimulatorversion = None if fmisimulator: if not isFMPy(fmisimulator): - fmisimulatorversion = subprocess.check_output([fmisimulator, "-v"], stderr=subprocess.STDOUT).strip() + fmisimulatorversion = "fmpy latest via pip" # subprocess.check_output([fmisimulator, "-v"], stderr=subprocess.STDOUT).strip() else: fmisimulatorversion = subprocess.check_output([fmisimulator, "-h"], stderr=subprocess.STDOUT).strip() From 94a06fe16a65dabf72807acc333ac0dcd17520ad Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Thu, 23 Nov 2023 14:40:47 +0100 Subject: [PATCH 207/452] The other branch! --- test.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test.py b/test.py index c539b87..f35e6a2 100755 --- a/test.py +++ b/test.py @@ -209,9 +209,9 @@ def timeSeconds(f): fmisimulatorversion = None if fmisimulator: if not isFMPy(fmisimulator): - fmisimulatorversion = "fmpy latest via pip" # subprocess.check_output([fmisimulator, "-v"], stderr=subprocess.STDOUT).strip() + fmisimulatorversion = subprocess.check_output([fmisimulator, "-v"], stderr=subprocess.STDOUT).strip() else: - fmisimulatorversion = subprocess.check_output([fmisimulator, "-h"], stderr=subprocess.STDOUT).strip() + fmisimulatorversion = "fmpy latest via pip" # subprocess.check_output([fmisimulator, "-h"], stderr=subprocess.STDOUT).strip() print(fmisimulatorversion) else: From 5c88a6ba977b8809b4ec2f092a7eb04a4c7944d3 Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Thu, 23 Nov 2023 14:52:24 +0100 Subject: [PATCH 208/452] Put back the fmpy version --- test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test.py b/test.py index f35e6a2..7c5471f 100755 --- a/test.py +++ b/test.py @@ -211,7 +211,7 @@ def timeSeconds(f): if not isFMPy(fmisimulator): fmisimulatorversion = subprocess.check_output([fmisimulator, "-v"], stderr=subprocess.STDOUT).strip() else: - fmisimulatorversion = "fmpy latest via pip" # subprocess.check_output([fmisimulator, "-h"], stderr=subprocess.STDOUT).strip() + fmisimulatorversion = subprocess.check_output(fmisimulator.split() + ["-h"], stderr=subprocess.STDOUT).strip() print(fmisimulatorversion) else: From cd9cdd4479fdaca98aa4adc4e021e8424aa70388 Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Thu, 23 Nov 2023 19:42:16 +0100 Subject: [PATCH 209/452] see why it fails, catch the exception --- test.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/test.py b/test.py index 7c5471f..05b0fa5 100755 --- a/test.py +++ b/test.py @@ -208,10 +208,16 @@ def timeSeconds(f): fmisimulatorversion = None if fmisimulator: - if not isFMPy(fmisimulator): - fmisimulatorversion = subprocess.check_output([fmisimulator, "-v"], stderr=subprocess.STDOUT).strip() - else: - fmisimulatorversion = subprocess.check_output(fmisimulator.split() + ["-h"], stderr=subprocess.STDOUT).strip() + try: + if not isFMPy(fmisimulator): + fmisimulatorversion = subprocess.check_output([fmisimulator, "-v"], stderr=subprocess.STDOUT).strip() + else: + fmisimulatorversion = subprocess.check_output(fmisimulator.split() + ["-h"], stderr=subprocess.STDOUT).strip() + except subprocess.CalledProcessError as e: + print("Failure to run %s:\n%s", fmisimulator, e.output) + + + print(fmisimulatorversion) else: From 872cfecf524c7fafa47e7fddfcc8a08ebb3e3511 Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Thu, 23 Nov 2023 19:59:51 +0100 Subject: [PATCH 210/452] bind the variable before use --- testmodel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testmodel.py b/testmodel.py index ce8ec82..073116a 100755 --- a/testmodel.py +++ b/testmodel.py @@ -436,6 +436,7 @@ def sendExpressionOldOrNew(cmd): # Do the simulation # FMPy generates csv, OMSimulator generates mat (outputFormat) +fmisimulator = conf.get("fmisimulator") resFile = "%s_res.%s" % (conf["fileName"], outputFormat if not shared.isFMPy(fmisimulator) else 'csv') start=monotonic() @@ -449,7 +450,6 @@ def sendExpressionOldOrNew(cmd): fmitmpdir = "temp_%s_fmu" % conf["fileName"].replace(".","_") with open("%s.tmpfiles" % conf["fileName"], "a+") as fp: fp.write("%s\n" % fmitmpdir) - fmisimulator = conf.get("fmisimulator") if shared.isFMpy(fmisimulator): fmisimulator = "%s simulate " % fmisimulator cmd = "%s --start-time %g --stop-time %g --timeout %g --tolerance %g %s.fmu" % (("--output-file %s" % resFile),startTime,stopTime,conf["ulimitExe"],tolerance,conf["fileName"].replace(".","_")) From ad52e0d38a2d9f8546fece7a72a236b9a68dde89 Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Thu, 23 Nov 2023 20:24:51 +0100 Subject: [PATCH 211/452] mind the caps --- testmodel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testmodel.py b/testmodel.py index 073116a..6825162 100755 --- a/testmodel.py +++ b/testmodel.py @@ -450,7 +450,7 @@ def sendExpressionOldOrNew(cmd): fmitmpdir = "temp_%s_fmu" % conf["fileName"].replace(".","_") with open("%s.tmpfiles" % conf["fileName"], "a+") as fp: fp.write("%s\n" % fmitmpdir) - if shared.isFMpy(fmisimulator): + if shared.isFMPy(fmisimulator): fmisimulator = "%s simulate " % fmisimulator cmd = "%s --start-time %g --stop-time %g --timeout %g --tolerance %g %s.fmu" % (("--output-file %s" % resFile),startTime,stopTime,conf["ulimitExe"],tolerance,conf["fileName"].replace(".","_")) else: # OMSimulator From dfbfa7a14dea50619bd18cb38f039dbb26b6728f Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Thu, 23 Nov 2023 20:55:18 +0100 Subject: [PATCH 212/452] is called --relative-tolerance in fmpy --- .CI/Jenkinsfile | 1 - test.py | 2 +- testmodel.py | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index 8a2dedb..58d8dd0 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -930,7 +930,6 @@ def runRegressiontest(branch, name, extraFlags, omsHash, dbPrefix, sshConfig, om } if (name.contains('fmpy')) { sh """ - python3 -m pip install FMPy python3 -m fmpy -h || exit 1 """ FMI_TESTING_FLAG="--fmi=true --fmisimulator='python3 -m fmpy' --default=ulimitExe=50" diff --git a/test.py b/test.py index 05b0fa5..20bd009 100755 --- a/test.py +++ b/test.py @@ -214,7 +214,7 @@ def timeSeconds(f): else: fmisimulatorversion = subprocess.check_output(fmisimulator.split() + ["-h"], stderr=subprocess.STDOUT).strip() except subprocess.CalledProcessError as e: - print("Failure to run %s:\n%s", fmisimulator, e.output) + print("Failure to run %s:\n%s" %(fmisimulator, e.output)) diff --git a/testmodel.py b/testmodel.py index 6825162..5710636 100755 --- a/testmodel.py +++ b/testmodel.py @@ -452,7 +452,7 @@ def sendExpressionOldOrNew(cmd): fp.write("%s\n" % fmitmpdir) if shared.isFMPy(fmisimulator): fmisimulator = "%s simulate " % fmisimulator - cmd = "%s --start-time %g --stop-time %g --timeout %g --tolerance %g %s.fmu" % (("--output-file %s" % resFile),startTime,stopTime,conf["ulimitExe"],tolerance,conf["fileName"].replace(".","_")) + cmd = "%s --start-time %g --stop-time %g --timeout %g --relative-tolerance %g %s.fmu" % (("--output-file %s" % resFile),startTime,stopTime,conf["ulimitExe"],tolerance,conf["fileName"].replace(".","_")) else: # OMSimulator cmd = "%s --tempDir=%s --startTime=%g --stopTime=%g --timeout=%g --tolerance=%g %s.fmu" % (("-r=%s" % resFile) if outputFormat != "empty" else "",fmitmpdir,startTime,stopTime,conf["ulimitExe"],tolerance,conf["fileName"].replace(".","_")) with open(simFile,"w") as fp: From 032ef64be766bc0e15c4173c7008e6eef8f8a8a0 Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Thu, 23 Nov 2023 21:03:29 +0100 Subject: [PATCH 213/452] use the actual given fmisimulator --- testmodel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testmodel.py b/testmodel.py index 5710636..f720603 100755 --- a/testmodel.py +++ b/testmodel.py @@ -456,7 +456,7 @@ def sendExpressionOldOrNew(cmd): else: # OMSimulator cmd = "%s --tempDir=%s --startTime=%g --stopTime=%g --timeout=%g --tolerance=%g %s.fmu" % (("-r=%s" % resFile) if outputFormat != "empty" else "",fmitmpdir,startTime,stopTime,conf["ulimitExe"],tolerance,conf["fileName"].replace(".","_")) with open(simFile,"w") as fp: - fp.write("OMSimulator %s\n" % cmd) + fp.write("%s %s\n" % (fmisimulator, cmd)) res = checkOutputTimeout("(rm -f %s.pipe ; mkfifo %s.pipe ; head -c 1048576 < %s.pipe >> %s & %s %s > %s.pipe 2>&1)" % (conf["fileName"],conf["fileName"],conf["fileName"],simFile,fmisimulator,cmd,conf["fileName"]), 1.05*conf["ulimitExe"], conf) else: cmd = ("./%s %s %s %s" % (conf["fileName"],annotationSimFlags,conf["simFlags"],emit_protected)).strip() From c1991aaded11a1ebfac5f86cf141f701a9cba5b2 Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Fri, 24 Nov 2023 19:17:17 +0100 Subject: [PATCH 214/452] grep the version out of FMPy help --- test.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/test.py b/test.py index 20bd009..dbb2eca 100755 --- a/test.py +++ b/test.py @@ -212,13 +212,10 @@ def timeSeconds(f): if not isFMPy(fmisimulator): fmisimulatorversion = subprocess.check_output([fmisimulator, "-v"], stderr=subprocess.STDOUT).strip() else: - fmisimulatorversion = subprocess.check_output(fmisimulator.split() + ["-h"], stderr=subprocess.STDOUT).strip() + fmisimulatorversion = subprocess.getoutput(fmisimulator + " -h | grep version | tr '\n' ' ' | tr -s ' '" ).strip() except subprocess.CalledProcessError as e: print("Failure to run %s:\n%s" %(fmisimulator, e.output)) - - - - + raise e print(fmisimulatorversion) else: if allTestsFmi: From 6b4647bef7bd8fc52a1d3fbdb2734b63be934ba7 Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Sat, 25 Nov 2023 01:31:18 +0100 Subject: [PATCH 215/452] Check for nothing before using variable --- shared.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/shared.py b/shared.py index cd2eeb8..9193885 100644 --- a/shared.py +++ b/shared.py @@ -95,6 +95,9 @@ def simulationAcceptsFlag(f, checkOutput=True, cwd=None): return False def isFMPy(fmisimulator): - return 'fmpy' in fmisimulator + if fmisimulator: + return 'fmpy' in fmisimulator + else: + return False From 1d6ac42fdd8a3838cd26d784b5320388eeec1227 Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Tue, 28 Nov 2023 09:20:19 +0100 Subject: [PATCH 216/452] add info about OpenModelicaLibraryTesting used to run the test --- all-reports.py | 14 ++++++++++++-- history.html.tpl | 7 ++++++- library.html.tpl | 3 ++- test.py | 9 +++++++++ 4 files changed, 29 insertions(+), 4 deletions(-) diff --git a/all-reports.py b/all-reports.py index 5ba7385..19f9221 100755 --- a/all-reports.py +++ b/all-reports.py @@ -14,6 +14,7 @@ parser.add_argument('--baseurl', default="http://libraries.openmodelica.org/branches") parser.add_argument('--historyurl', default="http://libraries.openmodelica.org/branches/history") parser.add_argument('--githuburl', default="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/OpenModelica/OpenModelica/commit") +parser.add_argument('--githuburltesting', default="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/OpenModelica/OpenModelicaLibraryTesting/commit") parser.add_argument('--omcgitdir', default="../OpenModelica/OpenModelica") parser.add_argument('--email', default=False, action='store_true') args = parser.parse_args() @@ -25,7 +26,9 @@ baseurl = args.baseurl historyurl = args.historyurl githuburl = args.githuburl +githuburltesting = args.githuburltesting omcgitdir = args.omcgitdir +omctestinggitdir = args.omctestinggitdir doemail = args.email if not os.path.exists(omcgitdir): @@ -100,7 +103,7 @@ def modelLink(libname, modelname, extension, text): emails_current = set(["openmodelicabuilds@ida.liu.se"]) if v1 != v2: try: - gitlog = subprocess.check_output(["git", "log", '--pretty=%%h%%an%%s' % (githuburl), "%s..%s" % (v1,v2)], cwd=omcgitdir).decode("utf-8") + gitlog = subprocess.check_output(["git", "log", '--pretty=%%h%%ai%%an%%s' % (githuburl), "%s..%s" % (v1,v2)], cwd=omcgitdir).decode("utf-8") print("Do git ls-tree for %s %s" % (v1,v2)) try: t1 = subprocess.check_output(["git", "ls-tree", v1, "OMCompiler/3rdParty"], cwd=omcgitdir).decode("utf-8").strip().split(" ")[2].split("\t")[0] @@ -128,7 +131,14 @@ def modelLink(libname, modelname, extension, text): gitlog = "%s..%s" % (v1,v2) else: gitlog = "" - tpl = tpl.replace("#OMCGITLOG#",gitlog).replace("#NUMCOMMITS#",str(gitlog.count(""))).replace("#3rdParty#",thirdPartyChanged) + + try: + gitloglibrarytesting = subprocess.check_output(["git", "log", '--pretty=%%h%%ai%%an%%s' % (githuburltesting), "-2"], cwd="./").decode("utf-8") + except subprocess.CalledProcessError as e: + print(str(e)) + gitloglibrarytesting = "could not get the git log for OpenModelicaLibraryTesting" + + tpl = tpl.replace("#OMCGITLOG#",gitlog).replace("#NUMCOMMITS#",str(gitlog.count(""))).replace("#3rdParty#",thirdPartyChanged).replace("#OMCLIBRARYTESTINGGITLOG#",gitloglibrarytesting) libnames = [libname for (libname,) in cursor.execute("""SELECT libname FROM [%s] WHERE date=? GROUP BY libname""" % branch, (d2,))] startdates = {} # Get previous date of each library run and group them together for fast queries later diff --git a/history.html.tpl b/history.html.tpl index 58d7a79..6af95bd 100644 --- a/history.html.tpl +++ b/history.html.tpl @@ -26,10 +26,15 @@

OpenModelica Changes

- + #OMCGITLOG#
CommitAuthorSummary
CommitDateAuthorSummary
#3rdParty# +

OpenModelicaLibaryTesting Changes

+ + +#OMCLIBRARYTESTINGGITLOG# +
CommitDateAuthorSummary

Library Changes

diff --git a/library.html.tpl b/library.html.tpl index 9eb1f86..399fb32 100644 --- a/library.html.tpl +++ b/library.html.tpl @@ -33,8 +33,9 @@

System info: #sysInfo#

OpenModelica Version: #omcVersion#

#fmi# +#OpenModelicaLibraryTesting#

Test started: #timeStart#

-

Tested Library: #libraryVersionRevision#

+

Tested Library: ##

 #metadata#

BuildModel time limit: #ulimitOmc#s

Simulation time limit: #ulimitExe#s

diff --git a/test.py b/test.py index dbb2eca..2d2a0ae 100755 --- a/test.py +++ b/test.py @@ -819,6 +819,14 @@ def cpu_name(): ))(filename_prefix="files/%s_%s" % (s[2], s[1]), diff=s[3].get("diff")) for s in natsorted(stats, key=lambda s: s[1])]) numSucceeded = [len(stats)] + [sum(1 if s[3]["phase"]>=i else 0 for s in stats) for i in range(1,8)] + + try: + githuburltesting = "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/OpenModelica/OpenModelicaLibraryTesting/commit/" + gitloglibrarytesting = subprocess.check_output(["git", "log", '--pretty=
CommitDateAuthorSummary
%%h%%ai%%an%%s
' % (githuburltesting), "-1"], cwd="./").decode("utf-8") + except subprocess.CalledProcessError as e: + print(str(e)) + gitloglibrarytesting = "
could not get the git log for OpenModelicaLibraryTesting
" + replacements = ( (u"#sysInfo#", html.escape(sysInfo)), (u"#omcVersion#", html.escape(omc_version)), @@ -828,6 +836,7 @@ def cpu_name(): (u"#fileName#", html.escape(libname)), (u"#customCommands#", html.escape("\n".join(conf["customCommands"]))), (u"#libraryVersionRevision#", html.escape(conf["libraryVersionRevision"])), + (u"#OpenModelicaLibraryTesting#", html.escape(gitloglibrarytesting)), (u"#metadata#", html.escape(conf["metadata"])), (u"#ulimitOmc#", html.escape(str(conf["ulimitOmc"]))), (u"#ulimitExe#", html.escape(str(conf["ulimitExe"]))), From 74f1379eb4757fddf471f0e95a2bdb77145966d9 Mon Sep 17 00:00:00 2001 From: Andreas <38031952+AnHeuermann@users.noreply.github.com> Date: Mon, 15 Jan 2024 13:14:00 +0100 Subject: [PATCH 217/452] Fix html (#51) * Improve test.py doc in README * Fixing HTML issues - `` missing `DOCTYPE`. - Replace `
` with `
`. - Replace `
` with `
` - Element p not allowed as child of element span - Fix missing --- .gitignore | 10 +++++++++- README.md | 15 +++++++++++++++ all-reports.py | 2 +- history.html.tpl | 2 +- library.html.tpl | 2 +- overview.html.tpl | 3 ++- report.py | 10 +++++----- testmodel.py | 4 ++-- 8 files changed, 36 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index b1a0309..b1da1ab 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,11 @@ +__pycache__ +!HelloWorld.mo +!HelloWorld.mos /*.json /converted-libraries -__pycache__ +files/ +HelloWorld* +history/ +sqlite3.db +/*.html +/*.files diff --git a/README.md b/README.md index bf65d63..c963884 100644 --- a/README.md +++ b/README.md @@ -93,6 +93,21 @@ The scripts from this repository can be used to run regression tests for public, ``` Use `configs/*.json` to specify what to test. The test results are saved in `sqlite3.db`. + + Options: + - `--branch=master`: Branch of OpenModelica + - `--fmi=False`: Test FMI + - `--output=''`: Result location + - `--libraries=~/.openmodelica/libraries/`: Location of Modelica libraries + - `--extraflags=''`: Extra compiler flags. + - `--extrasimflags=''`: Extra simulation flags. + - `--ompython_omhome=''`: Path to OpenModelica for OMPython (can be different to the OM running the tests) + - `--noclean=False`: Clean (most) generated files. + - `--fmisimulator=''`: The default is nothing but you can use the path to OMSimulator executable or 'fmpy' + - `--ulimitvmem=8388608`: Virtual memory limit (in kB) + - `--default=[]`: Add a default value for some configuration key, such as --default=ulimitExe=60. The equals sign is mandatory + - `-j`,`--jobs`: Number of threads to use for testing. + - Generate HTML results ```bash ./report.py configs/myConf.json diff --git a/all-reports.py b/all-reports.py index 5ba7385..1bde2ea 100755 --- a/all-reports.py +++ b/all-reports.py @@ -256,7 +256,7 @@ def modelLink(libname, modelname, extension, text): The following reports contain regressions your account was involved with: """ + "\n".join(reversed(emails_to_send[email]["plain"]))) msg.add_alternative("""\ - +

The following reports contain regressions your account was involved with:

diff --git a/history.html.tpl b/history.html.tpl index 58d7a79..89ef833 100644 --- a/history.html.tpl +++ b/history.html.tpl @@ -1,5 +1,5 @@ - + OpenModelica #BRANCH# from #DATE1# to #DATE2# diff --git a/library.html.tpl b/library.html.tpl index 9eb1f86..e4e2cdd 100644 --- a/library.html.tpl +++ b/library.html.tpl @@ -1,5 +1,5 @@ - + #fileName# test using OpenModelica diff --git a/overview.html.tpl b/overview.html.tpl index e58f616..b62305c 100644 --- a/overview.html.tpl +++ b/overview.html.tpl @@ -1,4 +1,5 @@ - + + #title# - - -
-

- - - - - - - - - - - -Parameters used for the comparison: Relative tolerance %g (local), %g (relative to max-min). Range delta %g.

- - -""" % (tolerance, conf["reference_reltolDiffMinMax"], conf["reference_rangeDelta"], os.path.basename(prefix + "." + var + ".csv"), var)) + stat["diff"] = {"time":monotonic()-start, "vars":[], "numCompared":len(referenceVars)} + if len(diffVars)==0 and referenceOK: + stat["phase"]=7 + with open(errFile, 'a+') as fp: + fp.write("Reference file matches\n") + else: + with open(errFile, 'a+') as fp: + fp.write(omc_new.sendExpression('OpenModelica.Scripting.getErrorString()', parsed = False)) + fp.write("\nVariables in the reference:" ) + fp.write(",".join(referenceVars)+"\n") + resVars=omc_new.sendExpression('readSimulationResultVars("%s", readParameters=true, openmodelicaStyle=true)' % resFile) + fp.write("\nVariables in the result:" ) + fp.write(",".join(resVars)+"\n") + diffFiles = [prefix + "." + var for var in diffVars] + stat["diff"]["vars"]=diffVars + + # Create a file containing only the calibrated variables, for easy display + lstfiles = "\n".join(['
  • %s (javascript) (csv)
  • ' % (str.split(str(f),".diff.",1)[1],str(os.path.basename(f)),str(os.path.basename(f))) for f in diffFiles]) + with open(prefix+".html", 'w') as fp: + fp.write('

    %s differences from the reference file

    startTime: %g

    stopTime: %g

    Simulated using tolerance: %g

      %s
    ' % (conf["modelName"], startTime, stopTime, tolerance, lstfiles)) + for var in diffVars: + if "/" in var: + continue # Quoted identifier, or possibly an error message... Either way, avoid crapping out below + with open(prefix+"."+var+".html", 'w') as fp: + fp.write(""" + + + + + +
    +

    + + + + + + + + + + + + Parameters used for the comparison: Relative tolerance %g (local), %g (relative to max-min). Range delta %g.

    + + + """ % (tolerance, conf["reference_reltolDiffMinMax"], conf["reference_rangeDelta"], os.path.basename(prefix + "." + var + ".csv"), var)) + + +# The first simulator's results are the ones every non-FMI code path expects. +verifyAgainstReference(resFile, artifactPrefix(fmisimulators[0][0] if fmisimulators else None) + ".diff", execstat) + +# The FMU is built; every other simulator the job asked for is now only a +# simulation and a comparison. A tool that times out or fails takes its own +# results down with it and leaves the others alone - unlike the first one, +# whose timeout ends the model as it always has. +for (name, command) in fmisimulators[1:]: + stat = {"sim": None, "diff": None, "phase": 5} + simulators[name] = stat + simFileOther = os.path.abspath("../files/%s_%s.sim" % (conf["fileName"], name)).replace('\\','/') + other = resultFile(name) + start = monotonic() + try: + simulateFmu(name, command, other, simFileOther) + stat["sim"] = monotonic()-start + stat["phase"] = 6 + verifyAgainstReference(other, artifactPrefix(name) + ".diff", stat) + except TimeoutError as e: + stat["sim"] = monotonic()-start + with open(errFile, 'a+') as fp: + fp.write("%s timed out simulating the FMU\n" % name) + writeResult() -# quit omc_new +# quit omc_new: every verification needed it omc_new = quit_omc(omc_new) writeResultAndExit(0) From e48fd06aacdfd226f5eb8c3864e73738166bd89a Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Tue, 11 Aug 2026 18:55:31 +0200 Subject: [PATCH 428/452] sqlite3 to postgresql - migration (#296) * Add a sqlite3 to PostgreSQL migration and document the database Towards a network based SQL database for the library testing, issue #295. sqlite2postgres.py copies the per-machine sqlite3 databases into PostgreSQL. The PostgreSQL layout is a 1:1 mirror of the sqlite3 one - one table per branch with the same column names, only the types adapted - so that the test scripts can push new results to the network database with the statements they already use. The two machines are merged into the same tables, ripper1 first and ripper2 with --skip-existing, so that the row already in the database wins whenever a key collides. The keys the migration adds - (date, libname, model) for a branch table - are what makes a shared database possible at all: they hold across all 160 million migrated rows, and they stop a run that is pushed twice from storing its results twice. The script needs nothing but the standard library and the psql client, streams the rows through COPY in batches, and commits each batch together with its progress row in [migration_progress], so a migration that is interrupted continues where it stopped instead of duplicating rows. --index creates the keys and the index the reports need, --verify compares the row counts of both sides. --catch-up copies the runs a machine wrote after the migration read its database, which a test still using its sqlite3 file keeps doing until the jobs are switched over: a wasm-jit run of 19527 models finished right after the migration and was missing from the shared database until it was caught up. It picks the runs by date rather than by continuing from the rowid it stopped at, because VACUUM renumbers the rowids of these tables and clean-empty-omcversion-dates.py runs one after every test, and because two machines write into the same table for the branches they both test. Reading a whole database costs two to three minutes, and the keys make repeating it harmless. COPY is used in its text format rather than CSV because an empty CSV field reads back as NULL, which would silently turn the empty libversion strings of the old data into NULLs. For the same reason only the key columns are NOT NULL: the sqlite3 tables declare every column NOT NULL, but tables created by an older test.py kept their laxer declaration and the historical rows do not hold up. doc/README.md documents what is actually in the database: the per-branch tables, omcversion and libversion, what every column means, how finalphase maps to the phase names, how a test run writes its results, and how to run the migration. --- Generated by Claude Code. Signed-off-by: Adrian Pop * Let the testing use a shared PostgreSQL database instead of sqlite3 files Second part of issue #295: the test machines can now write their results to one network database and coordinate through it, instead of each copying a sqlite3 file in, testing, and copying it back - the step that made two machines overwrite each other depending on which one finished last. resultsdb.py holds both backends behind one interface. The scripts write the same statements for either, with "?" as the placeholder, and ask the connection where the dialects genuinely differ: quoting a branch name, testing whether a table exists, concatenating a group, counting a condition, matching a branch without case, skipping a row that is already there. Every script takes --db, which defaults to the LIBTEST_DB environment variable, so Jenkins sets the database once for the whole pipeline rather than on forty invocations. A machine claims a job in [job_claim] before testing a library, keyed by exactly the question the run already asks: which library, in which version, against which compiler and configuration. Only one machine can win the claim, and the others skip that library and move on. The winner refreshes a heartbeat every minute and marks the claim done when the results are written, so a machine that dies parks its jobs for STALE_CLAIM_MINUTES rather than forever. A local sqlite3 file has a single writer, so there claim() always says yes. Two PostgreSQL specifics were needed for the reports: GROUP_CONCAT relies on sqlite keeping the order of the subquery that feeds it, so the ported query orders inside the aggregate, and COUNT(x or null) becomes COUNT(*) FILTER. Running the report queries against ripper1's sqlite file and against the migrated database gives the same rows, down to the phase counts, the per-phase sums and the regression rows: checked on master, whose table holds 43 million of them, and on heavy_tests, conversion and basemodelica_jl_master. The two only render the doubles with a different number of digits, and the report parses them back with float(). The Jenkinsfile gets a "postgres" parameter, on by default, which selects the database and drops the download and the publishing of sqlite3.db. Unticking it restores the old behaviour unchanged. The password comes from a Jenkins secret file credential, omdb-pgpass, bound to PGPASSFILE, so it never reaches a command line or the build log. --- Generated by Claude Code. Signed-off-by: Adrian Pop --------- Signed-off-by: Adrian Pop --- .CI/Jenkinsfile | 55 ++-- .CI/build-dep/Dockerfile | 2 +- all-plots.py | 20 +- all-reports.py | 38 +-- clean-dates.py | 18 +- clean-empty-omcversion-dates.py | 22 +- doc/README.md | 432 ++++++++++++++++++++++++++++++++ report.py | 29 +-- requirements.txt | 1 + resultsdb.py | 405 ++++++++++++++++++++++++++++++ single-model.py | 21 +- sqlite2postgres.py | 406 ++++++++++++++++++++++++++++++ test.py | 70 ++---- 13 files changed, 1389 insertions(+), 130 deletions(-) create mode 100644 doc/README.md create mode 100644 resultsdb.py create mode 100644 sqlite2postgres.py diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index 5d99a79..1619e07 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -3,6 +3,8 @@ pipeline { parameters { booleanParam(name: 'OLDLIBS', defaultValue: false, description: 'Also test some outdated libraries') + booleanParam(name: 'postgres', defaultValue: true, description: 'Store the results in the shared PostgreSQL database (omdb on openmodelica.org) rather than in the per-machine sqlite3 file. Machines coordinate through it, so two of them no longer overwrite each other. Untick to go back to the sqlite3 files.') + booleanParam(name: 'v1_26', defaultValue: false, description: 'maintenance/v1.26 branch (ryzen-5950x-1)') booleanParam(name: 'v1_27', defaultValue: false, description: 'maintenance/v1.27 branch (ryzen-5950x-1)') booleanParam(name: 'master', defaultValue: false, description: 'master branch (ryzen-5950x-1)') @@ -40,6 +42,12 @@ pipeline { } environment { LC_ALL = 'C.UTF-8' + // Where the results go. The scripts take it from here instead of a --db + // option on every single invocation. + LIBTEST_DB = "${params.postgres ? 'postgresql://om@openmodelica.org/omdb' : 'sqlite3.db'}" + // A secret file holding one pgpass line; libpq reads the password from it, + // so it never reaches a command line or the build log. + PGPASSFILE = credentials('omdb-pgpass') } stages { stage('test') { parallel { @@ -455,7 +463,12 @@ pipeline { cd OpenModelica git fetch ''' - sh 'wget -q https://libraries.openmodelica.org/sqlite3/ripper1/sqlite3.db' + // The reports read the shared database directly when it is in use. + script { + if (!params.postgres) { + sh 'wget -q https://libraries.openmodelica.org/sqlite3/ripper1/sqlite3.db' + } + } sh './clean-empty-omcversion-dates.py' sh "./all-reports.py --email --omcgitdir=OpenModelica ${env.GITBRANCHES} conversion heavy_tests" @@ -521,7 +534,11 @@ pipeline { cd OpenModelica git fetch ''' - sh 'wget -q https://libraries.openmodelica.org/sqlite3/ripper2/sqlite3.db' + script { + if (!params.postgres) { + sh 'wget -q https://libraries.openmodelica.org/sqlite3/ripper2/sqlite3.db' + } + } sh './clean-empty-omcversion-dates.py' sh "./all-reports.py --email --omcgitdir=OpenModelica ${env.GITBRANCHES_FMI} ${env.GITBRANCHES_NEWINST} ${env.GITBRANCHES_DAE} ${env.GITBRANCHES_NEWBACKEND_DAE} ${env.GITBRANCHES_CPP} gbode cvode ida" @@ -978,14 +995,17 @@ def runRegressiontest(branch, name, extraFlags, omsHash, dbPrefix, sshConfig, om sh "test -d '${libraryPath}/.openmodelica/libraries/Modelica trunk'" - sh """ - if ! test -f ~/TEST_LIBS_BACKUP/${dbPrefix}-sqlite3.db; then - wget -O ~/TEST_LIBS_BACKUP/${dbPrefix}-sqlite3.db.tmp -q https://libraries.openmodelica.org/sqlite3/${dbPrefix}/sqlite3.db - mv ~/TEST_LIBS_BACKUP/${dbPrefix}-sqlite3.db.tmp ~/TEST_LIBS_BACKUP/${dbPrefix}-sqlite3.db - fi - cp ~/TEST_LIBS_BACKUP/${dbPrefix}-sqlite3.db OpenModelicaLibraryTesting/sqlite3.db - test -s OpenModelicaLibraryTesting/sqlite3.db - """ + // The shared database needs none of this: the results go straight into it. + if (!params.postgres) { + sh """ + if ! test -f ~/TEST_LIBS_BACKUP/${dbPrefix}-sqlite3.db; then + wget -O ~/TEST_LIBS_BACKUP/${dbPrefix}-sqlite3.db.tmp -q https://libraries.openmodelica.org/sqlite3/${dbPrefix}/sqlite3.db + mv ~/TEST_LIBS_BACKUP/${dbPrefix}-sqlite3.db.tmp ~/TEST_LIBS_BACKUP/${dbPrefix}-sqlite3.db + fi + cp ~/TEST_LIBS_BACKUP/${dbPrefix}-sqlite3.db OpenModelicaLibraryTesting/sqlite3.db + test -s OpenModelicaLibraryTesting/sqlite3.db + """ + } sh 'date' @@ -1008,11 +1028,16 @@ def runRegressiontest(branch, name, extraFlags, omsHash, dbPrefix, sshConfig, om stdbuf -oL -eL time ./test.py --ompython_omhome=/usr ${FMI_TESTING_FLAG} --extraflags='${extraFlags}' --extrasimflags='${extrasimflags}' ${testFlags} --branch="${name}" --output="libraries.openmodelica.org:/var/www/libraries.openmodelica.org/branches/${name}/" --libraries='${libraryPath}/.openmodelica/libraries/' --jobs=${jobs} ${libs_config_file} ${params.OLDLIBS ? "configs/conf-old.json configs/conf-nonstandard.json" : ""} || (killall omc ; false) || exit 1 """) sh 'date' - sh "rm -f OpenModelicaLibraryTesting/${dbPrefix}-sqlite3.db.tmp" - sh "ln OpenModelicaLibraryTesting/sqlite3.db OpenModelicaLibraryTesting/${dbPrefix}-sqlite3.db.tmp" sh "cd OpenModelicaLibraryTesting/ && ./clean-empty-omcversion-dates.py" - sh "cp OpenModelicaLibraryTesting/sqlite3.db ~/TEST_LIBS_BACKUP/${dbPrefix}-sqlite3.db" - sh "rm -f ~/TEST_LIBS_BACKUP/${dbPrefix}-`date +sqlite3.%Y%m%d.db`" - sshPublisher(publishers: [sshPublisherDesc(configName: sshConfig, transfers: [sshTransfer(removePrefix: 'OpenModelicaLibraryTesting', sourceFiles: 'OpenModelicaLibraryTesting/sqlite3.db')])], failOnError: true) + // Copying the file back is what made two machines overwrite each other's + // results, so it only happens while a job still writes its own sqlite3 file. + if (!params.postgres) { + sh "rm -f OpenModelicaLibraryTesting/${dbPrefix}-sqlite3.db.tmp" + sh "ln OpenModelicaLibraryTesting/sqlite3.db OpenModelicaLibraryTesting/${dbPrefix}-sqlite3.db.tmp" + sh "cp OpenModelicaLibraryTesting/sqlite3.db ~/TEST_LIBS_BACKUP/${dbPrefix}-sqlite3.db" + sh "rm -f ~/TEST_LIBS_BACKUP/${dbPrefix}-`date +sqlite3.%Y%m%d.db`" + + sshPublisher(publishers: [sshPublisherDesc(configName: sshConfig, transfers: [sshTransfer(removePrefix: 'OpenModelicaLibraryTesting', sourceFiles: 'OpenModelicaLibraryTesting/sqlite3.db')])], failOnError: true) + } } diff --git a/.CI/build-dep/Dockerfile b/.CI/build-dep/Dockerfile index 78dbab8..c0f8abe 100644 --- a/.CI/build-dep/Dockerfile +++ b/.CI/build-dep/Dockerfile @@ -1,4 +1,4 @@ FROM docker.openmodelica.org/build-deps:v1.16.3 RUN apt-get update && apt-get install libxml2 libxslt1.1 libxml2-dev libxslt1-dev -RUN pip3 install matplotlib FMPy +RUN pip3 install matplotlib FMPy psycopg2-binary diff --git a/all-plots.py b/all-plots.py index 6397707..e7c8026 100755 --- a/all-plots.py +++ b/all-plots.py @@ -3,7 +3,7 @@ import sys, argparse, subprocess, os import simplejson as json -import shared +import shared, resultsdb import re, time, math from omcommon import friendlyStr @@ -18,6 +18,7 @@ parser = argparse.ArgumentParser(description='OpenModelica model testing report generation tool') parser.add_argument('branches', nargs='*') parser.add_argument('--historypath', default="history") +resultsdb.addArgument(parser) args = parser.parse_args() branches = [branch.split("/")[-1] for branch in args.branches] @@ -25,11 +26,11 @@ libs = {} -import cgi, sqlite3, time, datetime +import cgi, time, datetime from omcommon import friendlyStr, multiple_replace -conn = sqlite3.connect('sqlite3.db') -cursor = conn.cursor() +db = resultsdb.connect(args.db) +cursor = db.cursor() def dateStr(dint): return str(datetime.datetime.fromtimestamp(dint).strftime('%Y-%m-%d %H:%M:%S')) @@ -98,8 +99,7 @@ def plotLibrary(branch, libname, xs, total, frontend,backend,simcode,template,co for branch in branches: try: - cursor.execute("SELECT name FROM [sqlite_master] WHERE type='table' AND name=?", (branch,)) - one = cursor.fetchone() + one = (branch,) if db.tableExists(branch) else None if one == None: print("No such table '%s'; specify it using --branch=XXX when running test.py" % branch) # ignore this table and continue @@ -112,13 +112,13 @@ def plotLibrary(branch, libname, xs, total, frontend,backend,simcode,template,co # ignore this table and continue continue - cursor.execute('''CREATE INDEX IF NOT EXISTS [idx_%s_date] ON [%s](date)''' % (branch,branch)) + db.createDateIndex(branch) libs = {} - for (date,libname,total,frontend,backend,simcode,template,compile,simulate,verify) in cursor.execute("""SELECT date,libname,COUNT(finalphase),COUNT(finalphase>=1 or null),COUNT(finalphase>=2 or null),COUNT(finalphase>=3 or null),COUNT(finalphase>=4 or null),COUNT(finalphase>=5 or null),COUNT(finalphase>=6 or null),COUNT(finalphase>=7 or null) - FROM [%s] + for (date,libname,total,frontend,backend,simcode,template,compile,simulate,verify) in cursor.execute("""SELECT date,libname,COUNT(finalphase),%s + FROM %s GROUP BY date,libname ORDER BY libname,date ASC -""" % (branch)): +""" % (",".join(db.countIf("finalphase>=%d" % i) for i in range(1,8)), db.quote(branch))): if libname not in libs: libs[libname] = ([],[],[],[],[],[],[],[],[]) libs[libname][0].append(datetime.datetime.fromtimestamp(date)) diff --git a/all-reports.py b/all-reports.py index 07f0c6e..dbd1a5b 100755 --- a/all-reports.py +++ b/all-reports.py @@ -5,7 +5,7 @@ import codecs import sys, argparse, subprocess, os, time import simplejson as json -import shared +import shared, resultsdb import re from omcommon import friendlyStr @@ -17,6 +17,7 @@ parser.add_argument('--githuburltesting', default="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/OpenModelica/OpenModelicaLibraryTesting/commit") parser.add_argument('--omcgitdir', default="../OpenModelica/OpenModelica") parser.add_argument('--email', default=False, action='store_true') +resultsdb.addArgument(parser) args = parser.parse_args() os.environ['TZ'] = 'Europe/Stockholm' @@ -44,11 +45,11 @@ libs = {} -import cgi, sqlite3, time, datetime +import cgi, time, datetime from omcommon import friendlyStr, multiple_replace -conn = sqlite3.connect('sqlite3.db') -cursor = conn.cursor() +db = resultsdb.connect(args.db) +cursor = db.cursor() def dateStr(dint): return str(datetime.datetime.fromtimestamp(dint).strftime('%Y-%m-%d %H:%M:%S')) @@ -70,8 +71,7 @@ def modelLink(libname, modelname, extension, text): emails_to_send = {} for branch in branches: try: - cursor.execute("SELECT name FROM [sqlite_master] WHERE type='table' AND name=?", (branch,)) - one = cursor.fetchone() + one = (branch,) if db.tableExists(branch) else None if one == None: print("No such table '%s'; specify it using --branch=XXX when running test.py" % branch) # ignore this table and continue @@ -86,8 +86,8 @@ def modelLink(libname, modelname, extension, text): missing_branches.append(branch) continue - cursor.execute('''CREATE INDEX IF NOT EXISTS [idx_%s_date] ON [%s](date)''' % (branch,branch)) - cursor.execute("SELECT date,omcversion FROM [omcversion] WHERE branch LIKE ? COLLATE NOCASE ORDER BY date ASC", (branch,)) + db.createDateIndex(branch) + cursor.execute("SELECT date,omcversion FROM omcversion WHERE %s ORDER BY date ASC" % db.likeNoCase("branch"), (branch,)) entries = cursor.fetchall() n = len(entries) urlToOpen = "%s/%s/00_history.html" % (historyurl, branch) @@ -152,11 +152,11 @@ def modelLink(libname, modelname, extension, text): gitloglibrarytesting = "could not get the git log for OpenModelicaLibraryTesting" tpl = tpl.replace("#OMCGITLOG#",gitlog).replace("#NUMCOMMITS#",str(gitlog.count(""))).replace("#3rdParty#",thirdPartyChanged).replace("#OMCLIBRARYTESTINGGITLOG#",gitloglibrarytesting) - libnames = [libname for (libname,) in cursor.execute("""SELECT libname FROM [%s] WHERE date=? GROUP BY libname""" % branch, (d2,))] + libnames = [libname for (libname,) in cursor.execute("""SELECT libname FROM %s WHERE date=? GROUP BY libname""" % db.quote(branch), (d2,))] startdates = {} # Get previous date of each library run and group them together for fast queries later for libname in libnames: - ds = cursor.execute("""SELECT date FROM [%s] WHERE date MAX(finalphase)) OR ((MIN(finalphase) >= ?) AND (MAX(frontend) > ?*MIN(frontend) AND MAX(frontend) > ?) OR @@ -179,7 +183,7 @@ def modelLink(libname, modelname, extension, text): (MAX(compile) > ?*MIN(compile) AND MAX(compile) > ?) OR (MAX(simulate) > ?*MIN(simulate) AND MAX(simulate) > ?) ) - """ % (branch,",".join(["'%s'" % libname for libname in startdates[d1lib]])) + """) % (db.quote(branch),",".join(["'%s'" % libname for libname in startdates[d1lib]])) cursor.execute(query, (d1lib,d2,timeMinPhase,timeRel,timeAbs,timeRel,timeAbs,timeRel,timeAbs,timeRel,timeAbs,timeRel,2*timeAbs,timeRel,timeAbs)) regressions += cursor.fetchall() regressions = sorted(regressions, key = lambda x: (x[1],x[0])) @@ -228,10 +232,10 @@ def modelLink(libname, modelname, extension, text): libstrs = [] for libname in sorted(list(libs)): - cursor.execute("SELECT libversion,confighash FROM [libversion] WHERE branch LIKE ? COLLATE NOCASE AND date<=? AND libname=? ORDER BY date DESC LIMIT 1", (branch,d1,libname)) + cursor.execute("SELECT libversion,confighash FROM libversion WHERE %s AND date<=? AND libname=? ORDER BY date DESC LIMIT 1" % db.likeNoCase("branch"), (branch,d1,libname)) (lv1,lh1) = cursor.fetchone() lv1 = lv1.strip() - cursor.execute("SELECT libversion,confighash FROM [libversion] WHERE branch LIKE ? COLLATE NOCASE AND date<=? AND libname=? ORDER BY date DESC LIMIT 1", (branch,d2,libname)) + cursor.execute("SELECT libversion,confighash FROM libversion WHERE %s AND date<=? AND libname=? ORDER BY date DESC LIMIT 1" % db.likeNoCase("branch"), (branch,d2,libname)) (lv2,lh2) = cursor.fetchone() lv2 = lv2.strip() if lv1 != lv2: diff --git a/clean-dates.py b/clean-dates.py index ddafe63..09b831e 100755 --- a/clean-dates.py +++ b/clean-dates.py @@ -1,11 +1,13 @@ #!/usr/bin/env python3 -import argparse, sqlite3, sys +import argparse, sys +import resultsdb from datetime import datetime parser = argparse.ArgumentParser(description='OpenModelica library testing tool') parser.add_argument('startDate') parser.add_argument('stopDate') +resultsdb.addArgument(parser) args = parser.parse_args() @@ -29,12 +31,12 @@ sys.stdout.write("Please respond with 'yes' or 'no'") sys.exit(1) -conn = sqlite3.connect('sqlite3.db') -cursor = conn.cursor() +db = resultsdb.connect(args.db) +cursor = db.cursor() -tables = [tbl for (tbl,) in cursor.execute("SELECT name FROM sqlite_master WHERE type='table'")] +tables = db.tables() for tbl in tables: - cursor.execute("DELETE FROM [%s] WHERE date?" % tbl, (stopTime.timestamp(),startTime.timestamp())) -conn.commit() -conn.execute("VACUUM") -conn.close() + cursor.execute("DELETE FROM %s WHERE date?" % db.quote(tbl), (stopTime.timestamp(),startTime.timestamp())) +db.commit() +db.vacuum() +db.close() diff --git a/clean-empty-omcversion-dates.py b/clean-empty-omcversion-dates.py index 1b0fef4..63aad13 100755 --- a/clean-empty-omcversion-dates.py +++ b/clean-empty-omcversion-dates.py @@ -1,14 +1,16 @@ #!/usr/bin/env python3 -import argparse, sqlite3, sys +import argparse, sys +import resultsdb from datetime import datetime parser = argparse.ArgumentParser(description='OpenModelica library testing tool') +resultsdb.addArgument(parser) args = parser.parse_args() -conn = sqlite3.connect('sqlite3.db') -cursor = conn.cursor() +db = resultsdb.connect(args.db) +cursor = db.cursor() entries = cursor.execute("SELECT date,branch FROM omcversion").fetchall() dropped=0 @@ -20,7 +22,11 @@ branchDates[branch] = set() branchDates[branch].add(date) for branch in branches: - data=cursor.execute("SELECT DISTINCT date FROM [%s]" % branch).fetchall() + # The shared database holds the branches of every machine, including ones + # this one never created a result table for. + if not db.tableExists(branch): + continue + data=cursor.execute("SELECT DISTINCT date FROM %s" % db.quote(branch)).fetchall() for (date,) in data: try: branchDates[branch].remove(date) @@ -28,10 +34,10 @@ pass for date in branchDates[branch]: print("Dropping empty omcversion entry (%d,%s)" % (date,branch)) - cursor.execute("DELETE FROM [omcversion] WHERE date=? AND branch=?", (date,branch)) + cursor.execute("DELETE FROM omcversion WHERE date=? AND branch=?", (date,branch)) dropped += 1 -conn.commit() +db.commit() if dropped>0: - conn.execute("VACUUM") -conn.close() + db.vacuum() +db.close() diff --git a/doc/README.md b/doc/README.md new file mode 100644 index 0000000..5d908a6 --- /dev/null +++ b/doc/README.md @@ -0,0 +1,432 @@ +# The OpenModelicaLibraryTesting result database + +This document describes how the library testing results are stored: the current +sqlite3 layout, what every table and column means, how the scripts query it, and +the PostgreSQL layout the data is being migrated to (issue +[#295](https://github.com/OpenModelica/OpenModelicaLibraryTesting/issues/295)). + +## Where the databases live + +Each test machine keeps a single sqlite3 file called `sqlite3.db` in the working +directory of the test run. The files are published at: + +| machine | URL | on omod-r630-2 | size | tables | rows | +| --- | --- | --- | --- | --- | --- | +| ripper1 | | `/var/www/libraries.openmodelica.org/sqlite3/ripper1/sqlite3.db` | 11.8 GB | 34 | ~69 million | +| ripper2 | | `/var/www/libraries.openmodelica.org/sqlite3/ripper2/sqlite3.db` | 15.5 GB | 54 | ~91 million | + +(sizes as of 2026-08-10; both are at `PRAGMA user_version` 3) + +Every branch/configuration tested on a machine ends up in that machine's file, +which is why the files are large and why two machines cannot test the same job +without overwriting each other's results. The tables are the branches currently +tested (`master`, `newInst-newBackend`, `cpp`, `master-fmi`, `gbode`, `cvode`, +`ida`, `daemode`, ...) plus one per historical release (`v1.9` ... `v1.27`, +`v1.11-fmi` ...). `master` alone holds ~43 million rows on ripper1. + +Six table names exist on both machines - `master`, `newInst`, `heavy_tests`, +`v1.17`, `libversion` and `omcversion` - so a shared database mixes rows from +both. They are distinguished by their `date`, which is unique per run and +machine. + +The scripts always open the file by the hardcoded relative name `sqlite3.db`: +`test.py` writes it, `report.py`, `all-reports.py`, `all-plots.py`, +`single-model.py`, `clean-dates.py` and `clean-empty-omcversion-dates.py` read +it. + +## Schema version + +`test.py` keeps the layout version in sqlite's `PRAGMA user_version` and +migrates on startup (`test.py`, around the `CREATE TABLE` block): + +| user_version | meaning | +| --- | --- | +| 0 | empty/new database; `omcversion` and `libversion` are created | +| 1 | `libversion.confighash` added | +| 2 | `parsing` added to every per-branch table | +| 3 | current layout | + +A database with a higher `user_version` makes `test.py` exit rather than guess. + +## Tables + +### Per-branch result tables + +There is **one table per tested branch/configuration**, named after the branch +(`master`, `gbode`, `ida`, `cvode`, `master-fmi`, `newInst-newBackend`, +`heavy_tests`, ...), created on demand by `test.py`: + +```sql +CREATE TABLE if not exists [] ( + date integer NOT NULL, -- unix epoch: start of the test run + libname text NOT NULL, -- library incl. version suffix, e.g. Buildings_9.1.0 + model text NOT NULL, -- full Modelica class name of the tested model + exectime real NOT NULL, -- wall clock for the whole test of this model [s] + frontend real NOT NULL, -- time in the front end [s] + backend real NOT NULL, -- time in the back end [s] + simcode real NOT NULL, -- time generating SimCode [s] + templates real NOT NULL, -- time running the code generation templates [s] + compile real NOT NULL, -- time compiling the generated code (or building the FMU) [s] + simulate real NOT NULL, -- time simulating [s] + verify real NOT NULL, -- time spent in diffSimulationResults [s] + verifyfail integer NOT NULL, -- number of variables that differ from the reference + verifytotal integer NOT NULL, -- number of variables compared against the reference + finalphase integer NOT NULL, -- how far the model got, see below + parsing real NOT NULL -- time loading/parsing the library [s] +) +``` + +Notes on the values, which are produced by `testmodel.py` and written by +`test.py`: + +- `date` is `int(time.time())` taken **once per test run** (`testRunStartTimeAsEpoch`), + so all rows of one run share the same date. It is the join key to + `omcversion`/`libversion` and the x-axis of every history plot. +- The phase times are exclusive, computed by subtracting the nested OMC timers + from each other (`frontend = frontend - backend`, `backend = backend - simcode`, ...). + A phase that was never reached is stored as `0.0`. +- `compile` is the `build` measurement: `make -f .makefile` for the C + runtime, the FMU build for FMI configurations, and the JIT compile time for + wasm-jit. +- `exectime` is the total wall clock of the model's test process. `test.py` + reads back the most recent value (`SELECT exectime ... ORDER BY date DESC LIMIT 1`) + to sort the queue longest-job-first. +- `verifyfail`/`verifytotal` are `len(diff.vars)` and `diff.numCompared`; a model + without reference variables stores `0`/`0` and still reaches phase 7. + +`finalphase` is the last phase completed; `shared.finalphaseName` maps it to: + +| value | name | meaning | +| --- | --- | --- | +| 0 | Failed | the front end did not finish | +| 1 | FrontEnd | front end ok, back end failed | +| 2 | BackEnd | back end ok, SimCode failed | +| 3 | SimCode | SimCode ok, templates/translation failed | +| 4 | Templates | translated, but compilation/build failed | +| 5 | Compile | built, but the simulation failed | +| 6 | Simulate | simulated, but the result does not verify (or was not compared) | +| 7 | Verify | the result matches the reference file | + +Reports count models per phase with `WHERE finalphase >= i`, so the columns of +the HTML tables are cumulative. + +### `omcversion` + +Maps a test run to the compiler that produced it: + +```sql +CREATE TABLE if not exists [omcversion] ( + date integer NOT NULL, -- same epoch as the result rows of that run + branch text NOT NULL, -- branch/configuration name = result table name + omcversion text NOT NULL -- output of getVersion(), e.g. "OMCompiler v1.26.0-dev.42+g0123abc" +) +``` + +One row per run. `report.py` and `all-reports.py` use it to label a run, and +`all-reports.py` walks it in date order to pair consecutive runs when generating +the regression reports. + +### `libversion` + +Maps a test run to the library versions and configuration used: + +```sql +CREATE TABLE if not exists [libversion] ( + date integer NOT NULL, -- same epoch as the result rows of that run + branch text NOT NULL, + libname text NOT NULL, -- as in the result table + libversion text NOT NULL, -- conf["libraryLastChange"]: version + git revision/zip hash + confighash integer NOT NULL -- hash of the configuration and the reference files +) +``` + +One row per (run, library). `confighash` is `strToHashInt()` over the +configuration dictionary plus the hashes of all reference files, so any change +to the config or to a reference file yields a different value. + +This drives the "do we need to test this at all" decision in `test.py`: before +testing a library it looks for + +```sql +SELECT date,libversion,libname,branch,omcversion FROM [libversion] NATURAL JOIN [omcversion] +WHERE libversion=? AND libname=? AND branch=? AND omcversion=? AND confighash=? ORDER BY date DESC LIMIT 1 +``` + +and skips the library when the exact same combination of library version, OMC +version and configuration was already tested. + +### `datelookup_` (obsolete) + +`datelookup_(date, runDate, libname, branch)` was a cache mapping every +omcversion date to the latest run date of a library. The code that fills it in +`all-plots.py` sits inside a triple-quoted block and is no longer executed; +neither ripper1 nor ripper2 still has such a table. The migration skips them. + +### Indexes + +No index is stored permanently. `test.py` drops `idx__date`, +`idx_omcversion_date` and `idx_libversion_date` on startup (they slow the bulk +insert down), and `report.py`/`all-reports.py`/`all-plots.py` recreate +`idx__date` when they need it. + +## How a test run writes the database + +1. Open `sqlite3.db`, apply the `user_version` migration, `CREATE TABLE IF NOT EXISTS []`. +2. Compute `confighash` per library, skip libraries already covered (query above). +3. Run the tests; each model writes `files/.stat.json`. +4. At the end, in one transaction: one `INSERT` per model into `[]`, one + `INSERT` per library into `[libversion]`, one `INSERT` into `[omcversion]`, + then `conn.commit()`. + +Nothing is written while the tests run, so an aborted run leaves no rows behind, +and two machines running the same job produce two full sets of rows in two +separate files - whichever file is copied back last wins. + +## Housekeeping scripts + +- `clean-dates.py --start --stop`: `DELETE FROM [] WHERE date?` + over every table, then `VACUUM`. Removes a range of bad runs. +- `clean-empty-omcversion-dates.py`: drops `omcversion` rows whose date has no + result rows in the corresponding branch table. + +## PostgreSQL layout + +The PostgreSQL database is a **mirror** of the sqlite3 one: the same tables with +the same names and columns, one table per branch plus `omcversion` and +`libversion`. That way the test scripts can push new results to the network +database with the same statements they use today, and the report scripts need no +query rewriting beyond the sqlite `[name]` / PostgreSQL `"name"` quoting. + +Only the types are adapted: + +| sqlite3 | PostgreSQL | +| --- | --- | +| `integer` | `bigint` (`integer` for `verifyfail`, `verifytotal`, `finalphase`) | +| `real` | `double precision` | +| `text` | `text` | +| `NOT NULL` on every column | only on the key columns, see below | +| `PRAGMA user_version` | not used; the `parsing` column always exists | +| `datelookup_*` | not migrated (derived data, no longer generated) | + +### Keys + +Each table gets a unique key, which sqlite3 never had: + +| table | key | +| --- | --- | +| `` | `(date, libname, model)` - a run tests every model of a library once | +| `omcversion` | `(date, branch)` - one row per run | +| `libversion` | `(date, branch, libname, confighash)` - one row per run and library | + +This is what makes a shared database possible: results from a second test +machine can be merged into a table that already holds another machine's rows, +and a run that is pushed twice cannot produce duplicates. + +Only those key columns are `NOT NULL`. The sqlite3 tables declare every column +`NOT NULL`, but `CREATE TABLE if not exists` means tables created by an older +`test.py` keep their old, laxer declaration, so the historical data does not +necessarily hold up. `libversion.libversion` for instance stores empty strings +for some old runs. + +So a branch table becomes: + +```sql +CREATE TABLE "master" ( + date bigint NOT NULL, + libname text NOT NULL, + model text NOT NULL, + exectime double precision NOT NULL, + frontend double precision NOT NULL, + backend double precision NOT NULL, + simcode double precision NOT NULL, + templates double precision NOT NULL, + compile double precision NOT NULL, + simulate double precision NOT NULL, + verify double precision NOT NULL, + verifyfail integer NOT NULL, + verifytotal integer NOT NULL, + finalphase integer NOT NULL, + parsing double precision NOT NULL +); +``` + +Two things to keep in mind when querying it: + +- Identifiers must be **double quoted**, not bracketed: branch names such as + `newInst-newBackend` contain upper case letters and dashes, which PostgreSQL + would otherwise fold to lower case or reject. +- All test machines write into the same tables, so a run is identified by + `date` (plus `branch`) exactly as before. Use `--pgschema ripper1` if a + machine should be mirrored into a schema of its own instead. + +Indexes are created by `sqlite2postgres.py --index` rather than on the fly: +`(date)` on every table, `(branch, date)` on `omcversion`, +`(branch, libname, date)` on `libversion` and `(libname, date)` on the branch +tables. + +## Using the shared database + +Every script takes `--db`, which is a path to a local sqlite3 file (the default, +`sqlite3.db`) or a `postgresql://` URL: + +```bash +./test.py --branch=master --db=postgresql://om@openmodelica.org/omdb configs/conf.json +./report.py --branches=master --db=postgresql://om@openmodelica.org/omdb configs/conf.json +``` + +The password comes from `PGPASSWORD` or `~/.pgpass`, never from the URL or the +command line. `resultsdb.py` holds the two backends behind one interface; the +scripts write the same statements for both, with `?` as the placeholder, and ask +the connection where the dialects genuinely differ (`quote()`, `tableExists()`, +`groupConcat()`, `countIf()`, `likeNoCase()`, `insertIgnore()`). + +### Job claiming + +The point of the shared database is that two machines can test at the same time +without overwriting each other. Before testing a library, `test.py` claims the +job in + +```sql +CREATE TABLE job_claim ( + branch text, libname text, libversion text, omcversion text, confighash bigint, + host text NOT NULL, state text NOT NULL, + claimed_at timestamptz NOT NULL DEFAULT now(), + heartbeat timestamptz NOT NULL DEFAULT now(), + PRIMARY KEY (branch, libname, libversion, omcversion, confighash) +); +``` + +The key is exactly the question "which library, in which version, against which +compiler and configuration": the same combination the run already uses to decide +whether results exist. A claim is taken with `INSERT ... ON CONFLICT DO UPDATE +... WHERE` so that only one machine can win it, and a machine that loses prints + +``` +Skipping Buildings_9.1.0 as ripper2 has been testing it since 2026-08-10 22:14:03 +``` + +and moves on to the next library instead of repeating the work. The winner +refreshes `heartbeat` every minute from a background thread and sets +`state='done'` when the results are written. A machine that dies stops sending +its heartbeat, and after 30 minutes (`STALE_CLAIM_MINUTES`) another machine may +take its jobs over, so a crash does not park a library forever. + +Nothing of this applies to a local sqlite3 file: it has a single writer, and +`claim()` always says yes. + +### In Jenkins + +The pipeline has a `postgres` parameter, on by default, and sets two variables +for every stage: + +```groovy +environment { + LIBTEST_DB = "${params.postgres ? 'postgresql://om@openmodelica.org/omdb' : 'sqlite3.db'}" + PGPASSFILE = credentials('omdb-pgpass') +} +``` + +`LIBTEST_DB` is where `--db` defaults to, so no invocation has to spell it out, +and `omdb-pgpass` is a Jenkins *secret file* credential holding a single line: + +``` +openmodelica.org:5432:omdb:om: +``` + +libpq reads the password from that file, so it never appears on a command line +or in the build log. `resultsdb.py` takes a private copy of the file when its +permissions let anyone else read it, because libpq silently ignores such a file +and then fails with `fe_sendauth: no password supplied`. + +With `postgres` ticked, a job no longer downloads the machine's `sqlite3.db` +before the run nor publishes it back afterwards - the step that made two +machines overwrite each other. Untick the parameter and the old behaviour is +back, unchanged. + +The test machines need `psycopg2`: `pip3 install psycopg2-binary`, or a rebuild +of the images, since it is in `requirements.txt` and in `.CI/build-dep`. + +## Migrating + +Run this **on omod-r630-2 (openmodelica.org)**: the sqlite3 files and the +PostgreSQL server are on the same machine, so the data never goes over the +network. Pushing it from a developer machine works too, but a home uplink does +0.3-1.8 MB/s, which means hours for ~27 GB. + +```bash +export PGPASSFILE=~/.pgpass # never put the password on the command line +DB=/var/www/libraries.openmodelica.org/sqlite3 +./sqlite2postgres.py --host localhost --sqlite $DB/ripper1/sqlite3.db --source ripper1 +./sqlite2postgres.py --host localhost --index +./sqlite2postgres.py --host localhost --sqlite $DB/ripper2/sqlite3.db --source ripper2 --skip-existing +./sqlite2postgres.py --host localhost --index +./sqlite2postgres.py --host localhost --sqlite $DB/ripper1/sqlite3.db --verify +``` + +The order matters. ripper1 goes in first and without an index, which is the +fast path. `--index` then creates the unique keys, so that ripper2, loaded with +`--skip-existing`, keeps whatever is already there whenever a key collides - +ripper1 wins. The second `--index` covers the tables that only exist on ripper2. + +On the databases as of 2026-08-10 the priority never actually fires: not one +`(branch, date)` is shared between the two machines, not even for the four +branches both of them test, so the merge is a plain union. The rule matters for +re-runs and for two machines pushing results later on. + +### Disk space + +A branch table row measures **212 bytes** in PostgreSQL (measured on `v1.10`, +average `model` length 57, `libname` 17). The whole migration is therefore about + +- 34 GB of table data for the ~160 million rows, plus +- 10-12 GB for the `(date)` and `(libname, date)` indexes. + +so **plan for ~50 GB**. On omod-r630-2 the cluster lives in +`/var/lib/postgresql/16` on the root LV, which has 14 GB free, while the `data` +ZFS pool has 2.9 TB free. Put the database on the pool before loading, e.g. + +```bash +sudo zfs create -o mountpoint=/data/postgres -o compression=lz4 -o recordsize=16k data/postgres +sudo install -d -o postgres -g postgres /data/postgres/omdb +sudo -u postgres psql -c "CREATE TABLESPACE omdb_ts LOCATION '/data/postgres/omdb'" +sudo -u postgres psql -c "ALTER DATABASE omdb SET TABLESPACE omdb_ts" # needs no open connections +``` + +`lz4` on the dataset typically cuts this data to well under half, since the +model names repeat in every run. + +### Catching up with the jobs that are still running + +The migration is a snapshot: a test run that was started before it, or any run +that still writes its own sqlite3 file, adds rows the shared database has never +seen. `--catch-up` copies them over: + +```bash +./sqlite2postgres.py --host localhost --sqlite $DB/ripper1/sqlite3.db --source ripper1 --catch-up +./sqlite2postgres.py --host localhost --sqlite $DB/ripper2/sqlite3.db --source ripper2 --catch-up +``` + +It reads the database from the start and keeps the runs the shared database +does not have, which takes two to three minutes per machine. Not "everything +past the rowid the migration stopped at", tempting as that is: `VACUUM` +renumbers the rowids of these tables and `clean-empty-omcversion-dates.py` runs +one after every test, so that number does not survive a test run. Picking the +runs by date is also what makes it correct for `master`, `newInst`, +`heavy_tests` and `v1.17`, where both machines write into the same table. + +Repeating it costs nothing but the reading: the keys reject anything already +there. Run it once more right after the jobs are switched to the shared +database; from then on nothing writes the sqlite3 files any more and there is +nothing left to catch up with. + +`--source` only names the machine for the bookkeeping table +`migration_progress(source, tbl, last_rowid, rows_read, done)`, which records how +far each sqlite table has been copied. Each batch is committed together with its +progress row, so an interrupted migration continues from the last rowid that +made it in and never copies a batch twice; the command can simply be run again. +Rows are streamed in batches of `--batch` (200000 by default) through +`COPY ... FROM STDIN`, so memory use does not depend on the size of the database. + +`COPY` is used in its text format rather than CSV on purpose: an empty CSV field +reads back as NULL, which would silently turn the empty `libversion` strings in +the old data into NULLs. diff --git a/report.py b/report.py index fe8eafe..97cbd80 100755 --- a/report.py +++ b/report.py @@ -3,11 +3,12 @@ import sys, argparse import simplejson as json -import shared +import shared, resultsdb parser = argparse.ArgumentParser(description='OpenModelica library testing report generation tool') parser.add_argument('configs', nargs='*') parser.add_argument('--branches', default='master') +resultsdb.addArgument(parser) args = parser.parse_args() configs = args.configs @@ -23,7 +24,7 @@ libs = {} -import html, sqlite3, time, datetime +import html, time, datetime from omcommon import friendlyStr, multiple_replace configs_lst = [shared.readConfig(c) for c in configs] @@ -32,8 +33,8 @@ configs = configs + c libnames = set(shared.libname(library,conf) for (library,conf) in configs) -conn = sqlite3.connect('sqlite3.db') -cursor = conn.cursor() +db = resultsdb.connect(args.db) +cursor = db.cursor() nmodels = {} nsimulate = {} @@ -42,7 +43,7 @@ missing_branches = [] for branch in branches: try: - cursor.execute("SELECT date FROM [%s] ORDER BY date DESC LIMIT 1" % branch) + cursor.execute("SELECT date FROM %s ORDER BY date DESC LIMIT 1" % db.quote(branch)) one = cursor.fetchone() if one == None: print("No such table '%s'; specify it using --branch=XXX when running test.py" % branch) @@ -58,18 +59,18 @@ continue dates_str[branch] = str(datetime.datetime.fromtimestamp(v).strftime('%Y-%m-%d %H:%M:%S')) - cursor.execute('''CREATE INDEX IF NOT EXISTS [idx_%s_date] ON [%s](date)''' % (branch,branch)) + db.createDateIndex(branch) dates[branch] = {} branch_nmodels = 0 for libname in libnames: - cursor.execute("SELECT date FROM [%s] WHERE libname=? ORDER BY date DESC LIMIT 1" % branch, (libname,)) + cursor.execute("SELECT date FROM %s WHERE libname=? ORDER BY date DESC LIMIT 1" % db.quote(branch), (libname,)) v = cursor.fetchone() if v is None: dates[branch][libname] = 0 continue dates[branch][libname] = v[0] - for x in cursor.execute("SELECT model FROM [%s] WHERE libname=? AND date=?" % branch, (libname,v[0])): + for x in cursor.execute("SELECT model FROM %s WHERE libname=? AND date=?" % db.quote(branch), (libname,v[0])): if libname not in libs: libs[libname] = set() libs[libname].add(x[0]) @@ -89,7 +90,7 @@ def checkEqual(iterator): for lib in sorted(libs.keys()): models = libs[lib] entries += "

    %s

    \n" % lib - branches_versions = [(cursor.execute("SELECT libversion FROM [libversion] WHERE libname=? AND branch=? ORDER BY date DESC LIMIT 1", (lib,branch)).fetchone() or ["unknown"])[0] for branch in branches] + branches_versions = [(cursor.execute("SELECT libversion FROM libversion WHERE libname=? AND branch=? ORDER BY date DESC LIMIT 1", (lib,branch)).fetchone() or ["unknown"])[0] for branch in branches] all_equal = checkEqual(branches_versions) if not all_equal: entries += "\n" @@ -109,12 +110,12 @@ def checkEqual(iterator): master_models = [] for i in range(0,8): i_models = set() - for v in cursor.execute("SELECT model FROM [%s] WHERE date=? AND finalphase>=? AND libname=?" % (branch), (dates[branch][lib],i,lib)): + for v in cursor.execute("SELECT model FROM %s WHERE date=? AND finalphase>=? AND libname=?" % (db.quote(branch)), (dates[branch][lib],i,lib)): i_models.add(v[0]) master_models.append(i_models) models[branch] = master_models for branch in branches: - vs = [cursor.execute("SELECT COUNT(*) FROM [%s] WHERE date=? AND finalphase>=? AND libname=?" % (branch), (dates[branch][lib],i,lib)).fetchone()[0] for i in range(0,8)] + vs = [cursor.execute("SELECT COUNT(*) FROM %s WHERE date=? AND finalphase>=? AND libname=?" % (db.quote(branch)), (dates[branch][lib],i,lib)).fetchone()[0] for i in range(0,8)] warnings = [] entries += '' % (branch,lib,lib,branch) for i in [0]+list(range(0,len(vs))): @@ -138,8 +139,8 @@ def checkEqual(iterator): entries += "
    %s
    \n" entries += entryhead for branch in branches: - vs = [cursor.execute("SELECT COUNT(*) FROM [%s] WHERE date=? AND finalphase>=? AND libname=?" % (branch), (dates[branch][lib],i,lib)).fetchone()[0] for i in range(0,8)] - sums = [cursor.execute("SELECT SUM(%s) FROM [%s] WHERE date=? AND libname=?" % (fields[i],branch), (dates[branch][lib],lib)).fetchone()[0] or 0 for i in range(0,9)] + vs = [cursor.execute("SELECT COUNT(*) FROM %s WHERE date=? AND finalphase>=? AND libname=?" % (db.quote(branch)), (dates[branch][lib],i,lib)).fetchone()[0] for i in range(0,8)] + sums = [cursor.execute("SELECT SUM(%s) FROM %s WHERE date=? AND libname=?" % (fields[i],db.quote(branch)), (dates[branch][lib],lib)).fetchone()[0] or 0 for i in range(0,9)] entries += '' % (branch,lib,lib,branch) entries += ("\n" % (friendlyStr(sums[0]),friendlyStr(sums[1]),friendlyStr(sums[2]),friendlyStr(sums[3]),friendlyStr(sums[4]),friendlyStr(sums[5]),friendlyStr(sums[6]),friendlyStr(sums[7]),friendlyStr(sums[8]))) exectime[branch] += sums[0] @@ -148,7 +149,7 @@ def checkEqual(iterator): nummodels = sum(len(l) for l in libs.values()) branches_lines = [("%d\n" % (html.escape(branch), html.escape( - (cursor.execute("SELECT omcversion FROM [omcversion] WHERE date=? AND branch=?", (max(dates[branch][lib] for lib in libnames),branch)).fetchone() or ["unknown"])[0] + (cursor.execute("SELECT omcversion FROM omcversion WHERE date=? AND branch=?", (max(dates[branch][lib] for lib in libnames),branch)).fetchone() or ["unknown"])[0] ), html.escape(dates_str[branch]), friendlyStr(exectime[branch]), " class=\"warning\"" if nummodels!=nmodels[branch] else "", nsimulate[branch], diff --git a/requirements.txt b/requirements.txt index bf3dd41..c24fbe9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,4 +5,5 @@ monotonic natsort ompython==3.6 psutil +psycopg2-binary simplejson diff --git a/resultsdb.py b/resultsdb.py new file mode 100644 index 0000000..81f817e --- /dev/null +++ b/resultsdb.py @@ -0,0 +1,405 @@ +#!/usr/bin/env python3 +""" +The result database of the library testing, either local or shared. + +Historically every test machine wrote its results to its own sqlite3 file, +copied in before a run and copied back afterwards, so two machines running the +same job overwrote each other. The scripts can now talk to a shared PostgreSQL +database instead, where the machines coordinate through [job_claim] and nobody +overwrites anybody. + + db = connect("sqlite3.db") # the old local file + db = connect("postgresql://om@openmodelica.org/omdb") # the shared database + +Both backends take the same statements, with "?" as the placeholder. Where the +two dialects genuinely differ - quoting a branch name, testing whether a table +exists, concatenating a group, counting a condition - ask the connection +instead of writing it out, see quote()/tableExists()/groupConcat()/countIf(). + +PostgreSQL needs psycopg2 (pip install psycopg2-binary) and reads the password +from PGPASSWORD or ~/.pgpass, never from the URL. +""" + +import os +import re +import socket +import sqlite3 +import threading +import time + +# A claim older than this without a heartbeat belongs to a machine that died, +# and another machine may take the job over. +STALE_CLAIM_MINUTES = 30 +HEARTBEAT_SECONDS = 60 + +# The columns of a per-branch result table, with the type spelled per backend. +BRANCH_COLUMNS = [ + ("date", "bigint"), ("libname", "text"), ("model", "text"), ("exectime", "real"), + ("frontend", "real"), ("backend", "real"), ("simcode", "real"), ("templates", "real"), + ("compile", "real"), ("simulate", "real"), ("verify", "real"), + ("verifyfail", "int"), ("verifytotal", "int"), ("finalphase", "int"), ("parsing", "real"), +] +SQLITE_TYPES = {"bigint": "integer", "int": "integer", "real": "real", "text": "text"} +POSTGRES_TYPES = {"bigint": "bigint", "int": "integer", "real": "double precision", "text": "text"} + +# What identifies a row, so that two machines writing the same shared table +# cannot store the same result twice. Mirrors sqlite2postgres.py. +KEYS = { + "omcversion": ["date", "branch"], + "libversion": ["date", "branch", "libname", "confighash"], +} +BRANCH_KEY = ["date", "libname", "model"] + +JOB_CLAIM = """ +CREATE TABLE IF NOT EXISTS job_claim ( + branch text NOT NULL, + libname text NOT NULL, + libversion text NOT NULL, + omcversion text NOT NULL, + confighash bigint NOT NULL, + host text NOT NULL, + state text NOT NULL, + claimed_at timestamptz NOT NULL DEFAULT now(), + heartbeat timestamptz NOT NULL DEFAULT now(), + PRIMARY KEY (branch, libname, libversion, omcversion, confighash) +) +""" + + +# Jenkins sets LIBTEST_DB once for the whole pipeline rather than passing --db +# to every script invocation. +DEFAULT_DB = os.environ.get("LIBTEST_DB") or "sqlite3.db" +DB_HELP = ("Result database: a local sqlite3 file, or a postgresql://user@host/database URL for " + "the shared one, taken from the LIBTEST_DB environment variable when not given. " + "Several machines can write to the shared database at the same time; a library " + "another machine is already testing is skipped instead of tested twice. The password " + "is read from PGPASSWORD or ~/.pgpass, never from the URL.") + + +def addArgument(parser): + """Give a script the --db option, spelled the same way everywhere.""" + parser.add_argument("--db", default=DEFAULT_DB, help=DB_HELP) + + +def _fixPgpassPermissions(): + """libpq ignores a password file others can read, and then fails to connect. + + Jenkins hands the credential to the build as a file it created itself, so + rather than have every job remember to chmod it, take a private copy. + """ + path = os.environ.get("PGPASSFILE") + if not path or not os.path.isfile(path): + return + if not (os.stat(path).st_mode & 0o077): + return + import shutil, tempfile + fd, private = tempfile.mkstemp(prefix="pgpass.") + os.close(fd) + os.chmod(private, 0o600) + shutil.copyfile(path, private) + os.environ["PGPASSFILE"] = private + + +def connect(url): + """Open the result database named by url: a path or a postgresql:// URL.""" + if url.startswith("postgres://") or url.startswith("postgresql://"): + return _Postgres(url) + return _Sqlite(url) + + +class _Db: + """What the testing and report scripts use; the backends fill in the rest.""" + + def cursor(self): + return _Cursor(self, self.conn.cursor()) + + def execute(self, sql, params=()): + return self.cursor().execute(sql, params) + + def commit(self): + self.conn.commit() + + def close(self): + self.conn.close() + + def insertIgnore(self): + """The clause that makes an INSERT skip a row that is already there.""" + return "" + + def createDateIndex(self, branch): + """The index the report queries need; test.py drops it before a run.""" + self.execute("CREATE INDEX IF NOT EXISTS %s ON %s (date)" + % (self.quote("idx_%s_date" % branch), self.quote(branch))) + + def claim(self, branch, libname, libversion, omcversion, confighash): + """True when this machine may test that library, False when another one is. + + Only the shared database can say no; a local file has a single writer. + """ + return True + + def claimedBy(self, branch, libname, libversion, omcversion, confighash): + return ("this machine", None) + + def release(self): + """Mark the claims of this run as finished.""" + + def vacuum(self): + self.conn.execute("VACUUM") + + +class _Cursor: + """A cursor that takes "?" placeholders whatever the backend wants.""" + + def __init__(self, db, cursor): + self.db = db + self.cursor = cursor + + def execute(self, sql, params=()): + # psycopg2 only looks for placeholders when parameters are passed, so a + # statement without any must not be handed an empty tuple. + params = tuple(params) + self.cursor.execute(self.db.sql(sql, bool(params)), self.db.params(params)) + return self + + def fetchone(self): + return self.cursor.fetchone() + + def fetchall(self): + return self.cursor.fetchall() + + def __iter__(self): + return iter(self.cursor) + + +class _Sqlite(_Db): + """The per-machine sqlite3 file the testing has always used.""" + + name = "sqlite3" + + def __init__(self, path): + self.conn = sqlite3.connect(path) + self.path = path + + def sql(self, sql, hasParams=False): + return sql + + def params(self, params): + return params + + def quote(self, ident): + """Quote a table or column name, typically a branch name.""" + return "[%s]" % ident + + def createTables(self, branch): + """The schema migration test.py has always done, plus the branch table.""" + cursor = self.cursor() + user_version = self.userVersion() + if user_version == 0: + # Table to lookup from a run (date, branch) to omcversion used + cursor.execute("CREATE TABLE if not exists [omcversion] (date integer NOT NULL, branch text NOT NULL, omcversion text NOT NULL)") + # Table to lookup from a run (date, branch) which library versions were used + cursor.execute("CREATE TABLE if not exists [libversion] (date integer NOT NULL, branch text NOT NULL, libname text NOT NULL, libversion text NOT NULL, confighash integer NOT NULL)") + elif user_version == 1: + cursor.execute("ALTER TABLE [libversion] ADD COLUMN confighash integer NOT NULL DEFAULT(0)") + elif user_version == 2: + for tbl in [t for t in self.tables() if t not in ["libversion", "omcversion"]]: + cursor.execute("ALTER TABLE [%s] ADD COLUMN parsing real NOT NULL DEFAULT(0.0)" % tbl) + elif user_version != 3: + raise SystemExit("Unknown schema user_version=%d" % user_version) + + cols = ", ".join("%s %s NOT NULL" % (c, SQLITE_TYPES[t]) for c, t in BRANCH_COLUMNS) + cursor.execute("CREATE TABLE if not exists %s (%s)" % (self.quote(branch), cols)) + # The indexes only slow the run's inserts down; the report scripts add them back. + cursor.execute("DROP INDEX IF EXISTS [idx_%s_date]" % branch) + cursor.execute("DROP INDEX IF EXISTS idx_omcversion_date") + cursor.execute("DROP INDEX IF EXISTS idx_libversion_date") + self.setUserVersion(3) + + def tables(self): + return [t for (t,) in self.conn.execute("SELECT name FROM sqlite_master WHERE type='table'")] + + def tableExists(self, name): + return self.conn.execute( + "SELECT 1 FROM sqlite_master WHERE type='table' AND name=?", (name,)).fetchone() is not None + + def groupConcat(self, expr, orderBy=None): + # sqlite keeps the order of the subquery that feeds the aggregate. + return "GROUP_CONCAT(%s)" % expr + + def countIf(self, cond): + return "COUNT(%s or null)" % cond + + def likeNoCase(self, column): + """A case insensitive comparison against a "?" placeholder.""" + return "%s LIKE ? COLLATE NOCASE" % column + + def userVersion(self): + return self.conn.execute("PRAGMA user_version").fetchone()[0] + + def setUserVersion(self, v): + self.conn.execute("PRAGMA user_version=%d" % v) + + +class _Postgres(_Db): + """The shared database several test machines write to at the same time.""" + + name = "postgresql" + + def __init__(self, url): + try: + import psycopg2 + except ImportError: + raise SystemExit("PostgreSQL support needs psycopg2: pip install psycopg2-binary") + # The password belongs in PGPASSWORD or ~/.pgpass, not in the URL. + _fixPgpassPermissions() + self.url = url + self.conn = psycopg2.connect(url) + self.conn.autocommit = False + self.host = socket.gethostname() + self.claims = [] + self.heartbeatThread = None + self.execute(JOB_CLAIM) + self.commit() + + def sql(self, sql, hasParams=False): + """sqlite spells the placeholder "?" and psycopg2 spells it "%s". + + psycopg2 also reads "%" itself, so a literal one has to be doubled - but + only in a statement that has parameters at all. + """ + if not hasParams: + return sql + return sql.replace("%", "%%").replace("?", "%s") + + def params(self, params): + # psycopg2 only looks for placeholders when parameters are passed, so a + # statement without any must not be handed an empty tuple. + return params or None + + def quote(self, ident): + return '"%s"' % ident.replace('"', '""') + + def createTables(self, branch): + """Create the shared tables, with the keys that keep the machines apart. + + Unlike sqlite there is no schema migration and the indexes stay: other + machines are reading the table while this one writes its few thousand rows. + """ + cursor = self.cursor() + cursor.execute("""CREATE TABLE IF NOT EXISTS omcversion ( + date bigint NOT NULL, branch text NOT NULL, omcversion text)""") + cursor.execute("""CREATE TABLE IF NOT EXISTS libversion ( + date bigint NOT NULL, branch text NOT NULL, libname text NOT NULL, + libversion text, confighash bigint NOT NULL)""") + cols = ", ".join("%s %s%s" % (c, POSTGRES_TYPES[t], " NOT NULL" if c in BRANCH_KEY else "") + for c, t in BRANCH_COLUMNS) + cursor.execute("CREATE TABLE IF NOT EXISTS %s (%s)" % (self.quote(branch), cols)) + for tbl in ["omcversion", "libversion", branch]: + key = KEYS.get(tbl, BRANCH_KEY) + cursor.execute("CREATE UNIQUE INDEX IF NOT EXISTS %s ON %s (%s)" + % (self.quote(("uq_%s_%s" % (tbl, "_".join(key)))[:63]), + self.quote(tbl), ",".join(key))) + cursor.execute("CREATE INDEX IF NOT EXISTS %s ON %s (libname, date)" + % (self.quote(("idx_%s_libname_date" % branch)[:63]), self.quote(branch))) + self.commit() + + def tables(self): + return [t for (t,) in self.execute( + "SELECT tablename FROM pg_tables WHERE schemaname=current_schema()")] + + def tableExists(self, name): + return self.execute("SELECT 1 FROM pg_tables WHERE schemaname=current_schema() AND tablename=?", + (name,)).fetchone() is not None + + def groupConcat(self, expr, orderBy=None): + if orderBy: + return "string_agg(%s::text, ',' ORDER BY %s)" % (expr, orderBy) + return "string_agg(%s::text, ',')" % expr + + def countIf(self, cond): + return "COUNT(*) FILTER (WHERE %s)" % cond + + def likeNoCase(self, column): + return "%s ILIKE ?" % column + + def insertIgnore(self): + # Another machine may have written the same run already; its row wins. + return " ON CONFLICT DO NOTHING" + + def createDateIndex(self, branch): + """Nothing to do: date is the first column of the table's unique key.""" + + def userVersion(self): + return 3 + + def setUserVersion(self, v): + pass + + def vacuum(self): + """Nothing to do: PostgreSQL has autovacuum, and a manual VACUUM of a + 50 GB database after every test run would be a waste of the machine.""" + + def claim(self, branch, libname, libversion, omcversion, confighash): + """Take the job unless another machine is running it right now. + + The claim is one row per (branch, library version, omc version, config). + A machine that dies stops sending its heartbeat, and after + STALE_CLAIM_MINUTES its jobs are up for grabs again. + """ + key = (branch, libname, libversion, omcversion, confighash) + got = self.execute("""INSERT INTO job_claim + (branch, libname, libversion, omcversion, confighash, host, state) + VALUES (?,?,?,?,?,?,'running') + ON CONFLICT (branch, libname, libversion, omcversion, confighash) DO UPDATE + SET host = EXCLUDED.host, state = 'running', claimed_at = now(), heartbeat = now() + WHERE job_claim.state <> 'running' + OR job_claim.heartbeat < now() - interval '%d minutes' + RETURNING host""" % STALE_CLAIM_MINUTES, + key + (self.host,)).fetchone() + self.commit() + if got is None: + return False + self.claims.append(key) + self._startHeartbeat() + return True + + def claimedBy(self, branch, libname, libversion, omcversion, confighash): + """The machine holding that job, for the message telling the user why we skip.""" + row = self.execute("""SELECT host, claimed_at FROM job_claim WHERE branch=? AND libname=? + AND libversion=? AND omcversion=? AND confighash=?""", + (branch, libname, libversion, omcversion, confighash)).fetchone() + return row or ("unknown", None) + + def _startHeartbeat(self): + if self.heartbeatThread is not None: + return + # A daemon thread: the run must not wait for it on the way out. + def beat(): + while self.claims: + time.sleep(HEARTBEAT_SECONDS) + try: + self._heartbeat() + except Exception as e: + print("Failed to update the job claims: %s" % e) + self.heartbeatThread = threading.Thread(target=beat, daemon=True) + self.heartbeatThread.start() + + def _heartbeat(self): + # A separate connection: the main one is in the middle of the run's work. + import psycopg2 + with psycopg2.connect(self.url) as conn: + with conn.cursor() as cur: + for (branch, libname, libversion, omcversion, confighash) in list(self.claims): + cur.execute("""UPDATE job_claim SET heartbeat = now() WHERE branch=%s AND libname=%s + AND libversion=%s AND omcversion=%s AND confighash=%s AND host=%s""", + (branch, libname, libversion, omcversion, confighash, self.host)) + + def release(self): + for (b, libname, libversion, omcversion, confighash) in self.claims: + self.execute("""UPDATE job_claim SET state='done', heartbeat=now() + WHERE branch=? AND libname=? AND libversion=? AND omcversion=? AND confighash=? + AND host=?""", + (b, libname, libversion, omcversion, confighash, self.host)) + self.claims = [] + self.commit() diff --git a/single-model.py b/single-model.py index d72e769..3d9af2b 100755 --- a/single-model.py +++ b/single-model.py @@ -3,11 +3,12 @@ import sys, argparse import simplejson as json -import shared +import shared, resultsdb parser = argparse.ArgumentParser(description='OpenModelica model testing report generation tool') parser.add_argument('models', nargs='*') parser.add_argument('--branch', default='') +resultsdb.addArgument(parser) args = parser.parse_args() @@ -21,28 +22,28 @@ libs = {} -import cgi, sqlite3, time, datetime +import cgi, time, datetime from omcommon import friendlyStr, multiple_replace -conn = sqlite3.connect('sqlite3.db') -cursor = conn.cursor() +db = resultsdb.connect(args.db) +cursor = db.cursor() try: - cursor.execute("SELECT name FROM [sqlite_master] WHERE type='table' AND name=?", (branch,)) - v = cursor.fetchone()[0] + if not db.tableExists(branch): + raise Exception("no table") except: raise Exception("No such table '%s'; specify it using --branch=XXX" % branch) for model in models: lines=[] c=0 - libnames = [libname for (libname,) in cursor.execute("SELECT DISTINCT libname FROM [%s] WHERE model=? ORDER BY libname ASC" % (branch), (model,))] + libnames = [libname for (libname,) in cursor.execute("SELECT DISTINCT libname FROM %s WHERE model=? ORDER BY libname ASC" % (db.quote(branch)), (model,))] for libname in libnames: - for (finalphase,dint,libversion) in cursor.execute("SELECT finalphase,date,libversion FROM [%s] NATURAL JOIN [libversion] WHERE model=? AND libname=? ORDER BY date ASC" % (branch), (model,libname)): + for (finalphase,dint,libversion) in cursor.execute("SELECT finalphase,date,libversion FROM %s NATURAL JOIN libversion WHERE model=? AND libname=? ORDER BY date ASC" % (db.quote(branch)), (model,libname)): c+=1 dstr = str(datetime.datetime.fromtimestamp(dint).strftime('%Y-%m-%d %H:%M:%S')) - cursor2 = conn.cursor() - omcversion = cursor2.execute("SELECT omcversion FROM [omcversion] WHERE date=? AND branch=?", (dint,branch)).fetchone()[0] + cursor2 = db.cursor() + omcversion = cursor2.execute("SELECT omcversion FROM omcversion WHERE date=? AND branch=?", (dint,branch)).fetchone()[0] omcversion = omcversion.replace("OpenModelica ","").replace("OMCompiler ","") lines.insert(0, "%s %s %s %s" % (dstr,shared.finalphaseName(finalphase),omcversion,libversion.strip())) if c==0: diff --git a/sqlite2postgres.py b/sqlite2postgres.py new file mode 100644 index 0000000..850d445 --- /dev/null +++ b/sqlite2postgres.py @@ -0,0 +1,406 @@ +#!/usr/bin/env python3 +""" +Migrate OpenModelicaLibraryTesting sqlite3 result databases into PostgreSQL. + +The PostgreSQL layout is a 1:1 mirror of the sqlite3 one: one table per branch +with the same columns, plus the [omcversion] and [libversion] lookup tables. +Only the types are adapted (integer -> bigint, real -> double precision). + +Only the python standard library is used; the psql client binary does the +talking, so nothing has to be installed on the test machines. The password is +never passed on the command line - use PGPASSFILE or PGPASSWORD, as understood +by psql. + +Typical use: + + export PGPASSFILE=~/.pgpass + ./sqlite2postgres.py --sqlite dbs/ripper1.db --source ripper1 + ./sqlite2postgres.py --index + ./sqlite2postgres.py --sqlite dbs/ripper2.db --source ripper2 --skip-existing + ./sqlite2postgres.py --index + +The machines share the tables of the branches they both test, so they are merged +in that order: ripper1 first, then ripper2 with --skip-existing, which keeps the +row already in the database whenever a key collides. --index in between creates +the unique keys that decide what a collision is - (date, libname, model) for a +branch table - so it has to run before the second machine. + +--source only names the machine for the resume bookkeeping; it is not stored in +the data. Use --pgschema ripper1 to keep a machine in a schema of its own +instead of merging. + +The migration is resumable and safe to re-run: how far each table has been +copied is recorded in [migration_progress], and a restart continues from the +last sqlite rowid that made it in. +""" + +import argparse +import io +import os +import sqlite3 +import subprocess +import sys +import time + +# Columns of a per-branch table, in the order used by test.py. Databases with +# PRAGMA user_version < 3 have no "parsing" column. +# +# The sqlite3 tables declare every column NOT NULL, but tables created before +# that declaration still hold NULLs (libversion.libversion has some), so only +# the key columns are NOT NULL here. +BRANCH_COLUMNS = [ + ("date", "bigint"), + ("libname", "text"), + ("model", "text"), + ("exectime", "double precision"), + ("frontend", "double precision"), + ("backend", "double precision"), + ("simcode", "double precision"), + ("templates", "double precision"), + ("compile", "double precision"), + ("simulate", "double precision"), + ("verify", "double precision"), + ("verifyfail", "integer"), + ("verifytotal", "integer"), + ("finalphase", "integer"), + ("parsing", "double precision"), +] + +LOOKUP_COLUMNS = { + "omcversion": [("date", "bigint"), ("branch", "text"), ("omcversion", "text")], + "libversion": [("date", "bigint"), ("branch", "text"), ("libname", "text"), + ("libversion", "text"), ("confighash", "bigint")], +} + +# Derived data, no longer generated by all-plots.py; not worth migrating. +SKIP_PREFIXES = ("datelookup_", "sqlite_") + + +# What identifies a row. A test run writes one row per model, so a model +# appears once per (date, libname); the lookup tables have one row per run and +# per (run, library). --index enforces these, which is what lets a second test +# machine be merged into a table that already holds another machine's results. +KEYS = { + "omcversion": ["date", "branch"], + "libversion": ["date", "branch", "libname", "confighash"], +} +BRANCH_KEY = ["date", "libname", "model"] + +PROGRESS_TABLE = """ +CREATE TABLE IF NOT EXISTS "migration_progress" ( + source text NOT NULL, + tbl text NOT NULL, + last_rowid bigint NOT NULL, + rows_read bigint NOT NULL, + done boolean NOT NULL DEFAULT false, + updated_at timestamptz NOT NULL DEFAULT now(), + PRIMARY KEY (source, tbl) +) +""" + + +def lit(s): + """Quote a python value as an SQL string literal.""" + return "'" + str(s).replace("'", "''") + "'" + + +def ident(s): + """Quote an SQL identifier. Branch names contain '-' and upper case.""" + return '"' + s.replace('"', '""') + '"' + + +def copy_text(v): + """Encode one value for COPY's text format. + + Not CSV: an empty CSV field reads back as NULL, and libversion.libversion + does contain empty strings that have to stay empty strings. The text format + spells NULL \\N instead, so both survive. + """ + if v is None: + return "\\N" + return (str(v).replace("\\", "\\\\").replace("\n", "\\n") + .replace("\r", "\\r").replace("\t", "\\t")) + + +class Psql: + """Runs SQL through the psql client, which keeps this script dependency-free.""" + + def __init__(self, args): + self.base = ["psql", "--no-psqlrc", "-w", "-v", "ON_ERROR_STOP=1", + "-h", args.host, "-p", str(args.port), "-U", args.user, "-d", args.dbname] + self.schema = args.pgschema + + def _run(self, argv, stdin=None): + p = subprocess.run(self.base + argv, input=stdin, capture_output=True, text=True) + if p.returncode != 0: + raise RuntimeError("psql failed: %s" % (p.stderr.strip() or p.stdout.strip())) + return p.stdout + + def query(self, sql): + """Execute SQL and return the output unaligned and without headers.""" + return self._run(["-tAq", "-c", "SET search_path TO %s; %s" % (ident(self.schema), sql)]).strip() + + def script(self, sql): + return self._run(["-q", "-f", "-"], stdin="SET search_path TO %s;\n%s" % (ident(self.schema), sql)) + + def copy_rows(self, table, columns, rows, also="", skip_existing=None): + """COPY an iterable of tuples into a table. + + The statements in "also" are committed together with the batch, so that a + migration killed halfway through never copies the same rows twice. + + With skip_existing set to the key columns of the table, the batch goes + through a temporary table first and rows that are already there are + dropped, so the machine migrated first keeps its results. + """ + cols = ",".join(ident(c) for c in columns) + target = ident(table) + buf = io.StringIO() + buf.write("SET search_path TO %s;\nBEGIN;\n" % ident(self.schema)) + if skip_existing: + buf.write("CREATE TEMP TABLE batch (LIKE %s) ON COMMIT DROP;\n" % target) + target = "batch" + buf.write("COPY %s (%s) FROM STDIN;\n" % (target, cols)) + for r in rows: + buf.write("\t".join(copy_text(v) for v in r)) + buf.write("\n") + buf.write("\\.\n") + if skip_existing: + key = ",".join(ident(c) for c in skip_existing) + # DISTINCT ON also drops rows the batch itself holds twice, which the + # unique index would otherwise reject. + buf.write("INSERT INTO %s (%s) SELECT DISTINCT ON (%s) %s FROM batch ORDER BY %s" + " ON CONFLICT DO NOTHING;\n" % (ident(table), cols, key, cols, key)) + if also: + buf.write(also.rstrip().rstrip(";") + ";\n") + buf.write("COMMIT;\n") + if not skip_existing: + self._run(["-q", "-f", "-"], stdin=buf.getvalue()) + return None + # Without -q psql reports every statement, so the INSERT says how many rows + # were new - the interesting number when catching up with a running test. + out = self._run(["-f", "-"], stdin=buf.getvalue()) + for line in out.split("\n"): + if line.startswith("INSERT "): + return int(line.split()[-1]) + return 0 + + +def sqlite_tables(conn): + """The tables of a testing database, split into (branch tables, lookup tables).""" + names = [n for (n,) in conn.execute( + "SELECT name FROM sqlite_master WHERE type='table' ORDER BY name")] + branches, lookups = [], [] + for n in names: + if any(n.startswith(p) for p in SKIP_PREFIXES): + continue + (lookups if n in LOOKUP_COLUMNS else branches).append(n) + return branches, lookups + + +def sqlite_columns(conn, tbl): + return [row[1] for row in conn.execute("PRAGMA table_info(%s)" % ident(tbl))] + + +def create_table(pg, tbl, columns): + key = KEYS.get(tbl, BRANCH_KEY) + cols = ",\n ".join("%s %s%s" % (ident(c), t, " NOT NULL" if c in key else "") + for c, t in columns) + pg.script("CREATE TABLE IF NOT EXISTS %s (\n %s\n);" % (ident(tbl), cols)) + + +def read_progress(pg, source, tbl): + out = pg.query("SELECT last_rowid, rows_read, done FROM migration_progress " + "WHERE source=%s AND tbl=%s" % (lit(source), lit(tbl))) + if not out: + return 0, 0, False + last, rows, done = out.split("|") + return int(last), int(rows), done == "t" + + +def progress_sql(source, tbl, last_rowid, rows_read, done): + return ("""INSERT INTO migration_progress (source, tbl, last_rowid, rows_read, done, updated_at) + VALUES (%s, %s, %d, %d, %s, now()) + ON CONFLICT (source, tbl) DO UPDATE SET + last_rowid = EXCLUDED.last_rowid, rows_read = EXCLUDED.rows_read, + done = EXCLUDED.done, updated_at = now()""" + % (lit(source), lit(tbl), last_rowid, rows_read, "true" if done else "false")) + + +def migrate_table(pg, sconn, source, tbl, columns, batch, quiet, skip_existing=False, + catch_up=False): + """Copy one sqlite table into its PostgreSQL twin, in resumable batches.""" + names = [c for c, _ in columns] + have = sqlite_columns(sconn, tbl) + missing = [c for c in names if c not in have] + # Older databases lack "parsing"; test.py defaults it to 0.0 as well. + select = ",".join(ident(c) if c in have else "0" for c in names) + + create_table(pg, tbl, columns) + last_rowid, rows_read, done = read_progress(pg, source, tbl) + if done and not catch_up: + if not quiet: + print(" %-30s done earlier (%d rows)" % (tbl, rows_read)) + return rows_read, 0 + + stored = None + if catch_up: + # Read the table from the start and keep the runs the database has never + # seen. Not "everything past the rowid we stopped at": VACUUM renumbers + # the rowids of these tables, and clean-empty-omcversion-dates.py runs one + # after every test, so that number cannot be trusted between two runs. + stored = set(int(d) for d in pg.query("SELECT DISTINCT date FROM %s" % ident(tbl)).split("\n") if d) + last_rowid, rows_read = 0, 0 + skip_existing = True + key = KEYS.get(tbl, BRANCH_KEY) if skip_existing else None + if not quiet: + extra = "" + if missing: + extra = ", %s defaulted to 0" % ",".join(missing) + if catch_up: + extra += ", %d runs already stored" % len(stored) + elif last_rowid: + extra += ", resuming after rowid %d" % last_rowid + print(" %-30s starting%s" % (tbl, extra)) + + t0 = time.time() + inserted = 0 + date = names.index("date") + while True: + chunk = sconn.execute( + "SELECT rowid,%s FROM %s WHERE rowid > ? ORDER BY rowid LIMIT %d" + % (select, ident(tbl), batch), (last_rowid,)).fetchall() + if not chunk: + break + last_rowid = chunk[-1][0] + rows_read += len(chunk) + rows = [row[1:] for row in chunk] + if stored is not None: + rows = [r for r in rows if r[date] not in stored] + if rows: + n = pg.copy_rows(tbl, names, rows, + also=progress_sql(source, tbl, last_rowid, rows_read, False), + skip_existing=key) + inserted += n if n is not None else len(rows) + if not quiet: + sys.stdout.write("\r %-30s %d rows read, %d new (%.0f rows/s)" + % (tbl, rows_read, inserted, rows_read / max(time.time() - t0, 1e-9))) + sys.stdout.flush() + + pg.query(progress_sql(source, tbl, last_rowid, rows_read, True)) + if not quiet and (inserted or not catch_up): + print("\r %-30s %d rows read, %d new%s" % (tbl, rows_read, inserted, " " * 30)) + return rows_read, inserted + + +def migrate_database(pg, args): + sconn = sqlite3.connect("file:%s?mode=ro" % os.path.abspath(args.sqlite), uri=True) + branches, lookups = sqlite_tables(sconn) + if args.only: + branches = [b for b in branches if b in args.only] + lookups = [l for l in lookups if l in args.only] + print("%s: %d branch tables, lookup tables: %s" + % (args.sqlite, len(branches), ",".join(lookups) or "none")) + + total = new = 0 + for tbl in lookups + branches: + cols = LOOKUP_COLUMNS.get(tbl, BRANCH_COLUMNS) + (r, i) = migrate_table(pg, sconn, args.source, tbl, cols, args.batch, args.quiet, + args.skip_existing, args.catch_up) + total += r + new += i + sconn.close() + print("%s: %d rows read, %d new" % (args.sqlite, total, new)) + + +def create_indexes(pg): + """The unique key of each table, plus the index the reports need. + + The unique index has to exist before a second test machine is migrated with + --skip-existing. It also covers the [date] index the report scripts create + on the fly in sqlite, since date is its first column. + """ + tables = [t for t in pg.query( + "SELECT tablename FROM pg_tables WHERE schemaname=current_schema() ORDER BY tablename").split("\n") if t] + + def index(tbl, cols, unique=False): + name = ("%s_%s_%s" % ("uq" if unique else "idx", tbl, "_".join(cols)))[:63] + pg.script("CREATE %sINDEX IF NOT EXISTS %s ON %s (%s);" + % ("UNIQUE " if unique else "", ident(name), ident(tbl), + ",".join(ident(c) for c in cols))) + + for tbl in tables: + if tbl == "migration_progress": + continue + index(tbl, KEYS.get(tbl, BRANCH_KEY), unique=True) + if tbl == "omcversion": + index(tbl, ["branch", "date"]) + elif tbl == "libversion": + index(tbl, ["branch", "libname", "date"]) + else: + index(tbl, ["libname", "date"]) + print(" indexed %s" % tbl) + + +def verify(pg, args): + """Compare the sqlite and PostgreSQL row counts table by table.""" + sconn = sqlite3.connect("file:%s?mode=ro" % os.path.abspath(args.sqlite), uri=True) + branches, lookups = sqlite_tables(sconn) + bad = 0 + for tbl in lookups + branches: + (n,) = sconn.execute("SELECT COUNT(*) FROM %s" % ident(tbl)).fetchone() + m = int(pg.query("SELECT COUNT(*) FROM %s" % ident(tbl)) or 0) + flag = "ok" if m >= n else "MISSING" + if m < n: + bad += 1 + print(" %-30s sqlite %10d postgres %10d %s" % (tbl, n, m, flag)) + sconn.close() + print("%d of %d tables incomplete" % (bad, len(lookups) + len(branches))) + return bad + + +def main(): + parser = argparse.ArgumentParser(description=__doc__, + formatter_class=argparse.RawDescriptionHelpFormatter) + parser.add_argument("--sqlite", help="sqlite3 database to migrate") + parser.add_argument("--source", help="machine the database comes from, e.g. ripper1; used for resuming") + parser.add_argument("--host", default=os.environ.get("PGHOST", "openmodelica.org")) + parser.add_argument("--port", type=int, default=int(os.environ.get("PGPORT", 5432))) + parser.add_argument("--user", default=os.environ.get("PGUSER", "om")) + parser.add_argument("--dbname", default=os.environ.get("PGDATABASE", "omdb")) + parser.add_argument("--pgschema", default="public", help="PostgreSQL schema to write to (default public)") + parser.add_argument("--batch", type=int, default=200000, help="rows per COPY batch (default 200000)") + parser.add_argument("--only", action="append", help="migrate only this table (repeatable)") + parser.add_argument("--catch-up", action="store_true", + help="copy the runs written since the last migration, for a test that was " + "still using the sqlite3 database. Reads the whole database but only " + "writes the runs it does not have; safe to repeat") + parser.add_argument("--skip-existing", action="store_true", + help="keep the rows already in the database when a key collides; " + "use it for every machine after the first one, and run --index before") + parser.add_argument("--index", action="store_true", help="create the indexes; do this after loading") + parser.add_argument("--verify", action="store_true", help="compare row counts with --sqlite") + parser.add_argument("--quiet", action="store_true") + args = parser.parse_args() + + pg = Psql(args) + pg.script("CREATE SCHEMA IF NOT EXISTS %s;" % ident(args.pgschema)) + pg.script(PROGRESS_TABLE) + + if args.sqlite and not args.verify: + if not args.source: + parser.error("--sqlite needs --source, the machine name, e.g. ripper1") + migrate_database(pg, args) + + if args.index: + print("creating indexes") + create_indexes(pg) + + if args.verify: + if not args.sqlite: + parser.error("--verify needs --sqlite") + sys.exit(1 if verify(pg, args) else 0) + + +if __name__ == "__main__": + main() diff --git a/test.py b/test.py index affc5e3..b6ca625 100755 --- a/test.py +++ b/test.py @@ -8,7 +8,7 @@ if (sys.version_info < (3, 0)): raise Exception("Python2 is no longer supported") -import html, shutil, os, re, glob, time, argparse, sqlite3, datetime, math, platform +import html, shutil, os, re, glob, time, argparse, datetime, math, platform from joblib import Parallel, delayed import simplejson as json import psutil, subprocess, threading, hashlib @@ -18,7 +18,7 @@ from natsort import natsorted from shared import readConfig, getReferenceFileName, simulationAcceptsFlag, isFMPy from platform import processor -import shared +import shared, resultsdb import signal @@ -47,6 +47,7 @@ parser.add_argument('--msysEnvironment', help = 'MSYS2 environment used by OpenModelica on Windows.', default = 'ucrt64') parser.add_argument('--debug', action="store_true", help="turn on the DEBUG mode", default=False) parser.add_argument('--addmsl', action="store_true", help="add the MSL path to the OPENMODELICAPATH if the MSL is not detected in the libraries path", default=False) +resultsdb.addArgument(parser) args = parser.parse_args() configs = args.configs @@ -557,43 +558,10 @@ def testHelloWorld(cmd): # Create mos-files -conn = sqlite3.connect('sqlite3.db') -cursor = conn.cursor() - -user_version = cursor.execute("PRAGMA user_version").fetchone()[0] - -if user_version==0: - # BOOLEAN NOT NULL CHECK (verify IN (0,1) AND builds IN (0,1) AND simulates IN (0,1)) - # Table to lookup from a run (date, branch) to omcversion used - cursor.execute("CREATE TABLE if not exists [omcversion] (date integer NOT NULL, branch text NOT NULL, omcversion text NOT NULL)") - # Table to lookup from a run (date, branch) which library versions were used - cursor.execute("CREATE TABLE if not exists [libversion] (date integer NOT NULL, branch text NOT NULL, libname text NOT NULL, libversion text NOT NULL, confighash integer NOT NULL)") -elif user_version==1: - cursor.execute("ALTER TABLE [libversion] ADD COLUMN confighash integer NOT NULL DEFAULT(0)") -elif user_version==2: - tables = [tbl for (tbl,) in cursor.execute("SELECT name FROM sqlite_master WHERE type='table'") if tbl not in ["libversion","omcversion"]] - for tbl in tables: - cursor.execute("ALTER TABLE [%s] ADD COLUMN parsing real NOT NULL DEFAULT(0.0)" % tbl) -elif user_version in [3]: - pass -else: - print("Unknown schema user_version=%d" % user_version) - sys.exit(1) - -def createBranchTable(branch): - """A run fills one table per FMI simulator, so this happens more than once.""" - cursor.execute('''CREATE TABLE if not exists [%s] - (date integer NOT NULL, libname text NOT NULL, model text NOT NULL, exectime real NOT NULL, - frontend real NOT NULL, backend real NOT NULL, simcode real NOT NULL, templates real NOT NULL, compile real NOT NULL, simulate real NOT NULL, - verify real NOT NULL, verifyfail integer NOT NULL, verifytotal integer NOT NULL, finalphase integer NOT NULL, parsing real NOT NULL)''' % branch) - cursor.execute('''DROP INDEX IF EXISTS [idx_%s_date]''' % branch) - -createBranchTable(primaryBranch) -cursor.execute('''DROP INDEX IF EXISTS idx_omcversion_date''') -cursor.execute('''DROP INDEX IF EXISTS idx_libversion_date''') - -# Set user_version to the current schema -cursor.execute("PRAGMA user_version=3") +db = resultsdb.connect(args.db) +cursor = db.cursor() +# One table per simulator, so this happens once per branch the run fills. +db.createTables(primaryBranch) def strToHashInt(s): return int(hashlib.sha1((s+"fixCorruptBuilds-2017-03-26").encode("utf-8")).hexdigest()[0:8],16) @@ -778,11 +746,18 @@ def hashReferenceFiles(s): prefix = conf["ignoreModelPrefix"] res=list(filter(lambda x: not x.startswith(prefix), res)) libName=shared.libname(library, conf) - v = cursor.execute("""SELECT date,libversion,libname,branch,omcversion FROM [libversion] NATURAL JOIN [omcversion] + v = cursor.execute("""SELECT date,libversion,libname,branch,omcversion FROM libversion NATURAL JOIN omcversion WHERE libversion=? AND libname=? AND branch=? AND omcversion=? AND confighash=? ORDER BY date DESC LIMIT 1""", (conf["libraryLastChange"],libName,primaryBranch,omc_version,confighash)).fetchone() if libName in stats_by_libname or libName in skipped_libs: raise Exception("Duplicate libName found: %s" % libName) if v is None or execAllTests: + # On the shared database another machine may already be running this exact + # job; claiming it is what keeps the two from testing the same thing. + if not db.claim(primaryBranch, libName, conf["libraryLastChange"], omc_version, confighash): + (host, since) = db.claimedBy(primaryBranch, libName, conf["libraryLastChange"], omc_version, confighash) + print("Skipping %s as %s has been testing it since %s" % (libName, host, since)) + skipped_libs[libName] = None + continue stats_by_libname[libName] = {"conf":conf, "stats":[]} tests = tests + [(r,library,libName,libName+"_"+r,conf) for r in res] print("Running library %s (%d tests)" % (libName, len(res))) @@ -899,7 +874,7 @@ def expectedExec(c): (model,lib,libName,name,data) = c if "expectedExec" in data: return data["expectedExec"] - cursor.execute("SELECT exectime FROM [%s] WHERE libname = ? AND model = ? ORDER BY date DESC LIMIT 1" % primaryBranch, (libName,model)) + cursor.execute("SELECT exectime FROM %s WHERE libname = ? AND model = ? ORDER BY date DESC LIMIT 1" % db.quote(primaryBranch), (libName,model)) v = cursor.fetchone() data["expectedExec"] = (v or (0.0,))[0] return data["expectedExec"] @@ -1003,17 +978,17 @@ def resultValues(model, libname, data, simulator=None): ) for (resultBranch, simulator) in resultBranches: - createBranchTable(resultBranch) + db.createTables(resultBranch) for key in stats.keys(): (name,model,libname,data)=stats[key] if simulator is None: stats_by_libname[libname]["stats"].append(stats[key]) - cursor.execute("INSERT INTO [%s] VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)" % resultBranch, + cursor.execute("INSERT INTO %s VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)%s" % (db.quote(resultBranch), db.insertIgnore()), resultValues(model, libname, data, simulator)) for libname in stats_by_libname.keys(): confighash = stats_by_libname[libname]["conf"]["confighash"] - cursor.execute("INSERT INTO [libversion] VALUES (?,?,?,?,?)", (testRunStartTimeAsEpoch, resultBranch, libname, stats_by_libname[libname]["conf"]["libraryLastChange"], confighash)) - cursor.execute("INSERT INTO [omcversion] VALUES (?,?,?)", (testRunStartTimeAsEpoch, resultBranch, omc_version)) + cursor.execute("INSERT INTO libversion VALUES (?,?,?,?,?)%s" % db.insertIgnore(), (testRunStartTimeAsEpoch, resultBranch, libname, stats_by_libname[libname]["conf"]["libraryLastChange"], confighash)) + cursor.execute("INSERT INTO omcversion VALUES (?,?,?)%s" % db.insertIgnore(), (testRunStartTimeAsEpoch, resultBranch, omc_version)) """ # Not really a good thing to do; was just done to make generation of the report simpler for libname in skipped_libs.keys(): @@ -1364,7 +1339,8 @@ def artifactSuffix(simulator): print("-- problem during removing of ./files dir") # Do not commit until we have generated and uploaded the reports -conn.commit() -conn.close() +db.commit() +db.release() +db.close() print("all tests done ...") From 5a54c3516f86685172ea57ccfb962608fdad14db Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Tue, 11 Aug 2026 19:16:41 +0200 Subject: [PATCH 429/452] Bind the pgpass credential where there is a workspace to write it to (#299) Every build of the library testing has failed since #296 with org.jenkinsci.plugins.workflow.steps.MissingContextVariableException: Required context class hudson.FilePath is missing before a single stage ran. The password of the results database is a secret file, and Jenkins writes such a file into the workspace of a node; #296 bound it in the environment of the pipeline, which has agent none and therefore no workspace at all. It is now bound where a node exists: in the environment of the two report stages, beside the IDA_EMAIL credential they already bind that way, and around the test run and the cleanup in runRegressiontest, the way withSccache already binds its key. LIBTEST_DB stays in the environment of the pipeline; it is a string and needs nothing. Nothing about how the scripts read the password changes: libpq still finds it through PGPASSFILE. --- Generated by Claude Code. --- .CI/Jenkinsfile | 58 +++++++++++++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 23 deletions(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index 1619e07..007a4b0 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -45,9 +45,6 @@ pipeline { // Where the results go. The scripts take it from here instead of a --db // option on every single invocation. LIBTEST_DB = "${params.postgres ? 'postgresql://om@openmodelica.org/omdb' : 'sqlite3.db'}" - // A secret file holding one pgpass line; libpq reads the password from it, - // so it never reaches a command line or the build log. - PGPASSFILE = credentials('omdb-pgpass') } stages { stage('test') { parallel { @@ -450,6 +447,11 @@ pipeline { GITBRANCHES = 'maintenance/v1.20 maintenance/v1.21 maintenance/v1.22 maintenance/v1.23 maintenance/v1.24 maintenance/v1.25 maintenance/v1.26 maintenance/v1.27 master newInst-newBackend' PYTHONIOENCODING = 'utf-8' IDA_EMAIL = credentials('IDA email') + // A secret file holding one pgpass line; libpq reads the password from + // it, so it never reaches a command line or the build log. It is bound + // per stage because writing the file needs the workspace of a node, + // which the pipeline as a whole does not have (agent none). + PGPASSFILE = credentials('omdb-pgpass') } steps { //sshagent (credentials: ['Hudson-SSH-Key']) { @@ -521,6 +523,11 @@ pipeline { GITBRANCHES_CPP = 'v1.19-cpp v1.20-cpp v1.21-cpp v1.22-cpp v1.23-cpp v1.24-cpp v1.25-cpp cpp v1.26-cpp v1.27-cpp' PYTHONIOENCODING = 'utf-8' IDA_EMAIL = credentials('IDA email') + // A secret file holding one pgpass line; libpq reads the password from + // it, so it never reaches a command line or the build log. It is bound + // per stage because writing the file needs the workspace of a node, + // which the pipeline as a whole does not have (agent none). + PGPASSFILE = credentials('omdb-pgpass') } steps { //sshagent (credentials: ['Hudson-SSH-Key']) { @@ -1009,26 +1016,31 @@ def runRegressiontest(branch, name, extraFlags, omsHash, dbPrefix, sshConfig, om sh 'date' - runSh(""" - export OPENMODELICAHOME="${WORKSPACE}/OpenModelica/${OMCPATH}/build" - export MSLREFERENCE="${MSLREFERENCE}" - export REFERENCEFILES="${REFERENCEFILES}" - export GITREPOS="${GITREPOS}" - export PNLIBREFS="${PNLIBREFS}" - export THERMOFLUIDSTREAMREFS="${THERMOFLUIDSTREAMREFS}" - export THERMOFLUIDSTREAMREFSOM="${THERMOFLUIDSTREAMREFSOM}" - export PREVIOUSHOME="${env.HOME}" - export HOME="${libraryPath}" - # we need to do some crap magic here to make sure python3 finds fmpy as we change the HOME here - # too bad if we cannot do it, just continue - ln -s -t \${HOME} \${PREVIOUSHOME}/.local .local || true - - cd OpenModelicaLibraryTesting - # Force /usr/bin/omc as being used for generating the mos-files. Ensures consistent behavior among all tested OMC versions - stdbuf -oL -eL time ./test.py --ompython_omhome=/usr ${FMI_TESTING_FLAG} --extraflags='${extraFlags}' --extrasimflags='${extrasimflags}' ${testFlags} --branch="${name}" --output="libraries.openmodelica.org:/var/www/libraries.openmodelica.org/branches/${name}/" --libraries='${libraryPath}/.openmodelica/libraries/' --jobs=${jobs} ${libs_config_file} ${params.OLDLIBS ? "configs/conf-old.json configs/conf-nonstandard.json" : ""} || (killall omc ; false) || exit 1 - """) - sh 'date' - sh "cd OpenModelicaLibraryTesting/ && ./clean-empty-omcversion-dates.py" + // The password of the results database comes from a secret file, bound here + // rather than for the pipeline as a whole: writing the file needs the + // workspace of a node, and the pipeline has agent none. + withCredentials([file(credentialsId: 'omdb-pgpass', variable: 'PGPASSFILE')]) { + runSh(""" + export OPENMODELICAHOME="${WORKSPACE}/OpenModelica/${OMCPATH}/build" + export MSLREFERENCE="${MSLREFERENCE}" + export REFERENCEFILES="${REFERENCEFILES}" + export GITREPOS="${GITREPOS}" + export PNLIBREFS="${PNLIBREFS}" + export THERMOFLUIDSTREAMREFS="${THERMOFLUIDSTREAMREFS}" + export THERMOFLUIDSTREAMREFSOM="${THERMOFLUIDSTREAMREFSOM}" + export PREVIOUSHOME="${env.HOME}" + export HOME="${libraryPath}" + # we need to do some crap magic here to make sure python3 finds fmpy as we change the HOME here + # too bad if we cannot do it, just continue + ln -s -t \${HOME} \${PREVIOUSHOME}/.local .local || true + + cd OpenModelicaLibraryTesting + # Force /usr/bin/omc as being used for generating the mos-files. Ensures consistent behavior among all tested OMC versions + stdbuf -oL -eL time ./test.py --ompython_omhome=/usr ${FMI_TESTING_FLAG} --extraflags='${extraFlags}' --extrasimflags='${extrasimflags}' ${testFlags} --branch="${name}" --output="libraries.openmodelica.org:/var/www/libraries.openmodelica.org/branches/${name}/" --libraries='${libraryPath}/.openmodelica/libraries/' --jobs=${jobs} ${libs_config_file} ${params.OLDLIBS ? "configs/conf-old.json configs/conf-nonstandard.json" : ""} || (killall omc ; false) || exit 1 + """) + sh 'date' + sh "cd OpenModelicaLibraryTesting/ && ./clean-empty-omcversion-dates.py" + } // Copying the file back is what made two machines overwrite each other's // results, so it only happens while a job still writes its own sqlite3 file. From dd760131efbf46be91026a2340e2e834aca7d72d Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Tue, 11 Aug 2026 19:29:32 +0200 Subject: [PATCH 430/452] Pass the count of re.sub by keyword (#298) Python 3.13 deprecates giving re.sub its count positionally, so every library test run printed test.py:1046: DeprecationWarning: 'count' is passed as positional argument return (re.sub( ".*model name.*:", "", line,1)).strip() once per job while reading the processor name out of /proc/cpuinfo. The substitution is unchanged; only how the argument is spelled. A run of configs/sanityCheck.json now goes through without a single DeprecationWarning. --- Generated by Claude Code. --- test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test.py b/test.py index b6ca625..e1994b6 100755 --- a/test.py +++ b/test.py @@ -1018,7 +1018,7 @@ def cpu_name(): else: for line in open("/proc/cpuinfo").readlines(): if "model name" in line.strip(): - return (re.sub( ".*model name.*:", "", line,1)).strip() + return (re.sub( ".*model name.*:", "", line, count=1)).strip() if isWin: lsb_release = "" From eb86871e40e3e0855cdfcbf3881f22bbd5f156cc Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Tue, 11 Aug 2026 20:32:18 +0200 Subject: [PATCH 431/452] Make the configuration hash the same on every machine (#303) Two machines testing the same library, with the same compiler and the same library version, claimed it both and tested it both. The claim in #295 is keyed by (branch, libname, libversion, omcversion, confighash), and their confighashes differed, so as far as the database was concerned they were testing different things. The hash is taken over the configuration of the library, and the configuration by then holds the reference files as an absolute path: destinationReal = os.path.realpath(destination) c["referenceFiles"] = destinationReal so two machines whose workspaces sit in different places, or whose paths pass through different symbolic links, hash the same configuration differently. That never mattered while each machine had its own sqlite3 file and the hash only had to be stable on the machine that made it. Sharing one database made it matter, and it defeats both the claim and the check for results we already have. The path says nothing that the hash needs: the contents of the reference files are hashed right after it, and the same files in another directory are the same test. It is replaced by a constant. Checked with the same configuration under two different reference directories: the hashes were 3181697168 and 2732211752 before, are equal after, and still differ when a reference file itself changes. Every confighash changes value once, so the first run after this treats every library as untested and tests it. From then on the machines agree. --- Generated by Claude Code. --- test.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test.py b/test.py index e1994b6..fb24cc8 100755 --- a/test.py +++ b/test.py @@ -605,6 +605,11 @@ def hashReferenceFiles(s): del(c["configFromFile"]) if "referenceFiles" in c: del(c["referenceFilesURL"]) + # Where the reference files happen to live on this machine must not go into + # the hash: their contents are hashed just below, and two machines sharing + # a database have to agree on what a configuration is. Each machine only + # ever had its own sqlite3 file before, so an absolute path was harmless. + c["referenceFiles"] = "referenceFiles" confighash = strToHashInt(str(c)+hashReferenceFiles(conf["referenceFiles"])) else: confighash = strToHashInt(str(c)+hashReferenceFiles("")) From f35c342fdb5d40978b7e08a08626371afd7a2fc8 Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Tue, 11 Aug 2026 20:47:41 +0200 Subject: [PATCH 432/452] Survive losing the connection to the results database (#300) A run opens its connection, claims its libraries, and then tests for hours before writing anything: the results of every model go into one transaction at the very end, after the reports have been generated. The connection spends that whole time idle, which is exactly the connection a firewall, a NAT or a restarted server drops. When that happened the first INSERT of the run threw OperationalError, test.py died, and a night of testing was lost - and nothing looked wrong until then, because the heartbeat that holds the claims opens a connection of its own every minute. The connection now asks for TCP keepalives, so an idle one is kept alive and a dead one is noticed. If it is lost anyway, the statement that discovers it reconnects, replays the statements the transaction had so far and carries on. Replaying is safe because everything a run writes is an insert guarded by a unique key: it can only produce the rows that were lost, never a duplicate. Queries are not remembered, so the tens of thousands a run makes do not fill the buffer. Checked against the real thing: with a run's transaction half written, killing its backend with pg_terminate_backend loses nothing - the run reconnects, replays its 250 statements, and all 500 rows are in the database, with the connection usable afterwards. This makes losing the connection survivable; it does not make a run's results arrive any earlier. Writing them per library, as each finishes, would also stop a crashed run from losing the libraries it had already tested, and is the better fix - it needs the results to be gathered per library rather than at the end, so it is worth doing on its own. --- Generated by Claude Code. --- resultsdb.py | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 76 insertions(+), 3 deletions(-) diff --git a/resultsdb.py b/resultsdb.py index 81f817e..0d498c9 100644 --- a/resultsdb.py +++ b/resultsdb.py @@ -122,6 +122,16 @@ def commit(self): def close(self): self.conn.close() + # The errors that mean the connection is gone rather than the statement bad. + lostConnection = () + + def record(self, statement, params): + """Remember a statement in case the transaction has to be replayed.""" + + def recover(self): + """Reconnect after the connection was lost and replay the transaction.""" + raise NotImplementedError + def insertIgnore(self): """The clause that makes an INSERT skip a row that is already there.""" return "" @@ -159,7 +169,19 @@ def execute(self, sql, params=()): # psycopg2 only looks for placeholders when parameters are passed, so a # statement without any must not be handed an empty tuple. params = tuple(params) - self.cursor.execute(self.db.sql(sql, bool(params)), self.db.params(params)) + statement = self.db.sql(sql, bool(params)) + try: + self.cursor.execute(statement, self.db.params(params)) + except self.db.lostConnection as e: + # The results of a run are written in one transaction at the end of it, + # after the connection has been idle for hours, which is exactly when a + # firewall or a restarted server has dropped it. Reconnecting and + # replaying what the transaction had so far costs nothing and saves the + # whole run; the keys make replaying it harmless. + print("Lost the connection to the database (%s); reconnecting" % str(e).strip()) + self.cursor = self.db.recover() + self.cursor.execute(statement, self.db.params(params)) + self.db.record(statement, self.db.params(params)) return self def fetchone(self): @@ -254,14 +276,65 @@ def __init__(self, url): # The password belongs in PGPASSWORD or ~/.pgpass, not in the URL. _fixPgpassPermissions() self.url = url - self.conn = psycopg2.connect(url) - self.conn.autocommit = False + self.lostConnection = (psycopg2.OperationalError, psycopg2.InterfaceError) + self.pending = [] + self.conn = self._connect() self.host = socket.gethostname() self.claims = [] self.heartbeatThread = None self.execute(JOB_CLAIM) self.commit() + def _connect(self): + """Open the connection, asking the kernel to keep it alive. + + A run holds this connection open while it tests, which is hours during + which nothing is sent on it, and an idle connection is what a firewall or + a NAT quietly drops. The keepalives make that visible rather than fatal. + """ + import psycopg2 + conn = psycopg2.connect(self.url, keepalives=1, keepalives_idle=60, + keepalives_interval=10, keepalives_count=5) + conn.autocommit = False + return conn + + # Only what changes the database has to be replayed; a run also makes tens of + # thousands of queries, which would fill the buffer for nothing. + WRITES = ("insert", "update", "delete", "create", "drop", "alter") + + def record(self, statement, params): + first = statement.lstrip().split(None, 1) + if first and first[0].lower() in self.WRITES: + self.pending.append((statement, params)) + + def recover(self): + """Reconnect and replay the transaction that the lost connection took. + + Everything a run writes is an insert guarded by a key, so replaying it can + only produce the rows that were lost, never a duplicate. + """ + try: + self.conn.close() + except Exception: + pass + self.conn = self._connect() + cursor = self.conn.cursor() + for (statement, params) in self.pending: + cursor.execute(statement, params) + if self.pending: + print("Replayed %d statements of the interrupted transaction" % len(self.pending)) + return cursor + + def commit(self): + try: + self.conn.commit() + except self.lostConnection as e: + print("Lost the connection to the database while committing (%s); reconnecting" + % str(e).strip()) + self.recover() + self.conn.commit() + self.pending = [] + def sql(self, sql, hasParams=False): """sqlite spells the placeholder "?" and psycopg2 spells it "%s". From 1b6468839e4bb5ab36e67cef8bc6ade9acf3c3f8 Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Tue, 11 Aug 2026 21:07:28 +0200 Subject: [PATCH 433/452] Build the report image on the same base as OpenModelica (#304) The image the report stages run in was still built on build-deps:v1.16.3, which is the dependency image of OpenModelica 1.16. It now uses ubuntu-22.04, the one the OpenModelica repository builds against in .CI/common.groovy and every cmake Jenkinsfile, so the reports run on the same Ubuntu and the same Python as everything else. That also gets psycopg2-binary a wheel to install rather than a source build, which needs pg_config from libpq-dev; the results database needs psycopg2 since #296. Two things the change makes explicit rather than assume of the base image: apt is told -y, because an image that does not assume it turns the build into a prompt that never gets answered, and python3-pip is installed, because the line after it needs pip and the base may not carry it. --- Generated by Claude Code. --- .CI/build-dep/Dockerfile | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.CI/build-dep/Dockerfile b/.CI/build-dep/Dockerfile index c0f8abe..5f329b7 100644 --- a/.CI/build-dep/Dockerfile +++ b/.CI/build-dep/Dockerfile @@ -1,4 +1,7 @@ -FROM docker.openmodelica.org/build-deps:v1.16.3 +# The image the OpenModelica repository builds against, see its .CI/common.groovy +FROM docker.openmodelica.org/build-deps:ubuntu-22.04 -RUN apt-get update && apt-get install libxml2 libxslt1.1 libxml2-dev libxslt1-dev +# -y because a base image that does not assume it turns the build into a prompt, +# and python3-pip because the line below needs it and the base may not carry it. +RUN apt-get update && apt-get install -y libxml2 libxslt1.1 libxml2-dev libxslt1-dev python3-pip RUN pip3 install matplotlib FMPy psycopg2-binary From 2c481fc872e91b60e68e633c02450ec2bc5f1bf6 Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Tue, 11 Aug 2026 21:50:46 +0200 Subject: [PATCH 434/452] Claim a library for a branch, not for a configuration (#305) Two machines testing master both claimed five of the same libraries and tested them twice. #303 fixed the confighash being different for no reason; these five differ for a real one. They are the libraries whose reference files come from MAP-LIB_ReferenceResults/v4.1.0, which a maintenance job updates from time to time, and the two machines had fetched them either side of such an update. The libraries pinned to v4.0.0 and v3.2.3, which do not move, agreed. So the configuration really did differ, and the claim was keyed by it: PRIMARY KEY (branch, libname, libversion, omcversion, confighash) which is finer than the question a claim answers. Whether this machine may test this library of this branch has nothing to do with which reference files it has; that belongs to the two questions that are keyed by the configuration and stay as they are - whether results for an exact configuration already exist, and whether two runs' rows can collide. The claim is now one row per (branch, libname). The versions are kept as columns, so a run still says who is testing what and since when. An existing job_claim is narrowed on connect, keeping the freshest claim per library so that a run in progress does not lose its claims and let a second machine in. Checked against a database seeded the way production looks: the live claim survives the migration, the key becomes (branch, libname), a second machine with a different confighash is refused and told who holds it, a free library is granted and then refused to the first machine, and after release the other machine may take it. Plus a sqlite3 run through the CI configuration and a PostgreSQL run with two FMI simulators. --- Generated by Claude Code. --- resultsdb.py | 73 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 54 insertions(+), 19 deletions(-) diff --git a/resultsdb.py b/resultsdb.py index 0d498c9..81bc764 100644 --- a/resultsdb.py +++ b/resultsdb.py @@ -50,18 +50,27 @@ } BRANCH_KEY = ["date", "libname", "model"] +# What a claim is about: this machine is testing this library of this branch. +# Not the configuration it is testing it with - the configuration hash covers +# the reference files, and two machines that fetched them either side of an +# upstream commit would then both claim the same library and both test it, +# which is the duplication the claim exists to prevent. The versions are kept +# to say who is testing what, and the run still decides for itself whether it +# already has results for an exact configuration. +JOB_CLAIM_KEY = ("branch", "libname") + JOB_CLAIM = """ CREATE TABLE IF NOT EXISTS job_claim ( branch text NOT NULL, libname text NOT NULL, - libversion text NOT NULL, - omcversion text NOT NULL, - confighash bigint NOT NULL, + libversion text, + omcversion text, + confighash bigint, host text NOT NULL, state text NOT NULL, claimed_at timestamptz NOT NULL DEFAULT now(), heartbeat timestamptz NOT NULL DEFAULT now(), - PRIMARY KEY (branch, libname, libversion, omcversion, confighash) + PRIMARY KEY (branch, libname) ) """ @@ -283,6 +292,7 @@ def __init__(self, url): self.claims = [] self.heartbeatThread = None self.execute(JOB_CLAIM) + self._migrateJobClaim() self.commit() def _connect(self): @@ -335,6 +345,31 @@ def commit(self): self.conn.commit() self.pending = [] + def _migrateJobClaim(self): + """Narrow an older job_claim to (branch, libname). + + It used to be keyed by the configuration as well, so two machines whose + reference files had been updated at different times each got a claim on the + same library. Claims of a run in progress are kept, the freshest per + library, so migrating does not let a second machine in. + """ + key = [c for (c,) in self.execute("""SELECT a.attname FROM pg_index i + JOIN pg_attribute a ON a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey) + WHERE i.indrelid = 'job_claim'::regclass AND i.indisprimary + ORDER BY a.attnum""")] + if tuple(key) == JOB_CLAIM_KEY: + return + print("Narrowing job_claim from (%s) to (%s)" % (", ".join(key), ", ".join(JOB_CLAIM_KEY))) + cursor = self.cursor() + cursor.execute(JOB_CLAIM.replace("job_claim", "job_claim_migrated")) + cursor.execute("""INSERT INTO job_claim_migrated + SELECT DISTINCT ON (branch, libname) branch, libname, libversion, omcversion, + confighash, host, state, claimed_at, heartbeat + FROM job_claim ORDER BY branch, libname, heartbeat DESC""") + cursor.execute("DROP TABLE job_claim") + cursor.execute("ALTER TABLE job_claim_migrated RENAME TO job_claim") + self.commit() + def sql(self, sql, hasParams=False): """sqlite spells the placeholder "?" and psycopg2 spells it "%s". @@ -420,16 +455,18 @@ def claim(self, branch, libname, libversion, omcversion, confighash): A machine that dies stops sending its heartbeat, and after STALE_CLAIM_MINUTES its jobs are up for grabs again. """ - key = (branch, libname, libversion, omcversion, confighash) + key = (branch, libname) got = self.execute("""INSERT INTO job_claim (branch, libname, libversion, omcversion, confighash, host, state) VALUES (?,?,?,?,?,?,'running') - ON CONFLICT (branch, libname, libversion, omcversion, confighash) DO UPDATE - SET host = EXCLUDED.host, state = 'running', claimed_at = now(), heartbeat = now() + ON CONFLICT (branch, libname) DO UPDATE + SET host = EXCLUDED.host, state = 'running', claimed_at = now(), heartbeat = now(), + libversion = EXCLUDED.libversion, omcversion = EXCLUDED.omcversion, + confighash = EXCLUDED.confighash WHERE job_claim.state <> 'running' OR job_claim.heartbeat < now() - interval '%d minutes' RETURNING host""" % STALE_CLAIM_MINUTES, - key + (self.host,)).fetchone() + (branch, libname, libversion, omcversion, confighash, self.host)).fetchone() self.commit() if got is None: return False @@ -439,9 +476,8 @@ def claim(self, branch, libname, libversion, omcversion, confighash): def claimedBy(self, branch, libname, libversion, omcversion, confighash): """The machine holding that job, for the message telling the user why we skip.""" - row = self.execute("""SELECT host, claimed_at FROM job_claim WHERE branch=? AND libname=? - AND libversion=? AND omcversion=? AND confighash=?""", - (branch, libname, libversion, omcversion, confighash)).fetchone() + row = self.execute("SELECT host, claimed_at FROM job_claim WHERE branch=? AND libname=?", + (branch, libname)).fetchone() return row or ("unknown", None) def _startHeartbeat(self): @@ -463,16 +499,15 @@ def _heartbeat(self): import psycopg2 with psycopg2.connect(self.url) as conn: with conn.cursor() as cur: - for (branch, libname, libversion, omcversion, confighash) in list(self.claims): - cur.execute("""UPDATE job_claim SET heartbeat = now() WHERE branch=%s AND libname=%s - AND libversion=%s AND omcversion=%s AND confighash=%s AND host=%s""", - (branch, libname, libversion, omcversion, confighash, self.host)) + for (branch, libname) in list(self.claims): + cur.execute("""UPDATE job_claim SET heartbeat = now() + WHERE branch=%s AND libname=%s AND host=%s""", + (branch, libname, self.host)) def release(self): - for (b, libname, libversion, omcversion, confighash) in self.claims: + for (branch, libname) in self.claims: self.execute("""UPDATE job_claim SET state='done', heartbeat=now() - WHERE branch=? AND libname=? AND libversion=? AND omcversion=? AND confighash=? - AND host=?""", - (b, libname, libversion, omcversion, confighash, self.host)) + WHERE branch=? AND libname=? AND host=?""", + (branch, libname, self.host)) self.claims = [] self.commit() From 7fc45144d1f434f64ae7f09a72401a8aeb7df83b Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Tue, 11 Aug 2026 22:18:01 +0200 Subject: [PATCH 435/452] Remove the sqlite3 file handling from the pipeline (#306) The results of a job went into a per-machine sqlite3 file that had to be downloaded before the run and published back afterwards, and since #296 they go into the shared database instead. Which of the two was a tick box on the job, defaulting to the shared one. Nobody should be able to send a day of testing to a file nobody reads by unticking a box, and keeping the old path around only leaves two ways of doing the same thing for someone to wonder about later. Both are gone: - the "postgres" parameter, and the branches it guarded; - copying ~/TEST_LIBS_BACKUP/-sqlite3.db into the workspace before a run, copying it back after, and the sshPublisher that uploaded it; - fetching a machine's sqlite3.db in the two report stages, which now read the shared database directly; - keeping a week of dated backups of those files on every node; - dbPrefix and sshConfig, which existed only to name and publish that file, from runRegressiontest and its twenty-three callers. The scripts themselves are untouched and still write a sqlite3 file by default: that is what a developer running test.py gets, and what the GitHub checks use. It is the pipeline that no longer has a second way of doing this. --- Generated by Claude Code. --- .CI/Jenkinsfile | 93 ++++++++++++++----------------------------------- 1 file changed, 27 insertions(+), 66 deletions(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index 007a4b0..a647eca 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -3,8 +3,6 @@ pipeline { parameters { booleanParam(name: 'OLDLIBS', defaultValue: false, description: 'Also test some outdated libraries') - booleanParam(name: 'postgres', defaultValue: true, description: 'Store the results in the shared PostgreSQL database (omdb on openmodelica.org) rather than in the per-machine sqlite3 file. Machines coordinate through it, so two of them no longer overwrite each other. Untick to go back to the sqlite3 files.') - booleanParam(name: 'v1_26', defaultValue: false, description: 'maintenance/v1.26 branch (ryzen-5950x-1)') booleanParam(name: 'v1_27', defaultValue: false, description: 'maintenance/v1.27 branch (ryzen-5950x-1)') booleanParam(name: 'master', defaultValue: false, description: 'master branch (ryzen-5950x-1)') @@ -44,7 +42,7 @@ pipeline { LC_ALL = 'C.UTF-8' // Where the results go. The scripts take it from here instead of a --db // option on every single invocation. - LIBTEST_DB = "${params.postgres ? 'postgresql://om@openmodelica.org/omdb' : 'sqlite3.db'}" + LIBTEST_DB = 'postgresql://om@openmodelica.org/omdb' } stages { stage('test') { parallel { @@ -62,7 +60,7 @@ pipeline { expression { params.v1_26 } } steps { - runRegressiontest('maintenance/v1.26', 'v1.26', '', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', '', false, false) + runRegressiontest('maintenance/v1.26', 'v1.26', '', '', false, '', '', false, false) } } @@ -79,7 +77,7 @@ pipeline { expression { params.v1_27 } } steps { - runRegressiontest('maintenance/v1.27', 'v1.27', '', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', '', false, false) + runRegressiontest('maintenance/v1.27', 'v1.27', '', '', false, '', '', false, false) } } @@ -96,7 +94,7 @@ pipeline { expression { params.master } } steps { - runRegressiontest('master', 'master', '', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', '', false, false) + runRegressiontest('master', 'master', '', '', false, '', '', false, false) } } @@ -113,7 +111,7 @@ pipeline { expression { params.conversion_script } } steps { - runRegressiontest('master', 'conversion', '', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', '', false, true) + runRegressiontest('master', 'conversion', '', '', false, '', '', false, true) } } @@ -130,7 +128,7 @@ pipeline { expression { params.newInst_newBackend } } steps { - runRegressiontest('master', 'newInst-newBackend', 'setCommandLineOptions("-d=newInst,-frontEndUnitCheck --newBackend")', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', '', false, false) + runRegressiontest('master', 'newInst-newBackend', 'setCommandLineOptions("-d=newInst,-frontEndUnitCheck --newBackend")', '', false, '', '', false, false) } } @@ -147,7 +145,7 @@ pipeline { expression { params.fmi_v1_26 || params.fmpy_fmi_v1_26 } } steps { - runRegressiontest('maintenance/v1.26', 'v1.26-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', false, '', '', false, false, 0, 'configs/conf.json', '', '', fmiSimulators(params.fmi_v1_26, params.fmpy_fmi_v1_26)) + runRegressiontest('maintenance/v1.26', 'v1.26-fmi', '', omsimulatorHash(), false, '', '', false, false, 0, 'configs/conf.json', '', '', fmiSimulators(params.fmi_v1_26, params.fmpy_fmi_v1_26)) } } stage('v1.27 FMI') { @@ -163,7 +161,7 @@ pipeline { expression { params.fmi_v1_27 || params.fmpy_fmi_v1_27 } } steps { - runRegressiontest('maintenance/v1.27', 'v1.27-fmi', '', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', false, '', '', false, false, 0, 'configs/conf.json', '', '', fmiSimulators(params.fmi_v1_27, params.fmpy_fmi_v1_27)) + runRegressiontest('maintenance/v1.27', 'v1.27-fmi', '', omsimulatorHash(), false, '', '', false, false, 0, 'configs/conf.json', '', '', fmiSimulators(params.fmi_v1_27, params.fmpy_fmi_v1_27)) } } stage('master FMI') { @@ -179,7 +177,7 @@ pipeline { expression { params.fmi_master || params.fmpy_fmi_master } } steps { - runRegressiontest('master', 'master-fmi', '', 'origin/master', 'ripper2', 'LibraryTestingRipper2DB', false, '', '', false, false, 0, 'configs/conf.json', '', '', fmiSimulators(params.fmi_master, params.fmpy_fmi_master)) + runRegressiontest('master', 'master-fmi', '', 'origin/master', false, '', '', false, false, 0, 'configs/conf.json', '', '', fmiSimulators(params.fmi_master, params.fmpy_fmi_master)) } } @@ -196,7 +194,7 @@ pipeline { expression { params.cs_fmu_cvode_v1_26 } } steps { - runRegressiontest('maintenance/v1.26', 'v1.26-cs-fmu-cvode', 'setCommandLineOptions("--fmiFlags=s:cvode --fmuRuntimeDepends=modelica")', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', false, '', '', false, false) + runRegressiontest('maintenance/v1.26', 'v1.26-cs-fmu-cvode', 'setCommandLineOptions("--fmiFlags=s:cvode --fmuRuntimeDepends=modelica")', omsimulatorHash(), false, '', '', false, false) } } stage('v1.27 CVODE CS-FMUs with OMSimulator') { @@ -212,7 +210,7 @@ pipeline { expression { params.cs_fmu_cvode_v1_27 } } steps { - runRegressiontest('maintenance/v1.27', 'v1.27-cs-fmu-cvode', 'setCommandLineOptions("--fmiFlags=s:cvode --fmuRuntimeDepends=modelica")', omsimulatorHash(), 'ripper2', 'LibraryTestingRipper2DB', false, '', '', false, false) + runRegressiontest('maintenance/v1.27', 'v1.27-cs-fmu-cvode', 'setCommandLineOptions("--fmiFlags=s:cvode --fmuRuntimeDepends=modelica")', omsimulatorHash(), false, '', '', false, false) } } stage('master CVODE CS-FMUs with OMSimulator') { @@ -228,7 +226,7 @@ pipeline { expression { params.cs_fmu_cvode_master } } steps { - runRegressiontest('master', 'master-cs-fmu-cvode', 'setCommandLineOptions("--fmiFlags=s:cvode --fmuRuntimeDepends=modelica")', 'origin/master', 'ripper2', 'LibraryTestingRipper2DB', false, '', '', false, false) + runRegressiontest('master', 'master-cs-fmu-cvode', 'setCommandLineOptions("--fmiFlags=s:cvode --fmuRuntimeDepends=modelica")', 'origin/master', false, '', '', false, false) } } @@ -245,7 +243,7 @@ pipeline { expression { params.newInst_daeMode } } steps { - runRegressiontest('master', 'newInst-daeMode', 'setCommandLineOptions("-d=newInst,-frontEndUnitCheck --daeMode=true")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', '', false, false) + runRegressiontest('master', 'newInst-daeMode', 'setCommandLineOptions("-d=newInst,-frontEndUnitCheck --daeMode=true")', '', false, '', '', false, false) } } stage('newBackend-daeMode') { @@ -261,7 +259,7 @@ pipeline { expression { params.newBackend_daeMode } } steps { - runRegressiontest('master', 'newBackend-daeMode', 'setCommandLineOptions("-d=newInst,-frontEndUnitCheck --newBackend --daeMode=true")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', '', false, false) + runRegressiontest('master', 'newBackend-daeMode', 'setCommandLineOptions("-d=newInst,-frontEndUnitCheck --newBackend --daeMode=true")', '', false, '', '', false, false) } } stage('oldInst') { @@ -277,7 +275,7 @@ pipeline { expression { params.oldInst } } steps { - runRegressiontest('master', 'oldInst', 'setCommandLineOptions("-d=nonewInst")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', '', false, false) + runRegressiontest('master', 'oldInst', 'setCommandLineOptions("-d=nonewInst")', '', false, '', '', false, false) } } stage('cvode') { @@ -293,7 +291,7 @@ pipeline { expression { params.cvode } } steps { - runRegressiontest('master', 'cvode', 'setCommandLineOptions("-d=newInst,-frontEndUnitCheck")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '-s cvode', '', false, false) + runRegressiontest('master', 'cvode', 'setCommandLineOptions("-d=newInst,-frontEndUnitCheck")', '', false, '-s cvode', '', false, false) } } stage('gbode') { @@ -309,7 +307,7 @@ pipeline { expression { params.gbode } } steps { - runRegressiontest('master', 'gbode', 'setCommandLineOptions("-d=newInst,-frontEndUnitCheck")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '-s gbode -gbm=radauIIA3', '', false, false) + runRegressiontest('master', 'gbode', 'setCommandLineOptions("-d=newInst,-frontEndUnitCheck")', '', false, '-s gbode -gbm=radauIIA3', '', false, false) } } stage('ida') { @@ -325,7 +323,7 @@ pipeline { expression { params.ida } } steps { - runRegressiontest('master', 'ida', 'setCommandLineOptions("-d=newInst,-frontEndUnitCheck")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '-s ida', '', false, false) + runRegressiontest('master', 'ida', 'setCommandLineOptions("-d=newInst,-frontEndUnitCheck")', '', false, '-s ida', '', false, false) } } stage('wasm-jit') { @@ -341,7 +339,7 @@ pipeline { expression { params.wasm_jit } } steps { - runRegressiontest('master', 'wasm-jit', 'setCommandLineOptions("--simCodeTarget=wasm-jit")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', '--nobuildmodel', false, false, 0, 'configs/conf.json', + runRegressiontest('master', 'wasm-jit', 'setCommandLineOptions("--simCodeTarget=wasm-jit")', '', false, '', '--nobuildmodel', false, false, 0, 'configs/conf.json', '-DOM_OMC_ENABLE_RUST=ON -DRUST_OMC_CI=ON -DRUST_OMC_THREADS=4 -DCMAKE_C_COMPILER_LAUNCHER=sccache -DCMAKE_CXX_COMPILER_LAUNCHER=sccache', '.CI/wasm-jit') } @@ -359,7 +357,7 @@ pipeline { expression { params.generateSymbolicJacobian } } steps { - runRegressiontest('master', 'generateSymbolicJacobian', 'setCommandLineOptions("--generateSymbolicJacobian")', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', '', false, false) + runRegressiontest('master', 'generateSymbolicJacobian', 'setCommandLineOptions("--generateSymbolicJacobian")', '', false, '', '', false, false) } } stage('heavy_tests') { @@ -375,7 +373,7 @@ pipeline { expression { params.heavy_tests } } steps { - runRegressiontest('master', 'heavy_tests', '', '', 'ripper1', 'LibraryTestingRipper1DB', false, '', '', false, false, 1, 'configs/heavy_tests.json') + runRegressiontest('master', 'heavy_tests', '', '', false, '', '', false, false, 1, 'configs/heavy_tests.json') } } @@ -392,7 +390,7 @@ pipeline { expression { params.cpp_v1_26 } } steps { - runRegressiontest('maintenance/v1.26', 'v1.26-cpp', 'setCommandLineOptions("--simCodeTarget=Cpp")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', '', false, false) + runRegressiontest('maintenance/v1.26', 'v1.26-cpp', 'setCommandLineOptions("--simCodeTarget=Cpp")', '', false, '', '', false, false) } } stage('C++ v1.27') { @@ -408,7 +406,7 @@ pipeline { expression { params.cpp_v1_27 } } steps { - runRegressiontest('maintenance/v1.27', 'v1.27-cpp', 'setCommandLineOptions("--simCodeTarget=Cpp")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', '', false, false) + runRegressiontest('maintenance/v1.27', 'v1.27-cpp', 'setCommandLineOptions("--simCodeTarget=Cpp")', '', false, '', '', false, false) } } @@ -425,7 +423,7 @@ pipeline { expression { params.cpp } } steps { - runRegressiontest('master', 'cpp', 'setCommandLineOptions("--simCodeTarget=Cpp")', '', 'ripper2', 'LibraryTestingRipper2DB', false, '', '', false, false) + runRegressiontest('master', 'cpp', 'setCommandLineOptions("--simCodeTarget=Cpp")', '', false, '', '', false, false) } } } } @@ -457,7 +455,7 @@ pipeline { //sshagent (credentials: ['Hudson-SSH-Key']) { // createInitialHistoryFilesOnRemote() //} - sh 'rm -rf sqlite3.db *.html history' + sh 'rm -rf *.html history' sh ''' if ! test -d OpenModelica; then git clone https://openmodelica.org/git-readonly/OpenModelica.git @@ -465,12 +463,6 @@ pipeline { cd OpenModelica git fetch ''' - // The reports read the shared database directly when it is in use. - script { - if (!params.postgres) { - sh 'wget -q https://libraries.openmodelica.org/sqlite3/ripper1/sqlite3.db' - } - } sh './clean-empty-omcversion-dates.py' sh "./all-reports.py --email --omcgitdir=OpenModelica ${env.GITBRANCHES} conversion heavy_tests" @@ -533,7 +525,7 @@ pipeline { //sshagent (credentials: ['Hudson-SSH-Key']) { // createInitialHistoryFilesOnRemote() //} - sh 'rm -f sqlite3.db *.html' + sh 'rm -f *.html' sh ''' if ! test -d OpenModelica; then git clone https://openmodelica.org/git-readonly/OpenModelica.git @@ -541,11 +533,6 @@ pipeline { cd OpenModelica git fetch ''' - script { - if (!params.postgres) { - sh 'wget -q https://libraries.openmodelica.org/sqlite3/ripper2/sqlite3.db' - } - } sh './clean-empty-omcversion-dates.py' sh "./all-reports.py --email --omcgitdir=OpenModelica ${env.GITBRANCHES_FMI} ${env.GITBRANCHES_NEWINST} ${env.GITBRANCHES_DAE} ${env.GITBRANCHES_NEWBACKEND_DAE} ${env.GITBRANCHES_CPP} gbode cvode ida" @@ -718,8 +705,6 @@ def sccachePreamble() { * Also used for stashing omc and uploading results to https://test.openmodelica.org. * @param extraFlags: Additional compiler flags passed to test.py via flag `--extraflags`. * @param omsHash: OMSimulator SHA. - * @param dbPrefix: Prefix for test results data base `sqlite3.db`. - * @parm sshConfig: SSH configuration saved on test node. * @param omcompiler: Checkout old OMCompiler submodule. Should be `false` nowadays. * @param extrasimflags: Additional simulation flags passed to test.py via flag `--extrasimflags`. * @param testFlags: Additional flags passed to test.py verbatim, e.g. `--nobuildmodel`. @@ -746,11 +731,9 @@ def fmiSimulators(boolean omsimulator, boolean fmpy) { return simulators } -def runRegressiontest(branch, name, extraFlags, omsHash, dbPrefix, sshConfig, omcompiler, extrasimflags, testFlags, boolean removePackageOrder, boolean conversionScript, int jobs=0, libs_config_file = 'configs/conf.json', cmakeFlags = '', dockerfile = '', fmiSimulators = null) { +def runRegressiontest(branch, name, extraFlags, omsHash, omcompiler, extrasimflags, testFlags, boolean removePackageOrder, boolean conversionScript, int jobs=0, libs_config_file = 'configs/conf.json', cmakeFlags = '', dockerfile = '', fmiSimulators = null) { sh ''' find /tmp -name "*openmodelica.hudson*" -exec rm {} ";" || true - mkdir -p ~/TEST_LIBS_BACKUP - find ~/TEST_LIBS_BACKUP -name *sqlite3.*.db -mtime +7 -exec rm {} ";" if test -z "$WORKSPACE"; then echo "Odd workspace" @@ -1002,18 +985,6 @@ def runRegressiontest(branch, name, extraFlags, omsHash, dbPrefix, sshConfig, om sh "test -d '${libraryPath}/.openmodelica/libraries/Modelica trunk'" - // The shared database needs none of this: the results go straight into it. - if (!params.postgres) { - sh """ - if ! test -f ~/TEST_LIBS_BACKUP/${dbPrefix}-sqlite3.db; then - wget -O ~/TEST_LIBS_BACKUP/${dbPrefix}-sqlite3.db.tmp -q https://libraries.openmodelica.org/sqlite3/${dbPrefix}/sqlite3.db - mv ~/TEST_LIBS_BACKUP/${dbPrefix}-sqlite3.db.tmp ~/TEST_LIBS_BACKUP/${dbPrefix}-sqlite3.db - fi - cp ~/TEST_LIBS_BACKUP/${dbPrefix}-sqlite3.db OpenModelicaLibraryTesting/sqlite3.db - test -s OpenModelicaLibraryTesting/sqlite3.db - """ - } - sh 'date' // The password of the results database comes from a secret file, bound here @@ -1042,14 +1013,4 @@ def runRegressiontest(branch, name, extraFlags, omsHash, dbPrefix, sshConfig, om sh "cd OpenModelicaLibraryTesting/ && ./clean-empty-omcversion-dates.py" } - // Copying the file back is what made two machines overwrite each other's - // results, so it only happens while a job still writes its own sqlite3 file. - if (!params.postgres) { - sh "rm -f OpenModelicaLibraryTesting/${dbPrefix}-sqlite3.db.tmp" - sh "ln OpenModelicaLibraryTesting/sqlite3.db OpenModelicaLibraryTesting/${dbPrefix}-sqlite3.db.tmp" - sh "cp OpenModelicaLibraryTesting/sqlite3.db ~/TEST_LIBS_BACKUP/${dbPrefix}-sqlite3.db" - sh "rm -f ~/TEST_LIBS_BACKUP/${dbPrefix}-`date +sqlite3.%Y%m%d.db`" - - sshPublisher(publishers: [sshPublisherDesc(configName: sshConfig, transfers: [sshTransfer(removePrefix: 'OpenModelicaLibraryTesting', sourceFiles: 'OpenModelicaLibraryTesting/sqlite3.db')])], failOnError: true) - } } From 4dc73871f927d7fefd66517fbebcf5de711e480e Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Wed, 12 Aug 2026 12:13:25 +0200 Subject: [PATCH 436/452] Test every library of an FMI job with FMI (#309) A library whose reference files are already prepared by another library took a `continue` that skipped the rest of the configuration loop - and the only thing after it is the line that turns FMI on: if allTestsFmi: c["fmi"] = "2.0" So four libraries of configs/conf.json have been running as ordinary native models inside the FMI jobs: PowerGrids_symb_jac, PowerGrids_dev, ClaRa_dev and ScalableTestSuite_noopt, each of them the second library to want a reference directory that PowerGrids, ClaRa and ScalableTestSuite had already cloned. They verify identically in master and in master-fmi - 66, 19, 72 and 244 models - while every library that prepares its own directory drops as an FMI job should (242 to 176 for ScalableTestSuite, 65 to 31 for PowerGrids). The reuse also looked the directory up under a key it had not computed yet, so it took whatever `destination` the previous library left behind. Both are fixed by computing the normalised destination first and putting the preparation in an else branch, which leaves nothing after the loop's body unreachable. Since #297 this crashed the run rather than quietly mistesting it. Such a model has no per-simulator results, so the second simulator's branch reported the phase the *first* simulator reached - 7, verified - with no comparison to go with it, and building the report died on it after seven hours: ("%s (%d verified)" % (timeSeconds(diff.get("time")), ...)) if s[3]["phase"]>=7 AttributeError: 'NoneType' object has no attribute 'get' A simulator that never ran a model now reports the phase the shared build reached and never a phase another simulator went on to reach with the same FMU, in the report and in the database row alike; and a model with nothing to compare renders as an empty cell whatever phase it claims, so a mismatch can never again throw away a finished run. Fixes the master-fmi failure of build 11369. --- test.py | 131 +++++++++++++++++++++++++++++++------------------------- 1 file changed, 72 insertions(+), 59 deletions(-) diff --git a/test.py b/test.py index fb24cc8..4b61852 100755 --- a/test.py +++ b/test.py @@ -490,65 +490,65 @@ def testHelloWorld(cmd): refFilesGitTag = c["referenceFiles"]["git-ref"].strip() if not refFilesGitTag.startswith("origin/"): refFilesGitTag = 'origin/%s' % refFilesGitTag - if c["referenceFiles"]["destination"] in preparedReferenceDirs: + # Several libraries share one set of reference files. The first of them + # prepares the directory and the rest take what it recorded - but the rest + # of this loop still has to run for every one of them. + destination = os.path.normpath(c["referenceFiles"]["destination"]) + if destination in preparedReferenceDirs: (c["referenceFiles"],c["referenceFilesURL"]) = preparedReferenceDirs[destination] - continue - giturl = c["referenceFiles"]["giturl"] - destination = c["referenceFiles"]["destination"] - if DEBUG: - print("destination %s" % destination) - destination = os.path.normpath(destination) - if DEBUG: - print("normalized destination %s" % destination) - print("not os.path.isdir(destination): %s" % (not os.path.isdir(destination))) - destinationReal = os.path.realpath(destination) - if DEBUG: - print("destinationReal %s" % destinationReal) - destinationReal = os.path.normpath(destinationReal) - if DEBUG: - print("normalized destinationReal %s" % destinationReal) - print("referenceFiles:", c["referenceFiles"]) + else: + giturl = c["referenceFiles"]["giturl"] + if DEBUG: + print("destination %s" % destination) + print("not os.path.isdir(destination): %s" % (not os.path.isdir(destination))) + destinationReal = os.path.realpath(destination) + if DEBUG: + print("destinationReal %s" % destinationReal) + destinationReal = os.path.normpath(destinationReal) + if DEBUG: + print("normalized destinationReal %s" % destinationReal) + print("referenceFiles:", c["referenceFiles"]) + + if not os.path.isdir(destination): + if "git-directory" in c["referenceFiles"]: + # Sparse clone + os.makedirs(destination) + check_call_log(["git", "init"], stderr=subprocess.STDOUT, cwd=destinationReal) + check_call_log(["git", "remote", "add", "-f", "origin", giturl], stderr=subprocess.STDOUT, cwd=destinationReal) + check_call_log(["git", "config", "core.sparseCheckout", "true"], stderr=subprocess.STDOUT, cwd=destinationReal) + file = open(os.path.join(destinationReal,".git", "info", "sparse-checkout"), "a") + file.write(c["referenceFiles"]["git-directory"].strip()) + file.close() + else: + # Clone + check_call_log(["git", "clone", giturl, destination], stderr=subprocess.STDOUT) + + check_call_log(["git", "clean", "-fdx", "--exclude=*.hash"], stderr=subprocess.STDOUT, cwd=destinationReal) + check_call_log(["git", "fetch", "origin"], stderr=subprocess.STDOUT, cwd=destination) + # do not fail if the branch we were given doesn't exist + try: + check_call_log(["git", "reset", "--hard", refFilesGitTag], stderr=subprocess.STDOUT, cwd=destinationReal) + except subprocess.CalledProcessError as e: + print(e.output) + check_call_log(["git", "clean", "-fdx", "--exclude=*.hash"], stderr=subprocess.STDOUT, cwd=destinationReal) + if glob.glob(destinationReal + "/*.mat.xz"): + check_call_log(["find", ".", "-name", "*.mat.xz", "-exec", "xz", "--decompress", "--keep", "{}", ";"], stderr=subprocess.STDOUT, cwd=destinationReal) + try: + githash = check_output_log(["git", "rev-parse", "--verify", "HEAD"], stderr=subprocess.STDOUT, cwd=destinationReal, encoding='utf8') + except subprocess.CalledProcessError as e: + print(e.output) - if not os.path.isdir(destination): if "git-directory" in c["referenceFiles"]: - # Sparse clone - os.makedirs(destination) - check_call_log(["git", "init"], stderr=subprocess.STDOUT, cwd=destinationReal) - check_call_log(["git", "remote", "add", "-f", "origin", giturl], stderr=subprocess.STDOUT, cwd=destinationReal) - check_call_log(["git", "config", "core.sparseCheckout", "true"], stderr=subprocess.STDOUT, cwd=destinationReal) - file = open(os.path.join(destinationReal,".git", "info", "sparse-checkout"), "a") - file.write(c["referenceFiles"]["git-directory"].strip()) - file.close() + c["referenceFiles"] = os.path.join(destinationReal, c["referenceFiles"]['git-directory']) + print(c["referenceFiles"]) else: - # Clone - check_call_log(["git", "clone", giturl, destination], stderr=subprocess.STDOUT) - - check_call_log(["git", "clean", "-fdx", "--exclude=*.hash"], stderr=subprocess.STDOUT, cwd=destinationReal) - check_call_log(["git", "fetch", "origin"], stderr=subprocess.STDOUT, cwd=destination) - # do not fail if the branch we were given doesn't exist - try: - check_call_log(["git", "reset", "--hard", refFilesGitTag], stderr=subprocess.STDOUT, cwd=destinationReal) - except subprocess.CalledProcessError as e: - print(e.output) - check_call_log(["git", "clean", "-fdx", "--exclude=*.hash"], stderr=subprocess.STDOUT, cwd=destinationReal) - if glob.glob(destinationReal + "/*.mat.xz"): - check_call_log(["find", ".", "-name", "*.mat.xz", "-exec", "xz", "--decompress", "--keep", "{}", ";"], stderr=subprocess.STDOUT, cwd=destinationReal) - try: - githash = check_output_log(["git", "rev-parse", "--verify", "HEAD"], stderr=subprocess.STDOUT, cwd=destinationReal, encoding='utf8') - except subprocess.CalledProcessError as e: - print(e.output) + c["referenceFiles"] = destinationReal - if "git-directory" in c["referenceFiles"]: - c["referenceFiles"] = os.path.join(destinationReal, c["referenceFiles"]['git-directory']) - print(c["referenceFiles"]) - else: - c["referenceFiles"] = destinationReal - - if giturl.startswith("https://github.com"): - c["referenceFilesURL"] = '%s (%s)' % (giturl, githash.strip(), giturl, githash.strip()) - else: - c["referenceFilesURL"] = "%s (%s)" % (giturl, githash.strip()) - preparedReferenceDirs[destination] = (c["referenceFiles"],c["referenceFilesURL"]) + if giturl.startswith("https://github.com"): + c["referenceFilesURL"] = '%s (%s)' % (giturl, githash.strip(), giturl, githash.strip()) + else: + c["referenceFilesURL"] = "%s (%s)" % (giturl, githash.strip()) + preparedReferenceDirs[destination] = (c["referenceFiles"],c["referenceFilesURL"]) else: raise Exception("Unknown referenceFiles in config: %s" % (str(c["referenceFiles"]))) @@ -952,6 +952,19 @@ def loadJsonOrEmptySet(f): print(" %-70s cold %8.4f hot %8.4f" % (model, data["simcold"], data.get("sim") or 0.0)) sys.stdout.flush() +BUILD_PHASE = 5 +"""The last phase a model shares with every simulator of its FMU.""" + +def phaseWithoutSimulator(data): + """How far a model got for a simulator that never ran it. + + Everything up to the build is shared, so such a model reports the phase the + build reached and never the phase another simulator went on to reach with the + same FMU. Reporting that one would claim a simulation, and a verification, + that this simulator never performed. + """ + return min(data.get("phase") or 0, BUILD_PHASE) + def resultValues(model, libname, data, simulator=None): """One row of a branch table. @@ -961,9 +974,7 @@ def resultValues(model, libname, data, simulator=None): """ simulated = data if simulator is None else (data.get("simulators") or {}).get(simulator) if simulated is None: - # The model never got as far as being simulated, so every simulator of it - # reports the phase the build stopped at rather than a failure of its own. - simulated = {"phase": data.get("phase") or 0} + simulated = {"phase": phaseWithoutSimulator(data)} diff = simulated.get("diff") or {} return (testRunStartTimeAsEpoch, libname, @@ -1095,7 +1106,7 @@ def dataForSimulator(data, simulator): merged["diff"] = (simulated or {}).get("diff") # A model that never got as far as being simulated stopped in the build, # which every simulator of it shares. - merged["phase"] = simulated.get("phase") if simulated else data.get("phase") + merged["phase"] = simulated.get("phase") if simulated is not None else phaseWithoutSimulator(data) return merged def artifactSuffix(simulator): @@ -1155,7 +1166,9 @@ def artifactSuffix(simulator): ('%s' % (errPrefix + ".err", html.escape(s[1]))) if is_non_zero_file(errPrefix + ".err") else html.escape(s[1]), (' (sim)' % (filename_prefix + ".sim")) if is_non_zero_file(filename_prefix + suffix + ".sim") else "", checkPhase(s[3]["phase"], 7) if s[3]["phase"]>=6 else "#FFFFFF", - ("%s (%d verified)" % (timeSeconds(diff.get("time")), diff.get("numCompared"))) if s[3]["phase"]>=7 else (" " if diff is None else + # Nothing was compared, whatever phase the model reports. + " " if diff is None else + (("%s (%d verified)" % (timeSeconds(diff.get("time")), diff.get("numCompared"))) if s[3]["phase"]>=7 else ('%s (%d/%d failed)' % (timeSeconds(diff.get("time")), filename_prefix, len(diff.get("vars")), diff.get("numCompared")))), checkPhase(s[3]["phase"], 6), timeSeconds(s[3].get("sim") or 0), From 44efed0d979d3225c325f85dd063535ba1f25b3a Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Wed, 12 Aug 2026 18:17:45 +0200 Subject: [PATCH 437/452] Record what a command killed by the watchdog cost (#310) A model whose command runs out of time reports nothing for the phase it was in, so the time disappears from every phase column and only `exectime` still counts it. In the master run of 2026-08-12 that is 15 models and 1.34 hours, including three BuildingSystems models that spend the full 660 second budget in translateModel and are recorded as having spent three seconds parsing and nothing else. The caller does try to account for it: except TimeoutError as e: execstat["frontend"]=monotonic()-start but that handler never runs. `sendExpressionTimeout` kills the command and calls `writeResultAndExit` itself, from inside, so the process is gone before the exception is raised - the results written are whatever `execstat` held when the command started. Recording it where the results are written covers every way out instead of the one path that remembered to. A phase now says when it started, `writeResult` charges it if it never reported a time of its own, and a phase that ends normally still reports exactly what it did before. Which phase a killed command belongs to cannot be known - the timers of omc are gone with it - so it is charged to what the command itself is: building an FMU to the build, simulating to the simulation, translating to the front end, which is also the phase such a model is reported as having failed in. Verified on Modelica.Fluid.Examples.HeatExchanger.HeatExchangerSimulation with ulimitOmc=1, which the watchdog kills: before {'parsing': 1.73} after {'parsing': 1.65, 'frontend': 3.01} and on Modelica.Blocks.Examples.PID_Controller, which succeeds, where every phase is unchanged. Part of #308. --- testmodel.py | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/testmodel.py b/testmodel.py index dba4b3b..bd89869 100755 --- a/testmodel.py +++ b/testmodel.py @@ -50,7 +50,29 @@ class TimeoutError(Exception): pass +runningPhase = None +"""What is running now, as (key of execstat, when it started). + +A command the watchdog has to kill never returns to its caller - +sendExpressionTimeout ends the process itself - so the caller's own timeout +handler does not run and the phase reports no time at all. Recording it here +instead covers every way out, because they all write the results first. +""" + +def phaseStarts(key): + global runningPhase + runningPhase = (key, monotonic()) + +def phaseEnded(): + global runningPhase + runningPhase = None + def writeResult(): + if runningPhase is not None: + (key, started) = runningPhase + # Only if the phase did not get to report its own time. + if not execstat.get(key): + execstat[key] = monotonic() - started with open(statFile, 'w') as fp: json.dump(execstat, fp) fp.flush() @@ -447,19 +469,28 @@ def simulateCmd(resimulate): total_before = omc.sendExpression("OpenModelica.Scripting.Internal.Time.timerTock(OpenModelica.Scripting.Internal.Time.RT_CLOCK_SIMULATE_TOTAL)") start=monotonic() timeout = conf["ulimitOmc"] +# If the command has to be killed there is no way to tell which phase it was in, +# so its time is charged to what the command itself is: building an FMU to the +# build, simulating to the simulation, translating to the front end - which is +# also the phase such a model is reported as having failed in. if conf.get("fmi"): cmd='"" <> buildModelFMU(%s,fileNamePrefix="%s",fmuType="%s",version="%s",platforms={"static"})' % (conf["modelName"],conf["fileName"].replace(".","_"),conf["fmuType"],conf["fmi"]) + timedPhase = "build" elif useSimulate: cmd=simulateCmd(resimulate=False) timeout = conf["ulimitOmc"] + conf["ulimitExe"] + timedPhase = "sim" else: cmd='translateModel(%s,tolerance=%g,outputFormat="%s",numberOfIntervals=%d,variableFilter="%s",fileNamePrefix="%s")' % (conf["modelName"],tolerance,outputFormat,numberOfIntervals,variableFilter,conf["fileName"]) + timedPhase = "frontend" with open(errFile, 'a+') as fp: fp.write("Running command: %s\n"%(cmd)) try: + phaseStarts(timedPhase) res=sendExpressionTimeout(omc, cmd, timeout) + phaseEnded() except TimeoutError as e: - execstat["frontend"]=monotonic()-start + execstat[timedPhase]=monotonic()-start with open(errFile, 'a+') as fp: fp.write("Timeout error for cmd: %s\n%s"%(cmd,str(e))) From dc682c82ddf359e5681ce061b69086867a106612 Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Wed, 12 Aug 2026 22:20:56 +0200 Subject: [PATCH 438/452] Let the other simulators run when the first one fails (#311) An FMI job that runs several simulators over one FMU (#297, #309) gives the first of them a veto over the rest. When it fails, the TimeoutError handler calls writeResultAndExit, the process is gone, and the loop that runs fmisimulators[1:] never starts -- but a row is still written for every simulator, recording the phase the first one stopped at. The other tools are marked as having failed at a model they were never given. checkOutputTimeout raises TimeoutError for a command that exits non-zero as well as for one that runs out of time, so this covers an ordinary failure and not just a slow one. In the master-fmi run of 2026-08-12 this cost 433 models. They had never simulated under OMSimulator -- phase 5 in every master-fmi run back to 2026-08-08 -- but FMPy ran them, and the previous master-fmi-fmpy run has them at phase 6 or 7. In the first combined run they are phase 5 in both tables, with FMPy's simulation time recorded as exactly 0: OMSimulator failed in under a second for 344 of them, and FMPy never started. They show up as 433 of the 653 regressions on the comparison page, next to the 213 that PR #309 really did find. It is also why that page reports OMSimulator's version, and its JSON parse warning, in place of "FMPy version 0.3.29": FMPy never ran to say what it was. The first simulator now records its failure and falls through to the others, which is what every simulator after it already did. Nothing changes when only one simulator is configured: that case still ends the model where it always has, so the non-FMI paths and the single-simulator FMI jobs are untouched. Verified on MyLibrary.Blocks.Examples.PID_Controller with the first simulator replaced by /bin/false: before phase 5, "simulators": {} after phase 5, "simulators": {"fmpy": {"sim": 0.64, "phase": 7}} and, unchanged in both: one failing simulator phase 5, os._exit as before both simulators working OMSimulator phase 7, fmpy phase 7 Claude-Session: https://claude.ai/code/session_01MYvMaAotMy425H7nvKzWX7 Co-authored-by: Claude Opus 5 (1M context) --- testmodel.py | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/testmodel.py b/testmodel.py index bd89869..da5e1c7 100755 --- a/testmodel.py +++ b/testmodel.py @@ -646,6 +646,9 @@ def simElapsed(): return monotonic()-start start=monotonic() +# Set when the first FMI simulator fails and there are others waiting for the +# same FMU, so that its result file is not compared against the reference. +firstSimulatorFailed = False try: # TODO: Timeout more reliably... if conf.get("fmi"): @@ -709,7 +712,20 @@ def simElapsed(): execstat["phase"] = 6 except TimeoutError as e: execstat["sim"] = monotonic()-start - writeResultAndExit(0, True, omc, omc_new) + # checkOutputTimeout raises TimeoutError for a command that fails as well as + # for one that runs out of time, so this covers both. + if len(fmisimulators) > 1: + # The FMU is built and the other simulators are about to run it. What the + # first one did says nothing about them, so record the failure and let them + # have their turn. Ending the model here would write them all down as having + # failed at this phase without ever being started, which is what the loop + # below already avoids for a failure in any simulator but the first. + firstSimulatorFailed = True + with open(errFile, 'a+') as fp: + fp.write("%s failed or timed out simulating the FMU; the other simulators still get to run it\n" + % fmisimulators[0][0]) + else: + writeResultAndExit(0, True, omc, omc_new) def verifyAgainstReference(resFile, prefix, stat): """Compare one simulation result against the reference file. @@ -822,12 +838,14 @@ def verifyAgainstReference(resFile, prefix, stat): # The first simulator's results are the ones every non-FMI code path expects. -verifyAgainstReference(resFile, artifactPrefix(fmisimulators[0][0] if fmisimulators else None) + ".diff", execstat) +# There is nothing to compare when it never produced any. +if not firstSimulatorFailed: + verifyAgainstReference(resFile, artifactPrefix(fmisimulators[0][0] if fmisimulators else None) + ".diff", execstat) # The FMU is built; every other simulator the job asked for is now only a # simulation and a comparison. A tool that times out or fails takes its own -# results down with it and leaves the others alone - unlike the first one, -# whose timeout ends the model as it always has. +# results down with it and leaves the others alone - the first one included, +# see the TimeoutError handler above. for (name, command) in fmisimulators[1:]: stat = {"sim": None, "diff": None, "phase": 5} simulators[name] = stat From d82101fdb995c66ec7d8e60d308df6fe9b19daef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Thu, 13 Aug 2026 11:35:16 +0200 Subject: [PATCH 439/452] Merge report stages and add wasm-jit to history/overview (#312) - Merge ryzen-5950x-1 and ryzen-5950x-2 report stages into a single stage (Postgres makes this fast) - Add wasm-jit to all-reports.py/all-plots.py so history reports are generated for it - Include wasm-jit in overview-combined.html and overview-special-jobs.html alongside master and newInst-newBackend Co-authored-by: Qwen 27B --- .CI/Jenkinsfile | 289 ++++++++++++++++++++---------------------------- 1 file changed, 120 insertions(+), 169 deletions(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index a647eca..e724be4 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -427,177 +427,128 @@ pipeline { } } } } - stage('report') { parallel { - stage('ryzen-5950x-1') { - agent { - dockerfile { - label 'linux' - dir '.CI/build-dep' - customWorkspace 'ws/OpenModelicaLibraryTestingReport' - args '-e IDA_EMAIL_USR=$IDA_EMAIL_USR -e IDA_EMAIL_PSW=$IDA_EMAIL_PSW' - } - } - when { - beforeAgent true - expression { params.v1_25 || params.v1_26 || params.v1_27 || params.master || params.conversion_script || params.report_ryzen_5950x_1 || params.newInst_newBackend || params.generateSymbolicJacobian || params.heavy_tests} - } - environment { - GITBRANCHES = 'maintenance/v1.20 maintenance/v1.21 maintenance/v1.22 maintenance/v1.23 maintenance/v1.24 maintenance/v1.25 maintenance/v1.26 maintenance/v1.27 master newInst-newBackend' - PYTHONIOENCODING = 'utf-8' - IDA_EMAIL = credentials('IDA email') - // A secret file holding one pgpass line; libpq reads the password from - // it, so it never reaches a command line or the build log. It is bound - // per stage because writing the file needs the workspace of a node, - // which the pipeline as a whole does not have (agent none). - PGPASSFILE = credentials('omdb-pgpass') - } - steps { - //sshagent (credentials: ['Hudson-SSH-Key']) { - // createInitialHistoryFilesOnRemote() - //} - sh 'rm -rf *.html history' - sh ''' - if ! test -d OpenModelica; then - git clone https://openmodelica.org/git-readonly/OpenModelica.git - fi - cd OpenModelica - git fetch - ''' - sh './clean-empty-omcversion-dates.py' - - sh "./all-reports.py --email --omcgitdir=OpenModelica ${env.GITBRANCHES} conversion heavy_tests" - sh "./all-plots.py ${env.GITBRANCHES}" - - sh "./report.py --branches='${env.GITBRANCHES}' configs/conf.json configs/conf-old.json configs/conf-nonstandard.json" - sh 'mv overview.html overview-combined.html' - sh "./report.py --branches='${env.GITBRANCHES}' configs/conf-old.json" - sh "mv overview.html overview-old-libs.html" - sh "./report.py --branches='${env.GITBRANCHES}' configs/conf-nonstandard.json" - sh "mv overview.html overview-nonstandard-libs.html" - sh "./report.py --branches='master conversion' configs/conf.json" - sh "mv overview.html overview-special-jobs.html" - - sh "./report.py --branches='generateSymbolicJacobian' configs/conf.json" - sh "mv overview.html overview-generateSymbolicJacobian.html" - - sh "./report.py --branches='heavy_tests' configs/heavy_tests.json" - sh "mv overview.html overview-heavy_tests.html" - - sh "./report.py --branches='${env.GITBRANCHES}' configs/conf.json" - - sh 'date' - sh 'find overview*.html history -type f | wc -l' - sh 'find overview*.html history' - - sshPublisher(publishers: [sshPublisherDesc(configName: 'LibraryTestingReports', transfers: [sshTransfer(sourceFiles: 'overview*.html,history/**')])]) - + stage('report') { + agent { + dockerfile { + label 'linux' + dir '.CI/build-dep' + customWorkspace 'ws/OpenModelicaLibraryTestingReport' + args '-e IDA_EMAIL_USR=$IDA_EMAIL_USR -e IDA_EMAIL_PSW=$IDA_EMAIL_PSW' } } - - stage('ryzen-5950x-2') { - agent { - dockerfile { - label 'linux' - dir '.CI/build-dep' - customWorkspace 'ws/OpenModelicaLibraryTestingReport' - args '-e IDA_EMAIL_USR=$IDA_EMAIL_USR -e IDA_EMAIL_PSW=$IDA_EMAIL_PSW' - } - } - when { - beforeAgent true - expression { params.fmi_v1_25 || params.fmi_v1_26 || params.fmi_v1_27 || params.fmi_master || params.fmpy_fmi_v1_25 || params.fmpy_fmi_v1_26 || params.fmpy_fmi_v1_27 || params.fmpy_fmi_master || params.newInst_daeMode || params.newBackend_daeMode || params.oldInst || params.report_ryzen_5950x_2 || params.cpp || params.cvode || params.gbode || params.ida || params.wasm_jit} - } - environment { - GITBRANCHES_FMI = 'maintenance/v1.20-fmi maintenance/v1.21-fmi maintenance/v1.22-fmi maintenance/v1.23-fmi maintenance/v1.24-fmi maintenance/v1.25-fmi maintenance/v1.26-fmi maintenance/v1.27-fmi maintenance/v1.22-fmi-fmpy maintenance/v1.23-fmi-fmpy maintenance/v1.24-fmi-fmpy maintenance/v1.25-fmi-fmpy maintenance/v1.26-fmi-fmpy maintenance/v1.27-fmi-fmpy master-fmi master-fmi-fmpy' - GITBRANCHES_NEWINST = 'oldInst' - GITBRANCHES_DAE = 'newInst-daeMode' - GITBRANCHES_NEWBACKEND_DAE = 'newBackend-daeMode' - GITBRANCHES_CPP = 'v1.19-cpp v1.20-cpp v1.21-cpp v1.22-cpp v1.23-cpp v1.24-cpp v1.25-cpp cpp v1.26-cpp v1.27-cpp' - PYTHONIOENCODING = 'utf-8' - IDA_EMAIL = credentials('IDA email') - // A secret file holding one pgpass line; libpq reads the password from - // it, so it never reaches a command line or the build log. It is bound - // per stage because writing the file needs the workspace of a node, - // which the pipeline as a whole does not have (agent none). - PGPASSFILE = credentials('omdb-pgpass') - } - steps { - //sshagent (credentials: ['Hudson-SSH-Key']) { - // createInitialHistoryFilesOnRemote() - //} - sh 'rm -f *.html' - sh ''' - if ! test -d OpenModelica; then - git clone https://openmodelica.org/git-readonly/OpenModelica.git - fi - cd OpenModelica - git fetch - ''' - sh './clean-empty-omcversion-dates.py' - - sh "./all-reports.py --email --omcgitdir=OpenModelica ${env.GITBRANCHES_FMI} ${env.GITBRANCHES_NEWINST} ${env.GITBRANCHES_DAE} ${env.GITBRANCHES_NEWBACKEND_DAE} ${env.GITBRANCHES_CPP} gbode cvode ida" - sh "./all-plots.py ${env.GITBRANCHES_FMI} ${env.GITBRANCHES_NEWINST} ${env.GITBRANCHES_DAE} ${env.GITBRANCHES_NEWBACKEND_DAE} ${env.GITBRANCHES_CPP} gbode cvode ida" - - sh "./report.py --branches='${env.GITBRANCHES_NEWINST}' configs/conf.json" - sh "mv overview.html overview-oldinst.html" - sh "./report.py --branches='${env.GITBRANCHES_NEWINST}' configs/conf.json configs/conf-old.json configs/conf-nonstandard.json" - sh "mv overview.html overview-combined-oldinst.html" - sh "./report.py --branches='${env.GITBRANCHES_NEWINST}' configs/conf-old.json" - sh "mv overview.html overview-old-libs-oldinst.html" - sh "./report.py --branches='${env.GITBRANCHES_NEWINST}' configs/conf-nonstandard.json" - sh "mv overview.html overview-nonstandard-libs-oldinst.html" - - sh "./report.py --branches='${env.GITBRANCHES_FMI}' configs/conf.json" - sh "mv overview.html overview-fmi.html" - sh "./report.py --branches='${env.GITBRANCHES_FMI}' configs/conf.json configs/conf-old.json configs/conf-nonstandard.json" - sh "mv overview.html overview-combined-fmi.html" - sh "./report.py --branches='${env.GITBRANCHES_FMI}' configs/conf-old.json" - sh "mv overview.html overview-old-libs-fmi.html" - sh "./report.py --branches='${env.GITBRANCHES_FMI}' configs/conf-nonstandard.json" - sh "mv overview.html overview-nonstandard-libs-fmi.html" - - sh "./report.py --branches='${env.GITBRANCHES_DAE}' configs/conf.json" - sh "mv overview.html overview-dae.html" - sh "./report.py --branches='${env.GITBRANCHES_DAE}' configs/conf.json configs/conf-old.json configs/conf-nonstandard.json" - sh "mv overview.html overview-combined-dae.html" - sh "./report.py --branches='${env.GITBRANCHES_DAE}' configs/conf-old.json" - sh "mv overview.html overview-old-libs-dae.html" - sh "./report.py --branches='${env.GITBRANCHES_DAE}' configs/conf-nonstandard.json" - sh "mv overview.html overview-nonstandard-libs-dae.html" - - sh "./report.py --branches='${env.GITBRANCHES_NEWBACKEND_DAE}' configs/conf.json" - sh "mv overview.html overview-newbackend-dae.html" - sh "./report.py --branches='${env.GITBRANCHES_NEWBACKEND_DAE}' configs/conf.json configs/conf-old.json configs/conf-nonstandard.json" - sh "mv overview.html overview-combined-newbackend-dae.html" - sh "./report.py --branches='${env.GITBRANCHES_NEWBACKEND_DAE}' configs/conf-old.json" - sh "mv overview.html overview-old-libs-newbackend-dae.html" - sh "./report.py --branches='${env.GITBRANCHES_NEWBACKEND_DAE}' configs/conf-nonstandard.json" - sh "mv overview.html overview-nonstandard-libs-newbackend-dae.html" - - sh "./report.py --branches='cvode' configs/conf.json" - sh "mv overview.html overview-cvode.html" - - sh "./report.py --branches='gbode' configs/conf.json" - sh "mv overview.html overview-gbode.html" - - sh "./report.py --branches='ida' configs/conf.json" - sh "mv overview.html overview-ida.html" - - sh "./report.py --branches='wasm-jit' configs/conf.json" - sh "mv overview.html overview-wasm-jit.html" - - sh "./report.py --branches='${env.GITBRANCHES_CPP}' configs/conf.json" - sh "mv overview.html overview-c++.html" - - sh 'date' - sh 'find overview*.html history -type f | wc -l' - sh 'find overview*.html history' - - sshPublisher(publishers: [sshPublisherDesc(configName: 'LibraryTestingReports', transfers: [sshTransfer(sourceFiles: 'overview-*.html,history/**')])]) - - } + when { + beforeAgent true + expression { params.v1_25 || params.v1_26 || params.v1_27 || params.master || params.conversion_script || params.report_ryzen_5950x_1 || params.report_ryzen_5950x_2 || params.newInst_newBackend || params.generateSymbolicJacobian || params.heavy_tests || params.fmi_v1_25 || params.fmi_v1_26 || params.fmi_v1_27 || params.fmi_master || params.fmpy_fmi_v1_25 || params.fmpy_fmi_v1_26 || params.fmpy_fmi_v1_27 || params.fmpy_fmi_master || params.newInst_daeMode || params.newBackend_daeMode || params.oldInst || params.cpp || params.cvode || params.gbode || params.ida || params.wasm_jit} } - } } + environment { + GITBRANCHES = 'maintenance/v1.20 maintenance/v1.21 maintenance/v1.22 maintenance/v1.23 maintenance/v1.24 maintenance/v1.25 maintenance/v1.26 maintenance/v1.27 master newInst-newBackend' + GITBRANCHES_FMI = 'maintenance/v1.20-fmi maintenance/v1.21-fmi maintenance/v1.22-fmi maintenance/v1.23-fmi maintenance/v1.24-fmi maintenance/v1.25-fmi maintenance/v1.26-fmi maintenance/v1.27-fmi maintenance/v1.22-fmi-fmpy maintenance/v1.23-fmi-fmpy maintenance/v1.24-fmi-fmpy maintenance/v1.25-fmi-fmpy maintenance/v1.26-fmi-fmpy maintenance/v1.27-fmi-fmpy master-fmi master-fmi-fmpy' + GITBRANCHES_NEWINST = 'oldInst' + GITBRANCHES_DAE = 'newInst-daeMode' + GITBRANCHES_NEWBACKEND_DAE = 'newBackend-daeMode' + GITBRANCHES_CPP = 'v1.19-cpp v1.20-cpp v1.21-cpp v1.22-cpp v1.23-cpp v1.24-cpp v1.25-cpp cpp v1.26-cpp v1.27-cpp' + GITBRANCHES_WASM_JIT = 'wasm-jit' + GITBRANCHES_SPECIAL = 'master wasm-jit newInst-newBackend' + PYTHONIOENCODING = 'utf-8' + IDA_EMAIL = credentials('IDA email') + // A secret file holding one pgpass line; libpq reads the password from + // it, so it never reaches a command line or the build log. It is bound + // per stage because writing the file needs the workspace of a node, + // which the pipeline as a whole does not have (agent none). + PGPASSFILE = credentials('omdb-pgpass') + } + steps { + //sshagent (credentials: ['Hudson-SSH-Key']) { + // createInitialHistoryFilesOnRemote() + //} + sh 'rm -rf *.html history' + sh ''' + if ! test -d OpenModelica; then + git clone https://openmodelica.org/git-readonly/OpenModelica.git + fi + cd OpenModelica + git fetch + ''' + sh './clean-empty-omcversion-dates.py' + + sh "./all-reports.py --email --omcgitdir=OpenModelica ${env.GITBRANCHES} ${env.GITBRANCHES_FMI} ${env.GITBRANCHES_NEWINST} ${env.GITBRANCHES_DAE} ${env.GITBRANCHES_NEWBACKEND_DAE} ${env.GITBRANCHES_CPP} ${env.GITBRANCHES_WASM_JIT} conversion heavy_tests generateSymbolicJacobian gbode cvode ida" + sh "./all-plots.py ${env.GITBRANCHES} ${env.GITBRANCHES_FMI} ${env.GITBRANCHES_NEWINST} ${env.GITBRANCHES_DAE} ${env.GITBRANCHES_NEWBACKEND_DAE} ${env.GITBRANCHES_CPP} ${env.GITBRANCHES_WASM_JIT} conversion heavy_tests generateSymbolicJacobian gbode cvode ida" + + sh "./report.py --branches='${env.GITBRANCHES} ${env.GITBRANCHES_WASM_JIT}' configs/conf.json configs/conf-old.json configs/conf-nonstandard.json" + sh 'mv overview.html overview-combined.html' + sh "./report.py --branches='${env.GITBRANCHES} ${env.GITBRANCHES_WASM_JIT}' configs/conf-old.json" + sh "mv overview.html overview-old-libs.html" + sh "./report.py --branches='${env.GITBRANCHES} ${env.GITBRANCHES_WASM_JIT}' configs/conf-nonstandard.json" + sh "mv overview.html overview-nonstandard-libs.html" + sh "./report.py --branches='${env.GITBRANCHES_SPECIAL} conversion' configs/conf.json" + sh "mv overview.html overview-special-jobs.html" + + sh "./report.py --branches='generateSymbolicJacobian' configs/conf.json" + sh "mv overview.html overview-generateSymbolicJacobian.html" + + sh "./report.py --branches='heavy_tests' configs/heavy_tests.json" + sh "mv overview.html overview-heavy_tests.html" + + sh "./report.py --branches='${env.GITBRANCHES_NEWINST}' configs/conf.json" + sh "mv overview.html overview-oldinst.html" + sh "./report.py --branches='${env.GITBRANCHES_NEWINST}' configs/conf.json configs/conf-old.json configs/conf-nonstandard.json" + sh "mv overview.html overview-combined-oldinst.html" + sh "./report.py --branches='${env.GITBRANCHES_NEWINST}' configs/conf-old.json" + sh "mv overview.html overview-old-libs-oldinst.html" + sh "./report.py --branches='${env.GITBRANCHES_NEWINST}' configs/conf-nonstandard.json" + sh "mv overview.html overview-nonstandard-libs-oldinst.html" + + sh "./report.py --branches='${env.GITBRANCHES_FMI}' configs/conf.json" + sh "mv overview.html overview-fmi.html" + sh "./report.py --branches='${env.GITBRANCHES_FMI}' configs/conf.json configs/conf-old.json configs/conf-nonstandard.json" + sh "mv overview.html overview-combined-fmi.html" + sh "./report.py --branches='${env.GITBRANCHES_FMI}' configs/conf-old.json" + sh "mv overview.html overview-old-libs-fmi.html" + sh "./report.py --branches='${env.GITBRANCHES_FMI}' configs/conf-nonstandard.json" + sh "mv overview.html overview-nonstandard-libs-fmi.html" + + sh "./report.py --branches='${env.GITBRANCHES_DAE}' configs/conf.json" + sh "mv overview.html overview-dae.html" + sh "./report.py --branches='${env.GITBRANCHES_DAE}' configs/conf.json configs/conf-old.json configs/conf-nonstandard.json" + sh "mv overview.html overview-combined-dae.html" + sh "./report.py --branches='${env.GITBRANCHES_DAE}' configs/conf-old.json" + sh "mv overview.html overview-old-libs-dae.html" + sh "./report.py --branches='${env.GITBRANCHES_DAE}' configs/conf-nonstandard.json" + sh "mv overview.html overview-nonstandard-libs-dae.html" + + sh "./report.py --branches='${env.GITBRANCHES_NEWBACKEND_DAE}' configs/conf.json" + sh "mv overview.html overview-newbackend-dae.html" + sh "./report.py --branches='${env.GITBRANCHES_NEWBACKEND_DAE}' configs/conf.json configs/conf-old.json configs/conf-nonstandard.json" + sh "mv overview.html overview-combined-newbackend-dae.html" + sh "./report.py --branches='${env.GITBRANCHES_NEWBACKEND_DAE}' configs/conf-old.json" + sh "mv overview.html overview-old-libs-newbackend-dae.html" + sh "./report.py --branches='${env.GITBRANCHES_NEWBACKEND_DAE}' configs/conf-nonstandard.json" + sh "mv overview.html overview-nonstandard-libs-newbackend-dae.html" + + sh "./report.py --branches='cvode master' configs/conf.json" + sh "mv overview.html overview-cvode.html" + + sh "./report.py --branches='gbode master' configs/conf.json" + sh "mv overview.html overview-gbode.html" + + sh "./report.py --branches='ida master' configs/conf.json" + sh "mv overview.html overview-ida.html" + + sh "./report.py --branches='wasm-jit master' configs/conf.json" + sh "mv overview.html overview-wasm-jit.html" + + sh "./report.py --branches='${env.GITBRANCHES_CPP}' configs/conf.json" + sh "mv overview.html overview-c++.html" + + sh "./report.py --branches='${env.GITBRANCHES}' configs/conf.json" + + sh 'date' + sh 'find overview*.html history -type f | wc -l' + sh 'find overview*.html history' + + sshPublisher(publishers: [sshPublisherDesc(configName: 'LibraryTestingReports', transfers: [sshTransfer(sourceFiles: 'overview*.html,history/**')])]) + } + } } } def omsimulatorHash() { @@ -633,7 +584,7 @@ HISTORY_DIRECTORY='/var/www/libraries.openmodelica.org/branches/history/' SEPARATOR='/' HISTORY_FILE='00_history.html' -for b in ${env.GITBRANCHES} ${env.GITBRANCHES_FMI} ${env.GITBRANCHES_NEWINST} ${env.GITBRANCHES_DAE} ${env.GITBRANCHES_CPP}; do +for b in ${env.GITBRANCHES} ${env.GITBRANCHES_FMI} ${env.GITBRANCHES_NEWINST} ${env.GITBRANCHES_DAE} ${env.GITBRANCHES_CPP} ${env.GITBRANCHES_WASM_JIT}; do BRANCH=`echo \${b} | cut -d '/' -f2` FILE="\${HISTORY_DIRECTORY}\${BRANCH}\${SEPARATOR}\${HISTORY_FILE}" ssh hudson@build.openmodelica.org << EOF From dc39a10519e67276ea3e8acccd7f008c72524027 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Thu, 13 Aug 2026 13:59:25 +0200 Subject: [PATCH 440/452] Strip -rust suffix from version for git range queries (#313) The all-reports script uses omcversion from the database to build git range specs like 'v1..v2' for commit log lookups. Rust builds append '-rust' to the version (e.g. 'v1.28.0-dev-308-g1ac9d5ad20-rust') which git cannot resolve as a tag or ref. Strip the trailing '-rust' before the version is used in git commands so the underlying tag (e.g. 'v1.28.0-dev-308-g1ac9d5ad20') is found. Co-authored-by: Qwen3.6-27B-TQ --- all-reports.py | 1 + 1 file changed, 1 insertion(+) diff --git a/all-reports.py b/all-reports.py index dbd1a5b..c100d42 100755 --- a/all-reports.py +++ b/all-reports.py @@ -56,6 +56,7 @@ def dateStr(dint): def getTagOrVersion(v): v = v.replace("OpenModelica ","").replace("OMCompiler ","") + v = re.sub(r"-rust$", "", v) m = re.search("[+]g([0-9a-f]{7}[0-9a-f]*)$", v) if m: return m.group(1) From 2ee99a9b643611496da0a4242185b396740ef9d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Thu, 13 Aug 2026 18:23:01 +0200 Subject: [PATCH 441/452] Install jinja2 in wasm-jit image for Buildings library (#314) The Buildings library's install.py requires jinja2 to generate HTML tables for EnergyPlus Spawn actuator/output variables. Co-authored-by: Qwen3.6 27B --- .CI/wasm-jit/Dockerfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.CI/wasm-jit/Dockerfile b/.CI/wasm-jit/Dockerfile index 5f309c6..78b8b72 100644 --- a/.CI/wasm-jit/Dockerfile +++ b/.CI/wasm-jit/Dockerfile @@ -15,6 +15,8 @@ RUN export DEBIAN_FRONTEND=noninteractive \ COPY requirements.txt /tmp/requirements.txt RUN python3 -m venv /opt/libtest-venv \ && /opt/libtest-venv/bin/pip install --no-cache-dir -r /tmp/requirements.txt \ + # Python dependencies of library install scripts (e.g. Buildings EnergyPlus) + && /opt/libtest-venv/bin/pip install --no-cache-dir jinja2 \ && rm /tmp/requirements.txt ENV PATH=/opt/libtest-venv/bin:$PATH From c65d56a179b5a287172adb19c131e9eca9c0e04d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Fri, 14 Aug 2026 08:44:36 +0200 Subject: [PATCH 442/452] Add some MDD dependencies (#315) --- .CI/wasm-jit/Dockerfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.CI/wasm-jit/Dockerfile b/.CI/wasm-jit/Dockerfile index 78b8b72..1fd8d66 100644 --- a/.CI/wasm-jit/Dockerfile +++ b/.CI/wasm-jit/Dockerfile @@ -4,9 +4,11 @@ FROM docker.openmodelica.org/build-deps:ubuntu-26.04-rust # rsync/ssh publish the results; time and killall are used around test.py. +# libcomedi-dev libx11-dev is used by Modelica_DeviceDrivers RUN export DEBIAN_FRONTEND=noninteractive \ && apt-get update \ && apt-get install -qy --no-install-recommends openssh-client psmisc rsync time \ + && apt-get install -qy --no-install-recommends libcomedi-dev libx11-dev \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* From cb514ad4a4a6f7aaa530a03c6cf68e94ff743566 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Mon, 17 Aug 2026 07:06:09 +0200 Subject: [PATCH 443/452] Run wasm-jit on same node as master (#316) --- .CI/Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index e724be4..c8327f8 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -329,7 +329,7 @@ pipeline { stage('wasm-jit') { agent { node { - label 'ryzen-5950x-2-1' + label 'ryzen-5950x-1' customWorkspace 'ws/OpenModelicaLibraryTestingWork' } } From ed8e4cbe9ec432063765405aedeedf394bc1b0cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Mon, 17 Aug 2026 16:00:09 +0200 Subject: [PATCH 444/452] Limit the memory of a dockerized test job (#317) test.py caps the address space of one test at a time, so nothing bounds the sum of the tests it runs in parallel. That is worst for wasm-jit, whose tests are allowed 16 GB of address space each because the JIT reserves ~4 GB of it per wasm memory. Cap the container the job runs in with `docker run --memory=N --memory-swap=N`, N = 85% of the node's RAM, since these jobs are pinned to the high-memory nodes. A cgroup limit charges memory in use rather than address space, covers every process test.py spawns, and on a breach the kernel kills the greediest omc - so a model can now fail because of a model tested in parallel with it, which the log makes visible: the limit is printed before the run and the peak plus the OOM kill count after it. Only the targets that build their own image (wasm-jit today) get this; the jobs running directly on a node are unchanged. Co-authored-by: Claude Opus 5 (1M context) --- .CI/Jenkinsfile | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index c8327f8..931bbf0 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -598,6 +598,18 @@ done """ } +/** + * `docker run` flags capping the container's cgroup at 90% of the node's RAM. test.py limits one + * test at a time, not the sum of the parallel ones. --memory-swap has to repeat the limit; docker + * reads 0 as "unset" and then allows swapping. + */ +def memoryLimitArgs() { + def mb = sh(script: '''awk '/^MemTotal:/ { print int($2 / 1024 * 0.85) }' /proc/meminfo''', + returnStdout: true).trim() + echo "Test container memory limit: ${mb} MB, no swap" + return "--memory=${mb}m --memory-swap=${mb}m" +} + /** * Runs `body` with the environment of the shared Rust compile cache of the OpenModelica job * (OpenModelica/.CI/sccache/), which builds the same commits first. Hitting its keys needs the @@ -713,10 +725,17 @@ def runRegressiontest(branch, name, extraFlags, omsHash, omcompiler, extrasimfla // build, the libraries (HOME during the test) and the ssh key; test.py writes a hash next to // every reference file. rust-cargo-registry is the volume the OpenModelica job uses. def dockerArgs = "--init" + + (image ? " ${memoryLimitArgs()}" : '') + " -v /etc/passwd:/etc/passwd:ro -v /etc/group:/etc/group:ro" + " -v ${env.HOME}:${env.HOME}" + " -v /mnt/ReferenceFiles:/mnt/ReferenceFiles" + " --mount type=volume,source=rust-cargo-registry,target=/opt/rust/cargo/registry" + // Only in a container is the cgroup this job's own; a breach kills the greediest omc, which need + // not be the model that caused it. + def cgroupReport = image ? """ + cat /sys/fs/cgroup/memory.max || true + trap 'cat /sys/fs/cgroup/memory.peak /sys/fs/cgroup/memory.events || true' EXIT + """ : '' // Jenkins exports the node's environment into the container, hiding the image's. def dockerEnv = ['PATH+VENV=/opt/libtest-venv/bin', 'PATH+CARGO=/opt/rust/cargo/bin', @@ -956,6 +975,7 @@ def runRegressiontest(branch, name, extraFlags, omsHash, omcompiler, extrasimfla # too bad if we cannot do it, just continue ln -s -t \${HOME} \${PREVIOUSHOME}/.local .local || true + ${cgroupReport} cd OpenModelicaLibraryTesting # Force /usr/bin/omc as being used for generating the mos-files. Ensures consistent behavior among all tested OMC versions stdbuf -oL -eL time ./test.py --ompython_omhome=/usr ${FMI_TESTING_FLAG} --extraflags='${extraFlags}' --extrasimflags='${extrasimflags}' ${testFlags} --branch="${name}" --output="libraries.openmodelica.org:/var/www/libraries.openmodelica.org/branches/${name}/" --libraries='${libraryPath}/.openmodelica/libraries/' --jobs=${jobs} ${libs_config_file} ${params.OLDLIBS ? "configs/conf-old.json configs/conf-nonstandard.json" : ""} || (killall omc ; false) || exit 1 From 9a153eb02e692b0508f82a9cf28b3af9ad40eaf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Tue, 18 Aug 2026 07:18:28 +0200 Subject: [PATCH 445/452] Give wasm-jit more RAM (#318) --- .CI/Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index 931bbf0..04db1ce 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -329,7 +329,7 @@ pipeline { stage('wasm-jit') { agent { node { - label 'ryzen-5950x-1' + label 'ryzen-5950x-2' customWorkspace 'ws/OpenModelicaLibraryTestingWork' } } From b5ecbba5c320692cb1137daf72abe84a3f965729 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Tue, 18 Aug 2026 14:22:58 +0200 Subject: [PATCH 446/452] wasm-jit should run on 9950x --- .CI/Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index 04db1ce..c12abc4 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -329,7 +329,7 @@ pipeline { stage('wasm-jit') { agent { node { - label 'ryzen-5950x-2' + label 'ryzen-9950x' customWorkspace 'ws/OpenModelicaLibraryTestingWork' } } From 9078733dde678840dcd0fdd82be96281d5216114 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Tue, 18 Aug 2026 20:35:21 +0200 Subject: [PATCH 447/452] Add old Python packages to wasm-jit image --- .CI/wasm-jit/Dockerfile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.CI/wasm-jit/Dockerfile b/.CI/wasm-jit/Dockerfile index 1fd8d66..2a66dab 100644 --- a/.CI/wasm-jit/Dockerfile +++ b/.CI/wasm-jit/Dockerfile @@ -5,10 +5,14 @@ FROM docker.openmodelica.org/build-deps:ubuntu-26.04-rust # rsync/ssh publish the results; time and killall are used around test.py. # libcomedi-dev libx11-dev is used by Modelica_DeviceDrivers +# Python 3.8 and 3.12 are used by Buildings RUN export DEBIAN_FRONTEND=noninteractive \ && apt-get update \ + && apt-get install -qy software-properties-common \ + && add-apt-repository -y ppa:deadsnakes/ppa \ && apt-get install -qy --no-install-recommends openssh-client psmisc rsync time \ && apt-get install -qy --no-install-recommends libcomedi-dev libx11-dev \ + && apt-get install -qy python3.8 python3.12 \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* From 26ba4cfbe51e1e8fc6ae37a1374873df02ac096d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Thu, 20 Aug 2026 10:18:29 +0200 Subject: [PATCH 448/452] Fix BuildSysPro's external "C" include directory (#319) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Its IncludeDirectory annotations name modelica://BuildSysPro/Resources/C-Sources, which the library does not have — the IBPSA C sources are in IBPSA/Resources/C-Sources, and in a stale copy under Resources/IBPSA/C-Sources in 3.5.0 and older. omc therefore emitted no -I for them and every model reaching one failed to compile. Add both directories with setCFlags, plus the -include flags a few of those sources need: they call str*/malloc/ModelicaError without including the header, and only compile for the C target because the surrounding translation unit happens to have it. With --nobuildmodel, translating and building share one simulate() call and only the record's messages says either failed. Tell them apart by the translation clocks, so a wasm-jit build failure — the JIT compile, or building the model's Include C sources — is reported as Compile rather than as SimCode or Simulate. Assisted-by: Claude Opus 5 --- configs/conf.json | 4 +++- testmodel.py | 11 +++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/configs/conf.json b/configs/conf.json index e038012..315cea0 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -210,7 +210,9 @@ "libraryVersionNameForTests":"" }, { - "library":"BuildSysPro" + "library":"BuildSysPro", + "_comment":"IncludeDirectory says modelica://BuildSysPro/Resources/C-Sources, which does not exist; the IBPSA C sources are in IBPSA/Resources/C-Sources (Resources/IBPSA/C-Sources in 3.5.0 and older). Some of them call str*/malloc/ModelicaError without including the header", + "extraCustomCommands":["setCFlags(getCFlags() + \" -include string.h -include stdlib.h -include ModelicaUtilities.h \\\"-I$libraryLocation/IBPSA/Resources/C-Sources\\\" \\\"-I$libraryLocation/Resources/IBPSA/C-Sources\\\"\")"] }, { "library":"BusinessSimulation" diff --git a/testmodel.py b/testmodel.py index da5e1c7..00e59a6 100755 --- a/testmodel.py +++ b/testmodel.py @@ -508,10 +508,13 @@ def simulateCmd(resimulate): execTimeTranslateModel=monotonic()-start simres = None +buildFailed = False if useSimulate: simres = res or {} - # A failed translate/build is only reported in the messages of the record - res = not (simres.get("messages") or "").startswith("Failed to build model") + # A failed translate/build is only reported in the messages of the record; the + # translation clocks below say which of the two it was + buildFailed = (simres.get("messages") or "").startswith("Failed to build model") + res = True err = omc.sendExpression("OpenModelica.Scripting.getErrorString()") total = omc.sendExpression("OpenModelica.Scripting.Internal.Time.timerTock(OpenModelica.Scripting.Internal.Time.RT_CLOCK_SIMULATE_TOTAL)")-total_before buildmodel = omc.sendExpression("OpenModelica.Scripting.Internal.Time.timerTock(OpenModelica.Scripting.Internal.Time.RT_CLOCK_BUILD_MODEL)") @@ -573,6 +576,10 @@ def simulateCmd(resimulate): # a resimulate leaves it in the simulation time execstat["build"] = simres["timeCompile"] if useSimulate else 0.0 execstat["phase"] = 5 + if buildFailed: + with open(errFile, 'a+') as fp: + fp.write(simres.get("messages") or "") + writeResultAndExit(0, False, omc, omc_new) else: if isWin: res = checkOutputTimeout("\"%s\\share\\omc\\scripts\\Compile.bat\" %s gcc %s parallel dynamic 24 0" % (conf["omhome"], conf["fileName"], msysEnvironment), conf["ulimitOmc"], conf) From 54cae49044ac060d6833f509d097d98cfd2a0928 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Thu, 20 Aug 2026 16:00:46 +0200 Subject: [PATCH 449/452] For the Rust image: include libpython --- .CI/wasm-jit/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.CI/wasm-jit/Dockerfile b/.CI/wasm-jit/Dockerfile index 2a66dab..30ab938 100644 --- a/.CI/wasm-jit/Dockerfile +++ b/.CI/wasm-jit/Dockerfile @@ -12,7 +12,7 @@ RUN export DEBIAN_FRONTEND=noninteractive \ && add-apt-repository -y ppa:deadsnakes/ppa \ && apt-get install -qy --no-install-recommends openssh-client psmisc rsync time \ && apt-get install -qy --no-install-recommends libcomedi-dev libx11-dev \ - && apt-get install -qy python3.8 python3.12 \ + && apt-get install -qy python3.8 python3.12 libpython3.8-dev libpython3.12-dev \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* From c963e04c04120f397a8af133a4918ad01f47ba44 Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Fri, 21 Aug 2026 15:43:26 +0200 Subject: [PATCH 450/452] Record the machine that produced each library's results (#320) The report's "System info" line was CPU model, RAM and distro, which is identical on ryzen-5950x-1 and ryzen-5950x-2, and nothing anywhere said which node a run came from. job_claim.host is the only place the hostname was written, and that is a live claim table - the next run overwrites it, so the question "which machine produced this result" was unanswerable a day later. Put the hostname in front of the report's system info, and store the hostname and the whole system info string in [libversion], which is already keyed (date, branch, libname) - one row per library per run, which is the right granularity now that libraries of the same branch can be claimed by different machines. Both schema changes are ADD COLUMN only: the rows already in the databases keep their results and read back NULL for a run whose machine was never recorded. sqlite migrates on user_version 3 -> 4 (and from 1 and 2, which also had to gain the columns); PostgreSQL uses ADD COLUMN IF NOT EXISTS, since the shared database is created once and never migrated. Verified on a copy of both: the existing rows survive, the new insert shape works, re-running createTables is a no-op, and the NATURAL JOIN in test.py is unaffected - the added names collide with nothing in omcversion or in a branch table. sqlite2postgres.py learns the two columns as well, and now fills a text column the source lacks with NULL instead of the string "0". What made this worth doing: ExternalMedia and Buildings' Utilities.IO.Python_3_8 models have been flipping in exact anti-phase on master since 2026-08-11, ten run pairs out of ten. It turned out that ExternalMedia does not load on the Ubuntu 22.04 node and the Buildings Python library does not load on the Ubuntu 24.04 nodes, so master alternating between two machines is the whole of it - but establishing that took cross-referencing a transient claim table against report timestamps, which is exactly the work this commit makes unnecessary. See OpenModelica/OpenModelica#16376. --- resultsdb.py | 31 ++++++++++++++++++++++++++----- sqlite2postgres.py | 11 ++++++++--- test.py | 42 ++++++++++++++++++++++-------------------- 3 files changed, 56 insertions(+), 28 deletions(-) diff --git a/resultsdb.py b/resultsdb.py index 81bc764..e709038 100644 --- a/resultsdb.py +++ b/resultsdb.py @@ -229,14 +229,19 @@ def createTables(self, branch): if user_version == 0: # Table to lookup from a run (date, branch) to omcversion used cursor.execute("CREATE TABLE if not exists [omcversion] (date integer NOT NULL, branch text NOT NULL, omcversion text NOT NULL)") - # Table to lookup from a run (date, branch) which library versions were used - cursor.execute("CREATE TABLE if not exists [libversion] (date integer NOT NULL, branch text NOT NULL, libname text NOT NULL, libversion text NOT NULL, confighash integer NOT NULL)") + # Table to lookup from a run (date, branch) which library versions were used, + # and the machine that produced them + cursor.execute("CREATE TABLE if not exists [libversion] (date integer NOT NULL, branch text NOT NULL, libname text NOT NULL, libversion text NOT NULL, confighash integer NOT NULL, host text, sysinfo text)") elif user_version == 1: cursor.execute("ALTER TABLE [libversion] ADD COLUMN confighash integer NOT NULL DEFAULT(0)") + self.addLibversionHost(cursor) elif user_version == 2: for tbl in [t for t in self.tables() if t not in ["libversion", "omcversion"]]: cursor.execute("ALTER TABLE [%s] ADD COLUMN parsing real NOT NULL DEFAULT(0.0)" % tbl) - elif user_version != 3: + self.addLibversionHost(cursor) + elif user_version == 3: + self.addLibversionHost(cursor) + elif user_version != 4: raise SystemExit("Unknown schema user_version=%d" % user_version) cols = ", ".join("%s %s NOT NULL" % (c, SQLITE_TYPES[t]) for c, t in BRANCH_COLUMNS) @@ -245,7 +250,18 @@ def createTables(self, branch): cursor.execute("DROP INDEX IF EXISTS [idx_%s_date]" % branch) cursor.execute("DROP INDEX IF EXISTS idx_omcversion_date") cursor.execute("DROP INDEX IF EXISTS idx_libversion_date") - self.setUserVersion(3) + self.setUserVersion(4) + + def addLibversionHost(self, cursor): + """Add the host columns to an existing [libversion]. + + ADD COLUMN only, so the rows already there keep their results and simply + read back NULL for a run whose machine was never recorded. + """ + have = set(r[1] for r in cursor.execute("PRAGMA table_info([libversion])")) + for col in ["host", "sysinfo"]: + if col not in have: + cursor.execute("ALTER TABLE [libversion] ADD COLUMN %s text" % col) def tables(self): return [t for (t,) in self.conn.execute("SELECT name FROM sqlite_master WHERE type='table'")] @@ -399,7 +415,12 @@ def createTables(self, branch): date bigint NOT NULL, branch text NOT NULL, omcversion text)""") cursor.execute("""CREATE TABLE IF NOT EXISTS libversion ( date bigint NOT NULL, branch text NOT NULL, libname text NOT NULL, - libversion text, confighash bigint NOT NULL)""") + libversion text, confighash bigint NOT NULL, + host text, sysinfo text)""") + # The shared database predates the host columns; add them without touching + # the rows already in there, which keep their results and read back NULL. + for col in ["host", "sysinfo"]: + cursor.execute("ALTER TABLE libversion ADD COLUMN IF NOT EXISTS %s text" % col) cols = ", ".join("%s %s%s" % (c, POSTGRES_TYPES[t], " NOT NULL" if c in BRANCH_KEY else "") for c, t in BRANCH_COLUMNS) cursor.execute("CREATE TABLE IF NOT EXISTS %s (%s)" % (self.quote(branch), cols)) diff --git a/sqlite2postgres.py b/sqlite2postgres.py index 850d445..af49bb9 100644 --- a/sqlite2postgres.py +++ b/sqlite2postgres.py @@ -69,7 +69,8 @@ LOOKUP_COLUMNS = { "omcversion": [("date", "bigint"), ("branch", "text"), ("omcversion", "text")], "libversion": [("date", "bigint"), ("branch", "text"), ("libname", "text"), - ("libversion", "text"), ("confighash", "bigint")], + ("libversion", "text"), ("confighash", "bigint"), + ("host", "text"), ("sysinfo", "text")], } # Derived data, no longer generated by all-plots.py; not worth migrating. @@ -233,8 +234,12 @@ def migrate_table(pg, sconn, source, tbl, columns, batch, quiet, skip_existing=F names = [c for c, _ in columns] have = sqlite_columns(sconn, tbl) missing = [c for c in names if c not in have] - # Older databases lack "parsing"; test.py defaults it to 0.0 as well. - select = ",".join(ident(c) if c in have else "0" for c in names) + # Older databases lack "parsing", and ones older still lack the libversion + # host columns. test.py defaults the numbers to 0; a text column a run never + # recorded is NULL, not the string "0". + types = dict(columns) + select = ",".join(ident(c) if c in have else ("NULL" if types[c] == "text" else "0") + for c in names) create_table(pg, tbl, columns) last_rowid, rows_read, done = read_progress(pg, source, tbl) diff --git a/test.py b/test.py index 4b61852..8351f66 100755 --- a/test.py +++ b/test.py @@ -12,6 +12,7 @@ from joblib import Parallel, delayed import simplejson as json import psutil, subprocess, threading, hashlib +import socket from subprocess import call from monotonic import monotonic from omcommon import friendlyStr, multiple_replace @@ -993,6 +994,26 @@ def resultValues(model, libname, data, simulator=None): data.get("parsing") or 0.0 ) +def cpu_name(): + if isWin: + return processor() + else: + for line in open("/proc/cpuinfo").readlines(): + if "model name" in line.strip(): + return (re.sub( ".*model name.*:", "", line, count=1)).strip() + +if isWin: + lsb_release = "" +else: + try: + lsb_release = check_output_log(commands + ["cat","/etc/lsb-release"]).decode().strip() + lsb_release = dict(a.split("=") for a in lsb_release.split("\n"))["DISTRIB_DESCRIPTION"].strip('"') + except: + lsb_release = "" + +hostname = socket.gethostname() +sysInfo = "%s: %s, %d GB RAM, %s%s" % (hostname, cpu_name(), int(math.ceil(psutil.virtual_memory().total / (1024.0**3))), ("Docker " + docker + " ") if docker else "", lsb_release) + for (resultBranch, simulator) in resultBranches: db.createTables(resultBranch) for key in stats.keys(): @@ -1003,7 +1024,7 @@ def resultValues(model, libname, data, simulator=None): resultValues(model, libname, data, simulator)) for libname in stats_by_libname.keys(): confighash = stats_by_libname[libname]["conf"]["confighash"] - cursor.execute("INSERT INTO libversion VALUES (?,?,?,?,?)%s" % db.insertIgnore(), (testRunStartTimeAsEpoch, resultBranch, libname, stats_by_libname[libname]["conf"]["libraryLastChange"], confighash)) + cursor.execute("INSERT INTO libversion VALUES (?,?,?,?,?,?,?)%s" % db.insertIgnore(), (testRunStartTimeAsEpoch, resultBranch, libname, stats_by_libname[libname]["conf"]["libraryLastChange"], confighash, hostname, sysInfo)) cursor.execute("INSERT INTO omcversion VALUES (?,?,?)%s" % db.insertIgnore(), (testRunStartTimeAsEpoch, resultBranch, omc_version)) """ # Not really a good thing to do; was just done to make generation of the report simpler @@ -1028,25 +1049,6 @@ def checkPhase(phase, n): def is_non_zero_file(fpath): return os.path.isfile(os.path.normpath(fpath)) and os.path.getsize(os.path.normpath(fpath)) > 0 -def cpu_name(): - if isWin: - return processor() - else: - for line in open("/proc/cpuinfo").readlines(): - if "model name" in line.strip(): - return (re.sub( ".*model name.*:", "", line, count=1)).strip() - -if isWin: - lsb_release = "" -else: - try: - lsb_release = check_output_log(commands + ["cat","/etc/lsb-release"]).decode().strip() - lsb_release = dict(a.split("=") for a in lsb_release.split("\n"))["DISTRIB_DESCRIPTION"].strip('"') - except: - lsb_release = "" - -sysInfo = "%s, %d GB RAM, %s%s" % (cpu_name(), int(math.ceil(psutil.virtual_memory().total / (1024.0**3))), ("Docker " + docker + " ") if docker else "", lsb_release) - # create target dir to move results without sync operations (win or when --noSync is used) def stageRootFor(simulator, suffix): """The directory a branch is published from. From 921bba4d501fa40d613830626c60a19f93a0607a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Fri, 21 Aug 2026 15:55:55 +0200 Subject: [PATCH 451/452] Workaround for older Buildings versions (#321) Newer clang complains about implicit function declarations --- configs/conf.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/configs/conf.json b/configs/conf.json index 315cea0..0999e8c 100644 --- a/configs/conf.json +++ b/configs/conf.json @@ -178,7 +178,8 @@ "runOnceBeforeTesting":[["$resourceLocation/src/ThermalZones/install.py", "--binaries-for-os-only"]], "referenceFileExtension":"csv", "referenceFileNameDelimiter":"_", - "referenceFiles":"/mnt/ReferenceFiles/Buildings/csv/maint_11.x" + "referenceFiles":"/mnt/ReferenceFiles/Buildings/csv/maint_11.x", + "extraCustomCommands":["setCFlags(getCFlags() + \" -Wno-error=implicit-function-declaration\")"] }, { "library":"Buildings", @@ -190,7 +191,8 @@ "runOnceBeforeTesting":[["$resourceLocation/src/ThermalZones/install.py", "--binaries-for-os-only"]], "referenceFileExtension":"csv", "referenceFileNameDelimiter":"_", - "referenceFiles":"/mnt/ReferenceFiles/Buildings/csv/maint_12.x" + "referenceFiles":"/mnt/ReferenceFiles/Buildings/csv/maint_12.x", + "extraCustomCommands":["setCFlags(getCFlags() + \" -Wno-error=implicit-function-declaration\")"] }, { "library":"Buildings", From 07e531b2fe23b35b988c7ce7fad489465b81606f Mon Sep 17 00:00:00 2001 From: Adrian Pop Date: Mon, 24 Aug 2026 16:07:02 +0200 Subject: [PATCH 452/452] Run the library testing on a pull request (#307) The library testing runs against a branch and says what broke after a change was merged. This tests a pull request before that, and compares it against master. The compiler is built from refs/pull//merge - the pull request as it would land, not the branch on its own - fetched from GitHub itself, since refs/pull/* is not on the read-only mirror the job clones. It is checked out detached, so nothing is left in the shared workspace for the next run to trip over. The run fills a pr- table like any other branch, which the shared database of #295 makes cheap: the claim is (branch, libname), so it cannot collide with a master run, and the results carry their own omcversion, so nothing else can reuse them by mistake. What did not exist is the comparison. all-reports.py reports a branch against its own previous run, which is exactly what a pull request must not do, and its query reads one table. pr-report.py takes the newest run of pr- and the newest run of the baseline branch and compares them with the same rule and the same thresholds: the phase each model reached, and what each phase cost. Per library it compares the newest run each side has of it, because a run does not necessarily hold every library - one whose version, compiler and configuration were tested before keeps the results of the run that produced them. It writes the report next to the nightly ones, in history/pr-/...html, and a summary to comment on the pull request with beside it. Two things would make a difference mean something other than "the pull request did this", and the report says so when they apply: - the machine, since two runs produced on different hardware compare the hardware as much as the change. The parameter defaults to the node that produces the master runs, and the report names both machines, which #320 records per library; - the libraries, since two runs that tested different library versions, or verified against different reference files, differ for reasons of their own. The models one run has and the other does not are counted and listed rather than quietly left out of the comparison, since a library that failed to load looks like nothing at all otherwise. In Jenkins it is the pull_request parameter, with pull_request_baseline, pull_request_config and pull_request_node beside it. A full run takes days, so this is on demand and takes a configuration file: testing every pull request is not the idea. The tables accumulate, roughly 19500 rows each, and unlike a branch a pull request is tested once and never again. drop-pr-tables.py drops the tables of pull requests that have been merged or closed, and of those tested more than --older-than days ago, together with the rows their runs left in the other tables; it lists them and does nothing unless it is given --yes. The reports published for them are not touched. It is the drop_stale_pull_request_tables parameter in Jenkins, and the same stage keeps the per-pull-request omc builds on the test node from piling up. --- Generated by Claude Code. --- .CI/Jenkinsfile | 105 +++++++++++++- README.md | 52 +++++++ drop-pr-tables.py | 97 +++++++++++++ pr-report.py | 346 ++++++++++++++++++++++++++++++++++++++++++++++ pr.html.tpl | 64 +++++++++ resultsdb.py | 12 ++ 6 files changed, 675 insertions(+), 1 deletion(-) create mode 100755 drop-pr-tables.py create mode 100755 pr-report.py create mode 100644 pr.html.tpl diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index c12abc4..21ebae7 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -37,6 +37,12 @@ pipeline { booleanParam(name: 'generateSymbolicJacobian', defaultValue: false, description: 'master branch, with --generateSymbolicJacobian (ryzen-5950x-1). This is an experimental job that does not run on a fixed schedule.') booleanParam(name: 'wasm_jit', defaultValue: false, description: 'master branch, with --simCodeTarget=wasm-jit (ryzen-5950x-2). This is an experimental job that does not run on a fixed schedule.') booleanParam(name: 'heavy_tests', defaultValue: false, description: 'master branch, runs one test at a time. That is, no parallel launching of tests. omc will use multiple threads for each test (-n=1 is not set unlike the other regression tests.), (ryzen-5950x-1). This is an experimental job that does not run on a fixed schedule.') + + string(name: 'pull_request', defaultValue: '', description: 'Test an OpenModelica pull request rather than a branch: its number, e.g. 16354. omc is built from refs/pull//merge - the pull request as it would land - the results fill a pr- table, and the report compares them against the newest run of pull_request_baseline. Left empty, nothing of this runs.') + string(name: 'pull_request_baseline', defaultValue: 'master', description: 'The branch a pull request is compared against. Its newest run has to come from pull_request_node, or the report compares the machines as much as the pull request.') + string(name: 'pull_request_config', defaultValue: 'configs/conf.json', description: 'What a pull request run tests. A full run takes days, so a smaller configuration file is often the better question to ask.') + choice(name: 'pull_request_node', choices: ['ryzen-5950x-1', 'ryzen-5950x-2-1', 'ryzen-9950x'], description: 'The machine a pull request runs on. The default is the one that produces the master runs it is compared against.') + booleanParam(name: 'drop_stale_pull_request_tables', defaultValue: false, description: 'Drop the pr- tables of pull requests that have been merged or closed, and of those tested more than 60 days ago. The reports published for them are not touched.') } environment { LC_ALL = 'C.UTF-8' @@ -115,6 +121,31 @@ pipeline { } } + stage('pull request') { + agent { + node { + label "${params.pull_request_node}" + customWorkspace 'ws/OpenModelicaLibraryTestingWork' + } + } + options { skipDefaultCheckout() } + when { + beforeAgent true + expression { params.pull_request.trim() } + } + steps { + script { + if (!(params.pull_request.trim() ==~ /[0-9]+/)) { + error "pull_request is a pull request number; got '${params.pull_request}'" + } + } + // One build of omc per pull request is kept, as for a branch, and they + // accumulate: a pull request is tested once and never again. + sh 'find "$HOME/saved_omc" -maxdepth 1 -name "pr-*" -type d -mtime +14 -exec rm -rf {} ";" || true' + runRegressiontest("pr-${params.pull_request.trim()}", "pr-${params.pull_request.trim()}", '', '', false, '', '', false, false, 0, params.pull_request_config) + } + } + stage('newInst-newBackend') { agent { node { @@ -549,6 +580,61 @@ pipeline { sshPublisher(publishers: [sshPublisherDesc(configName: 'LibraryTestingReports', transfers: [sshTransfer(sourceFiles: 'overview*.html,history/**')])]) } } + + stage('drop stale pull request tables') { + agent { + dockerfile { + label 'linux' + dir '.CI/build-dep' + customWorkspace 'ws/OpenModelicaLibraryTestingReport' + } + } + when { + beforeAgent true + expression { params.drop_stale_pull_request_tables } + } + environment { + PGPASSFILE = credentials('omdb-pgpass') + } + steps { + sh './drop-pr-tables.py --yes' + } + } + + /* A pull request is not reported on by the stage above: that one compares a + * branch against its own previous run, which a pull request has none of, and + * regenerating every overview for a job that tested one thing would take + * longer than the report itself. */ + stage('pull request report') { + agent { + dockerfile { + label 'linux' + dir '.CI/build-dep' + customWorkspace 'ws/OpenModelicaLibraryTestingReport' + } + } + when { + beforeAgent true + expression { params.pull_request.trim() } + } + environment { + PYTHONIOENCODING = 'utf-8' + PGPASSFILE = credentials('omdb-pgpass') + } + steps { + script { + if (!(params.pull_request.trim() ==~ /[0-9]+/)) { + error "pull_request is a pull request number; got '${params.pull_request}'" + } + } + sh 'rm -rf history' + sh "./pr-report.py '${params.pull_request.trim()}' --baseline='${params.pull_request_baseline.trim()}'" + // The summary to comment on the pull request with, in the build log + // until there is a token to post it with. + sh 'cat history/pr-*/00_comment.md' + sshPublisher(publishers: [sshPublisherDesc(configName: 'LibraryTestingReports', transfers: [sshTransfer(sourceFiles: 'history/**')])]) + } + } } } def omsimulatorHash() { @@ -808,6 +894,23 @@ def runRegressiontest(branch, name, extraFlags, omsHash, omcompiler, extrasimfla } } + // A pull request is fetched from GitHub itself: refs/pull/* is not on the + // read-only mirror the rest of the job clones. The merge ref rather than the + // head one, since the question is what happens once it is merged, and it is + // checked out detached so that nothing is left behind for the next run of the + // same workspace to trip over. + def pullRequest = branch.startsWith('pr-') && branch.substring(3).isInteger() ? branch.substring(3) : '' + def checkoutRef = pullRequest ? """ + if ! git fetch --force https://github.com/OpenModelica/OpenModelica.git refs/pull/${pullRequest}/merge; then + echo "Could not fetch refs/pull/${pullRequest}/merge: either there is no such pull request, or GitHub cannot merge it into its base branch." + exit 1 + fi + git checkout -f --detach FETCH_HEAD || exit 1 + git fetch --tags --force || exit 1 +""" : """ + git reset --hard && git checkout -f "${branch}" && (git rev-parse --verify "tags/${branch}" || (git reset --hard "origin/${branch}" && git pull)) && git fetch --tags --force || exit 1 +""" + OMCPATH = "${omcompiler ? '../' : './'}OMCompiler" // The build runs in OMCompiler, one level below the cmake source tree. @@ -883,7 +986,7 @@ def runRegressiontest(branch, name, extraFlags, omsHash, omcompiler, extrasimfla cd ${OMCPATH} if ! test -f ~/saved_omc/${name}/.nogit; then - git reset --hard && git checkout -f "${branch}" && (git rev-parse --verify "tags/${branch}" || (git reset --hard "origin/${branch}" && git pull)) && git fetch --tags --force || exit 1 + ${checkoutRef} git submodule update --init --recursive --force || (rm -rf * && git reset --hard && git submodule update --init --recursive --force) || exit 1 git submodule foreach --recursive "git fetch --tags --force && git reset --hard && git clean -fdxq -e /git -e /svn" || exit 1 git clean -fdxq || exit 1 diff --git a/README.md b/README.md index 51faab0..7bc562f 100644 --- a/README.md +++ b/README.md @@ -255,6 +255,58 @@ A tool that is a Python package rather than a command line needs a small driver script that takes the arguments its entry passes, simulates, writes the result file and exits non-zero when it fails; the entry then points `command` at it. +### Testing a pull request + +A branch is tested against its own previous run, which says what broke *after* a +change was merged. A pull request can be tested before that, against the newest +run of `master`. + +In Jenkins, set the **`pull_request`** parameter to the pull request number and +start the job; `pull_request_baseline`, `pull_request_config` and +`pull_request_node` say what it is compared against, what it tests and where. +None of the branch jobs run unless their own parameter is ticked as well. + +By hand it is two steps. The compiler is built from the merge ref - the pull +request as it would land, not the branch on its own - and the run fills a +`pr-` table like any other branch: + +```bash +git fetch --force https://github.com/OpenModelica/OpenModelica.git refs/pull//merge +git checkout -f --detach FETCH_HEAD +# build omc, then +./test.py --branch=pr- configs/conf.json +``` + +and the report compares that run against the newest run of `master`: + +```bash +./pr-report.py # --baseline=master by default +``` + +It writes `history/pr-/...html`, the same +kind of page as the nightly regression reports, next to `00_comment.md`, a +summary to comment on the pull request with. Both are published with the other +reports. + +Two things make a difference mean something other than "the pull request did +this", and the report says so when they apply: **the machine**, since two runs +produced on different hardware compare the hardware as much as the change, and +**the libraries**, since two runs that tested different library versions, or +verified against different reference files, differ for reasons of their own. The +baseline is also the newest `master` run rather than the commit the pull request +is based on, so a difference can come from anything merged since it was +branched - a reason to rebase before believing a surprising result. + +A full run takes days, so testing every pull request this way is not the idea; +point `--branch=pr-` at a smaller configuration file when the question is +narrower. + +The tables accumulate, about 19500 rows each. `drop-pr-tables.py` drops the ones +whose pull request has been merged or closed, and those tested more than +`--older-than` days ago, together with the rows their runs left in the other +tables; it lists them and does nothing unless it is given `--yes`. The reports +published for them are not touched. + ### Generate HTML results ```bash diff --git a/drop-pr-tables.py b/drop-pr-tables.py new file mode 100755 index 0000000..73e7c8d --- /dev/null +++ b/drop-pr-tables.py @@ -0,0 +1,97 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +"""Drop the result tables of pull requests that have been dealt with. + +Testing a pull request fills a pr- table like any other branch, about 19500 +rows and a few megabytes, and unlike a branch it is never written to again once +the pull request is merged or closed. This drops those tables, and the rows the +runs left in the other tables, for pull requests that are no longer open or that +were tested long enough ago not to matter. + +Nothing is dropped without --yes; without it the tables are only listed. +""" + +import argparse, datetime, json, os, re, time, urllib.error, urllib.request +import resultsdb + +parser = argparse.ArgumentParser(description='OpenModelica library testing pull request cleanup') +parser.add_argument('--repo', default="OpenModelica/OpenModelica", help='the repository the pull requests belong to') +parser.add_argument('--older-than', type=int, default=60, metavar='DAYS', + help='also drop a pull request still open whose newest run is older than this (0: never)') +parser.add_argument('--yes', action='store_true', help='actually drop them') +resultsdb.addArgument(parser) +args = parser.parse_args() + +prTableRe = re.compile(r"^pr-([0-9]+)$") + +db = resultsdb.connect(args.db) +cursor = db.cursor() + + +def pullRequestState(number): + """"open", "closed", "merged", or why we could not tell.""" + url = "https://api.github.com/repos/%s/pulls/%s" % (args.repo, number) + request = urllib.request.Request(url, headers={"Accept": "application/vnd.github+json"}) + # The rate limit is 60 requests an hour without one, which is enough for the + # handful of tables this looks at, but a token raises it and costs nothing. + token = os.environ.get("GITHUB_TOKEN") + if token: + request.add_header("Authorization", "Bearer %s" % token) + try: + pr = json.loads(urllib.request.urlopen(request).read().decode("utf-8")) + except urllib.error.HTTPError as e: + return "no answer from GitHub (%s)" % e + except Exception as e: + return "no answer from GitHub (%s)" % e + if pr.get("merged_at"): + return "merged" + return pr.get("state") or "unknown" + + +def newestRun(table): + (date,) = cursor.execute("SELECT max(date) FROM %s" % db.quote(table)).fetchone() + return date + + +def drop(table, branch): + """The table of a run, and everything the run wrote about itself elsewhere.""" + cursor.execute("DROP TABLE %s" % db.quote(table)) + for other in ["omcversion", "libversion", "history", "job_claim"]: + if db.tableExists(other): + cursor.execute("DELETE FROM %s WHERE branch=?" % db.quote(other), (branch,)) + db.commit() + + +tables = sorted((t for t in db.tables() if prTableRe.match(t)), + key=lambda t: int(prTableRe.match(t).group(1))) +if not tables: + raise SystemExit("No pull request tables in this database") + +dropping = [] +for table in tables: + number = prTableRe.match(table).group(1) + date = newestRun(table) + age = (time.time() - date) / 86400.0 if date else 0 + state = pullRequestState(number) + stale = args.older_than and date and age > args.older_than + why = None + if state in ("merged", "closed"): + why = "%s, tested %d days ago" % (state, age) + elif stale: + why = "still %s, but tested %d days ago" % (state, age) + print("%-12s %-8s %s%s" % (table, state, + "last run %s" % datetime.datetime.fromtimestamp(date) if date else "no runs", + ", dropping: %s" % why if why else "")) + if why: + dropping.append((table, why)) + +if not dropping: + raise SystemExit(0) +if not args.yes: + print("\n%d tables would be dropped; pass --yes to drop them" % len(dropping)) + raise SystemExit(0) +for (table, why) in dropping: + print("Dropping %s (%s)" % (table, why)) + drop(table, table) +print("The reports and files published for them are not touched; they are on the web server.") diff --git a/pr-report.py b/pr-report.py new file mode 100755 index 0000000..b6abd57 --- /dev/null +++ b/pr-report.py @@ -0,0 +1,346 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +"""Compare a pull request run against a run of another branch. + +all-reports.py reports a branch against its own previous run, which is what a +pull request must not do: pr- has no previous run, and the question is not +"what changed since yesterday" but "what does this pull request change against +master". The comparison itself is the same one - the phase a model reached and +what each phase cost - only the two runs it is given come from two branches. +""" + +import argparse, codecs, datetime, html, os, re, time +import shared, resultsdb +from omcommon import friendlyStr, multiple_replace + +parser = argparse.ArgumentParser(description='OpenModelica library testing pull request report') +parser.add_argument('pullrequest', help='the pull request number, or its branch name pr-') +parser.add_argument('--baseline', default="master", help='the branch the pull request is compared against') +parser.add_argument('--date', type=int, default=0, help='the pull request run to report on (default: its newest)') +parser.add_argument('--baselinedate', type=int, default=0, help='the baseline run to compare against (default: its newest)') +parser.add_argument('--baseurl', default="http://libraries.openmodelica.org/branches") +parser.add_argument('--historyurl', default="http://libraries.openmodelica.org/branches/history") +parser.add_argument('--historypath', default="history") +parser.add_argument('--githuburl', default="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/OpenModelica/OpenModelica") +parser.add_argument('--markdown', default="", help='where to write the summary to comment on the pull request with (default: //00_comment.md)') +resultsdb.addArgument(parser) +args = parser.parse_args() + +os.environ['TZ'] = 'Europe/Stockholm' +time.tzset() + +# The same thresholds all-reports.py uses, so that a change reported here means +# what it means in the nightly reports. +timeMinPhase = 4 # Need to have completed code generation to report performance regressions +timeRel = 1.7 # Minimum 1.7x time is registered as a performance regression +timeAbs = 10 # Ignore performance regressions for times <10s... + +PHASES = [(1,"frontend"),(2,"backend"),(3,"simcode"),(4,"templates"),(5,"compile"),(6,"simulate")] + +m = re.match(r"^(?:pr-)?([0-9]+)$", args.pullrequest.strip()) +if not m: + raise SystemExit("Expected a pull request number or a pr- branch name, got '%s'" % args.pullrequest) +pr = m.group(1) +branch = "pr-%s" % pr +baseline = args.baseline.split("/")[-1] +prurl = "%s/pull/%s" % (args.githuburl, pr) + +db = resultsdb.connect(args.db) +cursor = db.cursor() + +for tbl in [branch, baseline]: + if not db.tableExists(tbl): + raise SystemExit("No results for '%s'; run test.py --branch=%s first" % (tbl, tbl)) + db.createDateIndex(tbl) + + +def dateStr(dint): + return str(datetime.datetime.fromtimestamp(dint).strftime('%Y-%m-%d %H:%M:%S')) + +def newestRun(table, upto=0): + """The newest run of a table, or the newest at or before upto.""" + if upto: + (d,) = cursor.execute("SELECT max(date) FROM %s WHERE date<=?" % db.quote(table), (upto,)).fetchone() + else: + (d,) = cursor.execute("SELECT max(date) FROM %s" % db.quote(table)).fetchone() + return d + +def libraries(table, upto): + return set(l for (l,) in cursor.execute( + "SELECT DISTINCT libname FROM %s WHERE date<=?" % db.quote(table), (upto,))) + +def libraryRun(table, libname, upto): + """The newest run of one library at or before upto. + + A run does not necessarily hold every library: test.py skips a library whose + version, compiler and configuration were tested before, so its results stay at + the date of the run that produced them. Comparing two runs therefore means + comparing, per library, the newest run each of them has of it. + """ + (d,) = cursor.execute("SELECT max(date) FROM %s WHERE date<=? AND libname=?" + % db.quote(table), (upto, libname)).fetchone() + return d + +# A database written before the machine was recorded, #320, has no host column. +hostColumn = "host" if "host" in db.columns("libversion") else "NULL" + +def libraryVersions(table, libname, date): + """(libversion, confighash, host) of a library in a run.""" + row = cursor.execute( + "SELECT libversion,confighash,%s FROM libversion WHERE %s AND date=? AND libname=?" + % (hostColumn, db.likeNoCase("branch")), (table, date, libname)).fetchone() + return row if row else (None, None, None) + +def omcVersion(table, date): + row = cursor.execute("SELECT omcversion FROM omcversion WHERE %s AND date=?" + % db.likeNoCase("branch"), (table, date)).fetchone() + return row[0].strip() if row and row[0] else "unknown" + +def models(table, libname, date): + return set(mod for (mod,) in cursor.execute( + "SELECT model FROM %s WHERE date=? AND libname=?" % db.quote(table), (date, libname))) + +def changedModels(table1, date1, table2, date2, libnames): + """The models whose phase or timings differ between the two runs. + + One query per set of libraries that share a pair of dates, as all-reports.py + does. The values of both runs are aggregated into one string per column, + ordered by which run they come from rather than by their date: a pull request + run is normally the newer of the two, but need not be. + """ + concat = ",".join(db.groupConcat(c, "ord") for c in + ["finalphase","frontend","backend","simcode","templates","compile","simulate"]) + cols = "model,libname,finalphase,frontend,backend,simcode,templates,compile,simulate" + inlibs = ",".join("'%s'" % libname for libname in sorted(libnames)) + query = """SELECT model,libname,%s FROM + (SELECT * FROM + (SELECT %s,0 AS ord FROM %s WHERE date=? AND libname IN (%s) + UNION ALL + SELECT %s,1 AS ord FROM %s WHERE date=? AND libname IN (%s)) AS runs + ORDER BY ord) AS phases + GROUP BY model,libname HAVING + (MIN(finalphase) <> MAX(finalphase)) OR + (MIN(finalphase) >= ? AND ( + (MAX(frontend) > ?*MIN(frontend) AND MAX(frontend) > ?) OR + (MAX(backend) > ?*MIN(backend) AND MAX(backend) > ?) OR + (MAX(simcode) > ?*MIN(simcode) AND MAX(simcode) > ?) OR + (MAX(templates) > ?*MIN(templates) AND MAX(templates) > ?) OR + (MAX(compile) > ?*MIN(compile) AND MAX(compile) > ?) OR + (MAX(simulate) > ?*MIN(simulate) AND MAX(simulate) > ?))) + """ % (concat, cols, db.quote(table1), inlibs, cols, db.quote(table2), inlibs) + cursor.execute(query, (date1, date2, timeMinPhase, + timeRel, timeAbs, timeRel, timeAbs, timeRel, timeAbs, + timeRel, timeAbs, timeRel, 2*timeAbs, timeRel, timeAbs)) + return cursor.fetchall() + + +prdate = newestRun(branch, args.date) +if not prdate: + raise SystemExit("No results for %s%s" % (branch, " at or before %d" % args.date if args.date else "")) +basedate = newestRun(baseline, args.baselinedate) +if not basedate: + raise SystemExit("No results for %s%s" % (baseline, " at or before %d" % args.baselinedate if args.baselinedate else "")) + +prlibs = libraries(branch, prdate) +baselibs = libraries(baseline, basedate) +libnames = sorted(prlibs & baselibs) +if not libnames: + raise SystemExit("%s and %s have no library in common" % (branch, baseline)) + +# Per library the newest run each side has of it, grouped by the pair of dates +# so that one query covers every library that shares it. +groups = {} +prlibdates = {} +baselibdates = {} +for libname in libnames: + d1 = libraryRun(baseline, libname, basedate) + d2 = libraryRun(branch, libname, prdate) + baselibdates[libname] = d1 + prlibdates[libname] = d2 + groups.setdefault((d1, d2), []).append(libname) + +changes = [] +for ((d1, d2), libs) in sorted(groups.items()): + changes += changedModels(baseline, d1, branch, d2, libs) +changes = sorted(changes, key=lambda x: (x[1], x[0])) + +# Models one of the runs has and the other does not: a library that grew a model, +# or one whose test did not run at all. They cannot be compared, but leaving them +# out of the report without saying so would hide a library that failed to load. +onlyPr = [] +onlyBaseline = [] +numCompared = 0 +for libname in libnames: + inpr = models(branch, libname, prlibdates[libname]) + inbase = models(baseline, libname, baselibdates[libname]) + onlyPr += [(libname, mod) for mod in sorted(inpr - inbase)] + onlyBaseline += [(libname, mod) for mod in sorted(inbase - inpr)] + numCompared += len(inpr & inbase) + + +def modelLink(table, libname, modelname, extension, text): + return '%s' % ( + args.baseurl, table, libname, libname, modelname, extension, html.escape(text)) + +def libraryLink(table, libname): + return '%s' % (args.baseurl, table, libname, libname, html.escape(libname)) + +def classify(group, times): + """(colour, message) for a model, in the terms all-reports.py uses.""" + (phase1, phase2) = [int(i) for i in group.split(",")] + if phase2 != phase1: + better = phase2 > phase1 + return ("better" if better else "warning", + "%s → %s" % (shared.finalphaseName(phase1), shared.finalphaseName(phase2)), + "improved" if better else "regression") + msgs = [] + colour = None + for ((phase, name), values) in zip(PHASES, times): + (t1, t2) = [float(d) for d in values.split(",")] + limit = 2*timeAbs if name == "compile" else timeAbs + if t2 > timeRel*t1 and t2 > limit: + colour = "warningPerformance" + msgs.append("%s performance %s → %s" % (shared.finalphaseName(phase), friendlyStr(t1), friendlyStr(t2))) + elif t1 > timeRel*t2 and t1 > limit: + if colour is None: + colour = "betterPerformance" + msgs.append("%s performance %s → %s" % (shared.finalphaseName(phase), friendlyStr(t1), friendlyStr(t2))) + if colour is None: + # Both runs are below timeMinPhase, or the difference is under the threshold + # in the direction the query did not test for. + return (None, "", None) + return (colour, " ".join(msgs), + "performance improved" if colour == "betterPerformance" else "performance regression") + +counts = {"improved": 0, "regression": 0, "performance improved": 0, "performance regression": 0} +rows = [] +markdownrows = [] +for (model, libname, group, frontend, backend, simcode, templates, compile, simulate) in changes: + (colour, msg, kind) = classify(group, [frontend, backend, simcode, templates, compile, simulate]) + if kind is None: + continue + counts[kind] += 1 + rows.append('' + % (libraryLink(branch, libname), + modelLink(branch, libname, model, "err", model), + modelLink(branch, libname, model, "sim", "(sim)"), + modelLink(baseline, libname, model, "err", "(%s)" % baseline), + colour, msg)) + markdownrows.append((libname, model, msg.replace("→", "->"))) + +# What makes a difference mean something other than "the pull request did this". +caveats = [] +prhosts = set() +basehosts = set() +libchanges = [] +for libname in libnames: + (lv1, lh1, host1) = libraryVersions(baseline, libname, baselibdates[libname]) + (lv2, lh2, host2) = libraryVersions(branch, libname, prlibdates[libname]) + prhosts.add(host2 or "unknown") + basehosts.add(host1 or "unknown") + if (lv1 or "").strip() != (lv2 or "").strip(): + libchanges.append("" + % (libraryLink(branch, libname), html.escape((lv1 or "").strip()), baseline, + html.escape((lv2 or "").strip()), branch)) + elif lh1 != lh2: + libchanges.append("" % libraryLink(branch, libname)) + +if prhosts != basehosts: + caveats.append("The two runs were produced on different machines (%s against %s), so the timings " + "compare the hardware as much as the pull request. The phases a model reaches are " + "still comparable." % (", ".join(sorted(prhosts)), ", ".join(sorted(basehosts)))) +if libchanges: + caveats.append("%d of the %d libraries were not tested in the same version, or not with the same " + "configuration and reference files, in the two runs; see Library Changes below." + % (len(libchanges), len(libnames))) +if prlibs - baselibs: + caveats.append("%d libraries of the pull request run have no counterpart in the baseline run: %s." + % (len(prlibs - baselibs), ", ".join(sorted(prlibs - baselibs)))) +if baselibs - prlibs: + caveats.append("%d libraries of the baseline run were not tested by the pull request run: %s." + % (len(baselibs - prlibs), ", ".join(sorted(baselibs - prlibs)))) +# Always true, and in the report itself rather than among the caveats. +note = ("The baseline is the newest run of %s, not the commit the pull request is based on, so a " + "difference can also come from something merged into %s since the pull request was " + "branched." % (baseline, baseline)) + +reportname = "%s..%s.html" % (dateStr(basedate), dateStr(prdate)) +historydir = os.path.join(args.historypath, branch) +os.makedirs(historydir, exist_ok=True) + +with open("pr.html.tpl") as fin: + tpl = fin.read() +tpl = multiple_replace(tpl, + ("#PRURL#", prurl), + ("#PR#", pr), + ("#BRANCH#", branch), + ("#BASELINE#", html.escape(baseline)), + ("#CAVEATS#", "\n".join('

    %s

    ' % c for c in caveats)), + ("#DATE1#", dateStr(basedate)), + ("#DATE2#", dateStr(prdate)), + ("#OMCVERSION1#", html.escape(omcVersion(baseline, basedate))), + ("#OMCVERSION2#", html.escape(omcVersion(branch, prdate))), + ("#HOST1#", html.escape(", ".join(sorted(basehosts)))), + ("#HOST2#", html.escape(", ".join(sorted(prhosts)))), + ("#NUMCOMPARED#", str(numCompared)), + ("#NUMIMPROVE#", str(counts["improved"])), + ("#NUMREGRESSION#", str(counts["regression"])), + ("#NUMPERFIMPROVE#", str(counts["performance improved"])), + ("#NUMPERFREGRESSION#", str(counts["performance regression"])), + ("#NUMONLYPR#", str(len(onlyPr))), + ("#NUMONLYBASELINE#", str(len(onlyBaseline))), + ("#LIBCHANGES#", "\n".join(libchanges)), + ("#MODELCHANGES#", "\n".join(rows)), + ("#MODELSONLYINONE#", "\n".join( + '' % (html.escape(libname), html.escape(model), where) + for (where, lst) in [("only in %s" % branch, onlyPr), ("only in %s" % baseline, onlyBaseline)] + for (libname, model) in lst)), +) +with codecs.open(os.path.join(historydir, reportname), "w", encoding="utf-8") as fout: + fout.write(tpl) + +# The index the history directory of every branch has, so that the report is +# reachable from the server without knowing its name. +reporturl = "%s/%s/%s" % (args.historyurl, branch, reportname.replace(" ", "%20")) +summary = ("%d improved, %d regressions; performance %d improved, %d regressions" + % (counts["improved"], counts["regression"], + counts["performance improved"], counts["performance regression"])) +indexname = os.path.join(historydir, "00_history.html") +index = [] +if os.path.exists(indexname): + with codecs.open(indexname, "r", encoding="utf-8") as fin: + # A report of the same two runs is one that has just been overwritten, so + # its line in the index is replaced rather than repeated. + index = [line for line in fin.read().splitlines() if line.strip() and reporturl not in line] +entry = '

    %s against %s %s %s

    ' % (reporturl, branch, baseline, reportname, summary) +with codecs.open(indexname, "w", encoding="utf-8") as fout: + fout.write("".join(line + "\n" for line in index + [entry])) + +markdown = ["## Library testing for [#%s](%s) against `%s`" % (pr, prurl, baseline), "", + "| | Branch | Run | Compiler | Machine |", + "| --- | --- | --- | --- | --- |", + "| Baseline | `%s` | %s | %s | %s |" % (baseline, dateStr(basedate), omcVersion(baseline, basedate), ", ".join(sorted(basehosts))), + "| Pull request | `%s` | %s | %s | %s |" % (branch, dateStr(prdate), omcVersion(branch, prdate), ", ".join(sorted(prhosts))), + "", + "%d models compared, **%d improved, %d regressions**, performance %d improved, %d regressions." + % (numCompared, counts["improved"], counts["regression"], + counts["performance improved"], counts["performance regression"]), + "", "[Full report](%s)" % reporturl, ""] +if markdownrows: + markdown += ["
    %d models affected" % len(markdownrows), "", + "| Library | Model | Change |", "| --- | --- | --- |"] + markdown += ["| %s | %s | %s |" % (libname, model, msg) for (libname, model, msg) in markdownrows] + markdown += ["", "
    ", ""] +markdown += ["
    Caveats", ""] +markdown += ["- %s" % c.replace("→", "->") for c in caveats + [note]] +markdown += ["", "
    ", "", "---", "Generated by the OpenModelica library testing"] +markdownname = args.markdown or os.path.join(historydir, "00_comment.md") +with codecs.open(markdownname, "w", encoding="utf-8") as fout: + fout.write("\n".join(markdown) + "\n") + +print("%s: %s" % (branch, summary)) +print("Report: %s" % os.path.join(historydir, reportname)) +print("Comment: %s" % markdownname) +print("Published as %s" % reporturl) diff --git a/pr.html.tpl b/pr.html.tpl new file mode 100644 index 0000000..34a5670 --- /dev/null +++ b/pr.html.tpl @@ -0,0 +1,64 @@ + + + + + OpenModelica pull request #PR# against #BASELINE# + + + +

    OpenModelica pull request #PR# against #BASELINE#

    + +#CAVEATS# +

    The baseline is the newest run of #BASELINE#, not the commit the pull request is +based on, so a difference can also come from something merged into #BASELINE# since +the pull request was branched.

    + +

    The two runs

    + +
    %s%s%s%s%s%s%s%s%s%s
    %s%s%s%s%d
    %s%s %s %s%s
    %sVersion %s in %s, %s in %s
    %sConfiguration hash (OMC settings, the testing script or a " + "reference file changed)
    %s%s%s
    + + + +
    BranchRunCompilerMachine
    Baseline#BASELINE##DATE1##OMCVERSION1##HOST1#
    Pull request#BRANCH##DATE2##OMCVERSION2##HOST2#
    + +

    Summary

    + + + + + + + + + +
    Models compared#NUMCOMPARED#
    Number of Improvements#NUMIMPROVE#
    Number of Regressions#NUMREGRESSION#
    Number of Performance Improvements#NUMPERFIMPROVE#
    Number of Performance Regressions#NUMPERFREGRESSION#
    Models only in the pull request run#NUMONLYPR#
    Models only in the baseline run#NUMONLYBASELINE#
    + +

    Library Changes

    + + +#LIBCHANGES# +
    LibraryChange
    + +

    Models Affected

    + + +#MODELCHANGES# +
    LibraryModelChange
    + +

    Models Only in One of the Runs

    + + +#MODELSONLYINONE# +
    LibraryModelWhere
    + + + diff --git a/resultsdb.py b/resultsdb.py index e709038..92773ab 100644 --- a/resultsdb.py +++ b/resultsdb.py @@ -163,6 +163,10 @@ def claimedBy(self, branch, libname, libversion, omcversion, confighash): def release(self): """Mark the claims of this run as finished.""" + def columns(self, table): + """The columns a table has, for the ones an older database may not have.""" + raise NotImplementedError + def vacuum(self): self.conn.execute("VACUUM") @@ -266,6 +270,9 @@ def addLibversionHost(self, cursor): def tables(self): return [t for (t,) in self.conn.execute("SELECT name FROM sqlite_master WHERE type='table'")] + def columns(self, table): + return [r[1] for r in self.conn.execute("PRAGMA table_info(%s)" % self.quote(table))] + def tableExists(self, name): return self.conn.execute( "SELECT 1 FROM sqlite_master WHERE type='table' AND name=?", (name,)).fetchone() is not None @@ -437,6 +444,11 @@ def tables(self): return [t for (t,) in self.execute( "SELECT tablename FROM pg_tables WHERE schemaname=current_schema()")] + def columns(self, table): + return [c for (c,) in self.execute( + "SELECT column_name FROM information_schema.columns " + "WHERE table_schema=current_schema() AND table_name=?", (table,))] + def tableExists(self, name): return self.execute("SELECT 1 FROM pg_tables WHERE schemaname=current_schema() AND tablename=?", (name,)).fetchone() is not None