From 6b6908e0c0a04271d3574323e96b60ad0701d14a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Sj=C3=B6lund?= Date: Mon, 5 Oct 2026 09:02:49 +0200 Subject: [PATCH] Test pull requests with wasm-jit by default wasm-jit gives the same results as C and is cheaper to run, so a pull request is now simulated with `--simCodeTarget=wasm-jit` and compared against the wasm-jit job, the way that job runs it. - `pull_request_target` (`wasm-jit` or `C`) picks the target. - `pull_request_baseline` defaults to the job testing that target: `wasm-jit`, or `master` for C. `pr-report.py --baseline` defaults to `wasm-jit` as well. - `pull_request_node` defaults to ryzen-9950x, where both master and wasm-jit run. The cmake flags are now part of the cached omc's stamp, so a C and a wasm-jit build of the same pull request do not reuse each other. The cached wasm-jit, wasm-web and heavy_tests_wasm builds rebuild once. Assisted-by: Claude Opus 5.5 --- .CI/Jenkinsfile | 34 ++++++++++++++++++++++++++-------- README.md | 18 +++++++++++------- pr-report.py | 4 ++-- 3 files changed, 39 insertions(+), 17 deletions(-) diff --git a/.CI/Jenkinsfile b/.CI/Jenkinsfile index 5cce0fa..622e60f 100644 --- a/.CI/Jenkinsfile +++ b/.CI/Jenkinsfile @@ -5,7 +5,7 @@ pipeline { 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, simulated with the solver each model asks for, filling master (ryzen-5950x-1).') + booleanParam(name: 'master', defaultValue: false, description: 'master branch, simulated with the solver each model asks for, filling master (ryzen-9950x).') booleanParam(name: 'fmi_v1_26', defaultValue: false, description: 'maintenance/v1.26 branch with FMI, simulated by OMSimulator, filling v1.26-fmi (ryzen-5950x-2). Ticking it together with fmpy_fmi_v1_26 runs one job that builds every FMU once and simulates it with both.') booleanParam(name: 'fmi_v1_27', defaultValue: false, description: 'maintenance/v1.27 branch with FMI, simulated by OMSimulator, filling v1.27-fmi (ryzen-5950x-2). Ticking it together with fmpy_fmi_v1_27 runs one job that builds every FMU once and simulates it with both.') @@ -41,9 +41,10 @@ pipeline { booleanParam(name: 'heavy_tests_wasm', defaultValue: false, description: 'heavy_tests with --simCodeTarget=wasm-jit, filling heavy_tests_wasm (r7945). Its results are in the heavy_tests report. 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.') + choice(name: 'pull_request_target', choices: ['wasm-jit', 'C'], description: 'The --simCodeTarget a pull request is simulated with. wasm-jit is the cheaper run and is compared against the wasm-jit job; C against master.') + string(name: 'pull_request_baseline', defaultValue: '', description: 'The branch a pull request is compared against. Left empty, the one pull_request_target is tested by: wasm-jit for wasm-jit, master for C. 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.') + choice(name: 'pull_request_node', choices: ['ryzen-9950x', 'ryzen-5950x-1', 'ryzen-5950x-2-1'], description: 'The machine a pull request runs on. The default is the one that produces the master and wasm-jit runs it is compared against.') booleanParam(name: 'pull_request_comment', defaultValue: false, description: 'Post the summary of a pull request run as a comment on the pull request, replacing the one an earlier run posted. Needs an OpenModelica-Hudson credential; without it the report is still written and published, only not commented.') 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.') } @@ -145,7 +146,7 @@ pipeline { stage('pull request') { agent { node { - label "${params.pull_request_node ?: 'ryzen-5950x-1'}" + label "${params.pull_request_node ?: 'ryzen-9950x'}" customWorkspace 'ws/OpenModelicaLibraryTestingWork' } } @@ -176,7 +177,15 @@ pipeline { find "$HOME/saved_omc/pr" -mindepth 1 -maxdepth 1 -type d -mtime +14 -exec rm -rf {} ";" 2> /dev/null || true find "$HOME/saved_omc" -mindepth 1 -maxdepth 1 -name "pr-*" -type d -mtime +14 -exec rm -rf {} ";" || true ''' - runRegressiontest("pr/${pullRequest()}", "pr/${pullRequest()}", '', '', false, '', '', false, false, 0, params.pull_request_config ?: 'configs/conf.json') + script { + def config = params.pull_request_config ?: 'configs/conf.json' + if (pullRequestTarget() == 'C') { + runRegressiontest("pr/${pullRequest()}", "pr/${pullRequest()}", '', '', false, '', '', false, false, 0, config) + } else { + runRegressiontest("pr/${pullRequest()}", "pr/${pullRequest()}", 'setCommandLineOptions("--simCodeTarget=wasm-jit")', '', false, '', '--nobuildmodel', false, false, 0, config, + wasmCmakeFlags()) + } + } } } @@ -691,7 +700,7 @@ pipeline { } } sh 'rm -rf history' - sh "./pr-report.py '${pullRequest()}' --baseline='${(params.pull_request_baseline ?: 'master').trim()}'" + sh "./pr-report.py '${pullRequest()}' --baseline='${pullRequestBaseline()}'" // Uploaded before it is announced, as the branch reports are: the // comment links to the report, and nothing after this may be what stops // it from being published. @@ -725,6 +734,14 @@ def pullRequest() { return (params.pull_request ?: '').trim() } +def pullRequestTarget() { + return params.pull_request_target ?: 'wasm-jit' +} + +def pullRequestBaseline() { + return (params.pull_request_baseline ?: '').trim() ?: (pullRequestTarget() == 'C' ? 'master' : 'wasm-jit') +} + /** * The cores of the node a build is running on, physical and logical, asked for * the way the OpenModelica job asks (numPhysicalCPU in .CI/common.groovy @@ -1162,9 +1179,10 @@ def runRegressiontest(branch, name, extraFlags, omsHash, omcompiler, extrasimfla export OPENMODELICAHOME="`pwd`/build" git rev-parse --verify HEAD > .newhash - # Part of the stamp rather than the commit alone: a build/ cached from the other build system is - # not what this job would produce for the same commit. + # Part of the stamp rather than the commit alone: a build/ cached from the other build system, or + # with other cmake flags, is not what this job would produce for the same commit. echo "${useCMake ? 'cmake' : 'autotools'}" >> .newhash + ${cmakeFlags ? "echo '${cmakeFlags}' >> .newhash" : ''} echo New Hash: cat .newhash echo Old Hash: diff --git a/README.md b/README.md index 35f4684..41ad228 100644 --- a/README.md +++ b/README.md @@ -425,11 +425,14 @@ builds every model once and simulates it with each. 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`. +run of `wasm-jit`, or of `master` when it is simulated with the C target. 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. +start the job; `pull_request_target` says which `--simCodeTarget` it is +simulated with (`wasm-jit` by default, which is the cheaper run), and +`pull_request_baseline`, `pull_request_config` and `pull_request_node` what it +is compared against, what it tests and where. The baseline defaults to the job +testing that target. 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 @@ -439,18 +442,19 @@ request as it would land, not the branch on its own - and the run fills a ```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 +# build omc with -DOM_OMC_ENABLE_RUST=ON, then +./test.py --branch=pr/ --nobuildmodel \ + --extraflags='--simCodeTarget=wasm-jit' configs/conf.json ``` `pr/` rather than `pr-`: the pull requests sit together in one directory of `branches/`, which otherwise holds branches. It is the one job name that keeps the directory part of its name - `maintenance/v1.27` is tested as `v1.27`. -The report compares that run against the newest run of `master`: +The report compares that run against the newest run of `wasm-jit`: ```bash -./pr-report.py # --baseline=master by default +./pr-report.py # --baseline=wasm-jit by default; master for C ``` It writes `history/pr//...html`, the same diff --git a/pr-report.py b/pr-report.py index 8080d57..ca31f80 100755 --- a/pr-report.py +++ b/pr-report.py @@ -6,7 +6,7 @@ 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 +wasm-jit (or 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. """ @@ -17,7 +17,7 @@ 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('--baseline', default="wasm-jit", help='the branch the pull request is compared against; master for a run with the C target') 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")