diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..46de937 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,27 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/ubuntu +{ + "name": "Ubuntu", + // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile + "image": "mcr.microsoft.com/devcontainers/base:noble", + + // Features to add to the dev container. More info: https://containers.dev/features. + "features": { + "ghcr.io/devcontainers/features/python:1": { + "installTools": true, + "version": "latest" + } + }, + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [], + + // Use 'postCreateCommand' to run commands after the container is created. + "postCreateCommand": "bash .devcontainer/install.sh && omc .devcontainer/install.mos && pip install -r requirements.txt" + + // Configure tool-specific properties. + // "customizations": {}, + + // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. + // "remoteUser": "root" +} diff --git a/.devcontainer/install.mos b/.devcontainer/install.mos new file mode 100644 index 0000000..aa626ee --- /dev/null +++ b/.devcontainer/install.mos @@ -0,0 +1,2 @@ +updatePackageIndex(); getErrorString(); +installPackage(Modelica, version="4.0.0", exactMatch=true); getErrorString(); diff --git a/.devcontainer/install.sh b/.devcontainer/install.sh new file mode 100644 index 0000000..65472c3 --- /dev/null +++ b/.devcontainer/install.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +sudo apt-get update +sudo apt-get install ca-certificates curl gnupg -qy +sudo curl -fsSL http://build.openmodelica.org/apt/openmodelica.asc | \ + sudo gpg --dearmor -o /usr/share/keyrings/openmodelica-keyring.gpg + +echo "deb [arch=amd64 signed-by=/usr/share/keyrings/openmodelica-keyring.gpg] \ + https://build.openmodelica.org/apt \ + noble \ + stable" | sudo tee /etc/apt/sources.list.d/openmodelica.list + +sudo apt update +sudo apt install --no-install-recommends omc -qy diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c6cebe4..5eb8140 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -53,12 +53,14 @@ jobs: - name: Install Python dependencies shell: bash run: | + sed -i '/^juliacall/d' requirements.txt # Remove juliacall to check if it works without pip install -r requirements.txt - name: Run library test shell: bash + env: + MY_SANITY_CHECK_DIRECTORY: sanityCheck run: | - export MY_SANITY_CHECK_DIRECTORY=sanityCheck python test.py --branch="${{ matrix.omc-version }}" --noclean --verbose ${{ matrix.msysEnvironment }} configs/sanityCheck.json - name: Generate HTML results @@ -73,7 +75,7 @@ jobs: - name: Verify that overview.html contains simulation and verification shell: bash run: | - if ! grep -q "${{ matrix.omc-version }}222222222" overview.html; then + if ! grep -q '${{ matrix.omc-version }}222222222' overview.html; then echo "Failed to find 2 simulating and 2 verifying models in overwiew.html:" cat overview.html exit 1 diff --git a/.github/workflows/test_julia.yml b/.github/workflows/test_julia.yml index 9785aa7..7f730b1 100644 --- a/.github/workflows/test_julia.yml +++ b/.github/workflows/test_julia.yml @@ -94,8 +94,9 @@ jobs: - name: Run library test shell: bash + env: + MY_SANITY_CHECK_DIRECTORY: sanityCheck run: | - export MY_SANITY_CHECK_DIRECTORY=sanityCheck python test.py --branch="${{ matrix.omc-version }}" --basemodelica-mtk-import --no-julia-sys-image --noclean --verbose configs/sanityCheck.json - name: Generate HTML results diff --git a/conversionscript.py b/conversionscript.py index e572cf6..59f00b8 100755 --- a/conversionscript.py +++ b/conversionscript.py @@ -1,7 +1,8 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- -from OMPython import OMCSessionZMQ, pyparsing +from OMPython import OMCSessionZMQ +import pyparsing import argparse import glob import json @@ -32,12 +33,12 @@ os.mkdir("converted-libraries/.openmodelica") os.mkdir("converted-libraries/.openmodelica/libraries") -def omcAssert(omc, cmd, extra=""): +def omcAssert(omc: OMCSessionZMQ, cmd: str, extra: str = ""): res = omc.sendExpression(cmd) if not res: raise Exception(cmd + "\n" + extra + "\n" + (omc.sendExpression("getErrorString()") or "")) -def omcSendExpression(omc, cmd, extra=""): +def omcSendExpression(omc: OMCSessionZMQ, cmd: str, extra: str = ""): try: return omc.sendExpression(cmd) except pyparsing.ParseException as e: diff --git a/requirements.txt b/requirements.txt index 7c5e0e0..306e8e7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,6 +4,6 @@ juliacall matplotlib monotonic natsort -ompython==3.6 +OMPython==4.0 psutil simplejson diff --git a/shared.py b/shared.py index 2f9b7a3..f0eeeab 100644 --- a/shared.py +++ b/shared.py @@ -74,6 +74,9 @@ def getReferenceFileName(conf): else: modelName += "."+conf["referenceFileNameExtraName"] referenceFile = conf["referenceFiles"]+"/"+modelName.replace(".",conf["referenceFileNameDelimiter"])+(conf.get("referenceFinalDot") or ".")+conf["referenceFileExtension"] + if os.path.exists(referenceFile): + referenceFile = os.path.abspath(referenceFile) + if not os.path.exists(referenceFile) and not os.path.isdir(referenceFile): if conf.get("allReferenceFilesExist"): raise Exception("Missing reference file %s for config %s" % (referenceFile,conf)) @@ -105,5 +108,3 @@ def isFMPy(fmisimulator): return 'fmpy' in fmisimulator else: return False - - diff --git a/single-model.py b/single-model.py index d72e769..c3cd0aa 100755 --- a/single-model.py +++ b/single-model.py @@ -1,8 +1,7 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- -import sys, argparse -import simplejson as json +import argparse import shared parser = argparse.ArgumentParser(description='OpenModelica model testing report generation tool') @@ -21,8 +20,7 @@ libs = {} -import cgi, sqlite3, time, datetime -from omcommon import friendlyStr, multiple_replace +import sqlite3, datetime conn = sqlite3.connect('sqlite3.db') cursor = conn.cursor() diff --git a/test.py b/test.py index 5ee14df..1e66330 100755 --- a/test.py +++ b/test.py @@ -8,11 +8,10 @@ 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, sqlite3, datetime, math from joblib import Parallel, delayed import simplejson as json import psutil, subprocess, threading, hashlib -from subprocess import call from monotonic import monotonic from omcommon import friendlyStr, multiple_replace from natsort import natsorted @@ -260,14 +259,19 @@ def target(): print("Error: Expected at least one configuration file to start the library test") sys.exit(1) -from OMPython import OMCSession, OMCSessionZMQ +from OMPython import OMCSessionZMQ, OMCProcessDocker # Try to make the processes a bit nicer... os.environ["GC_MARKERS"]="1" print("Start OMC version") -if ompython_omhome != "": +if docker: + omc = OMCProcessDocker(docker=docker, dockerExtraArgs=dockerExtraArgs) + omhome=omc.sendExpression('getInstallationDirectoryPath()') + omc_version=omc.sendExpression('getVersion()') + ompython_omc_version=omc_version +elif ompython_omhome != "": # Use a different OMC for running OMPython than for running the tests omhome = os.environ["OPENMODELICAHOME"] omc_version = check_output_log(omc_cmd + ["--version"], stderr=subprocess.STDOUT).decode("ascii").strip() @@ -276,10 +280,11 @@ def target(): ompython_omc_version=omc.sendExpression('getVersion()') os.environ["OPENMODELICAHOME"] = omhome else: - omc = OMCSessionZMQ(docker=docker, dockerExtraArgs=dockerExtraArgs) + omc = OMCSessionZMQ() omhome=omc.sendExpression('getInstallationDirectoryPath()') omc_version=omc.sendExpression('getVersion()') ompython_omc_version=omc_version + ompython_omc_version=ompython_omc_version.replace("OMCompiler","").strip() def timeSeconds(f): diff --git a/testmodel.py b/testmodel.py index 4d16ba8..e7a0a0b 100755 --- a/testmodel.py +++ b/testmodel.py @@ -2,10 +2,9 @@ # -*- coding: utf-8 -*- import argparse, os, sys, signal, threading, psutil, subprocess, shutil -from asyncio.subprocess import STDOUT import simplejson as json from monotonic import monotonic -from OMPython import FindBestOMCSession, OMCSession, OMCSessionZMQ +from OMPython import OMCSessionZMQ, OMCProcessDocker import shared, glob parser = argparse.ArgumentParser(description='OpenModelica library testing tool helper (single model)') @@ -58,7 +57,7 @@ def writeResult(): startJob=monotonic() -def quit_omc(omc): +def quit_omc(omc: OMCSessionZMQ | None): if omc is None: return omc try: @@ -72,7 +71,7 @@ def quit_omc(omc): omc = None return omc -def writeResultAndExit(exitStatus, useOsExit=False, omc=None, omc_new=None): +def writeResultAndExit(exitStatus: int, useOsExit: bool = False, omc: OMCSessionZMQ | None = None, omc_new: OMCSessionZMQ | None = None): writeResult() print("Calling exit ...") with open(errFile, 'a+') as fp: @@ -90,7 +89,7 @@ def writeResultAndExit(exitStatus, useOsExit=False, omc=None, omc_new=None): else: sys.exit(exitStatus) -def sendExpressionTimeout(omc, cmd, timeout): +def sendExpressionTimeout(omc: OMCSessionZMQ, cmd: str, timeout: int): with open(errFile, 'a+') as fp: fp.write("%s [Timeout %s]\n" % (cmd, timeout)) def target(res): @@ -251,7 +250,11 @@ def target(res): os.environ["OPENMODELICAHOME"] = omhome def createOmcSession(): - return OMCSession(docker=docker, dockerExtraArgs=dockerExtraArgs, timeout=5) if corbaStyle else OMCSessionZMQ(docker=docker, dockerExtraArgs=dockerExtraArgs, timeout=5) + if docker: + return OMCProcessDocker(docker=docker, dockerExtraArgs=dockerExtraArgs, timeout=5) + else: + return OMCSessionZMQ(timeout=5) + def createOmcSessionNew(): if ompython_omhome != "": os.environ["OPENMODELICAHOME"] = ompython_omhome diff --git a/testresults.md b/testresults.md index 56c3056..c1bfa22 100644 --- a/testresults.md +++ b/testresults.md @@ -2,42 +2,76 @@ ## 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) - are handled by released versions of OpenModelica and by the development version on the master branch. Regressions are marked in orange, +- **Overview with library test results across OMC versions**: + These reports shows how libraries with full or partial support level (see + [OMPackageManager, Library support levels](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 + + - [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 ## 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. +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: -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 +- _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 +- _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. +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. +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.