Skip to content

mcstas-conda-testsuite #426

mcstas-conda-testsuite

mcstas-conda-testsuite #426

name: mcstas-conda-testsuite
on:
schedule:
- cron: '00 02 * * *' # 02:00 every day
workflow_dispatch:
inputs:
manual-debugging:
type: boolean
description: Launch manual debugging tmate for inspection (automatic in case of errors)
default: false
jobs:
build:
strategy:
fail-fast: false
matrix:
include:
- { os: ubuntu-latest, mpi: 'openmpi', nmpi: 'auto', cogen: 'classic', method: 'conda' }
- { os: ubuntu-latest, mpi: 'openmpi', nmpi: 'auto', cogen: 'antlr', method: 'conda' }
- { os: macos-latest, mpi: 'openmpi', nmpi: '2', cogen: 'classic', method: 'conda' }
- { os: windows-latest, mpi: 'msmpi', nmpi: 'auto', cogen: 'classic', method: 'conda' }
# mccode.org-style .deb packages from buildscripts/build_debs_mcstas, installed
# in /usr with no $MCSTAS set (as for users of the mccode.org apt repo)
- { os: ubuntu-24.04, mpi: 'openmpi', nmpi: 'auto', cogen: 'classic', method: 'debian' }
name: ${{ matrix.os }}.${{ matrix.mpi }}.${{ matrix.cogen }}${{ matrix.method == 'debian' && '.debian' || '' }}.conda-testsuite
runs-on: ${{ matrix.os }}
defaults:
run:
shell: bash -el {0}
steps:
- name: Checkout
uses: actions/checkout@v6
with:
path: src
- name: Setup VS in shell Intel
if: runner.os == 'Windows'
uses: egor-tensin/vs-shell@v2
- name: Get conda dependency list
id: conda-deps
if: matrix.method == 'conda'
run: |
./src/devel/bin/mccode-create-conda-yml -m mcstas -n mcstas -o dependencies.yml
cat dependencies.yml
- uses: mamba-org/setup-micromamba@v3
if: matrix.method == 'conda'
with:
environment-name: mcstas
environment-file: dependencies.yml
- name: Check versions and set worker label
id: version-checks
run: |
which python3
python3 --version
which cmake
cmake --version
MYWORKERID=`echo ${RUNNER_TRACKING_ID} | md5sum | cut -c1-12`
echo MYWORKERID=${MYWORKERID} >> "$GITHUB_ENV"
- name: Configure build and install mcstas
id: mcstas-install
if: matrix.method == 'conda'
run: |
./src/devel/bin/mccode-build-conda -m mcstas -s $PWD/src -b $PWD/build_mcstas
- name: Build and install mccode.org-style .deb packages (debian)
id: mcstas-install-debian
if: matrix.method == 'debian'
run: |
set -e
set -u
set -x
sudo apt-get update
# Build dependencies, as in dependency-scripts/getdeps_debian (minus LaTeX/equivs:
# the manuals package and the suite metapackage are not needed for testing)
sudo apt-get -y install git cmake gcc g++ gfortran flex bison build-essential rsync libopenmpi-dev openmpi-bin python3-venv
cd src
./buildscripts/build_debs_mcstas 3.99.99
ls -l dist
# Install everything that was built, except the manuals package. apt resolves the
# runtime dependencies declared by the packages themselves (python3-*, libxrl-dev, ...)
sudo apt-get -y install $(ls $PWD/dist/*.deb | grep -v -- '-manuals')
# KDSource is not packaged for Debian, pip is the only route (as for Debian users).
# Install it into its own venv, so its pip dependencies (numpy, scipy, mcpl-core, ...)
# do not shadow the apt-installed ones, and expose only kdsource-config (used for
# KDSOURCEFLAGS) on PATH. libkdsource then resolves libmcpl from the mcpl .deb.
sudo python3 -m venv /opt/kdsource
sudo /opt/kdsource/bin/python -m pip install kdsource
sudo ln -sf /opt/kdsource/bin/kdsource-config /usr/local/bin/kdsource-config
kdsource-config --show buildflags
which -a mcpl-config
# Same openmpi transport settings as in the basictest source builds
sudo sed -i.bak 's/"mpirun/"mpirun --mca btl self,vader,tcp/g' /usr/share/mcstas/tools/Python/mccodelib/mccode_config.json
test -x /usr/bin/mcstas
test -x /usr/bin/mctest
test -d /usr/share/mcstas/resources/data
- name: Setup mcstas-antlr
id: setup-mcstas-antlr
if: matrix.cogen == 'antlr'
continue-on-error: true
run: |
# Cache checkout src/ with mccode-antlr
if [ "${{ matrix.cogen }}" == "antlr" ];
then
# Set up config file to use mcstas-antlr
MCCODE_CONFIG=`mcrun --write-user-config | cut -f4 -d\ `
sed -i.bak s+\"MCCOGEN\"\:\ \"mcstas\",+\"MCCOGEN\"\:\ \"mcstas-antlr\ -I\$\{CONDA_PREFIX\}/share/mcstas/resources\",+g ${MCCODE_CONFIG}
grep -H COGEN ${MCCODE_CONFIG}
MCCODEANTLR_FLAGS__NEXUS=`grep NEXUSFLAGS ${MCCODE_CONFIG} |cut -f4 -d\"`
echo "MCCODEANTLR_FLAGS__NEXUS=${MCCODEANTLR_FLAGS__NEXUS}" >> "$GITHUB_ENV"
# Pre-poulate mccode-antlr cache
mccode-antlr cache populate --from-path src/ --flavor mcstas --no-strict --check-hashes
fi
- name: Validate build output
id: build-validation
if: always() && matrix.method == 'conda'
run: |
set -e
set -u
set -x
if [ "$RUNNER_OS" == "Windows" ];
then
echo "Validating Windows build output..."
echo "CONDA_PREFIX: $CONDA_PREFIX"
echo "Checking for mcstas executable..."
test -f ${CONDA_PREFIX}/bin/mcstas || test -f ${CONDA_PREFIX}/bin/mcstas.bat || { echo "ERROR: mcstas not found"; exit 1; }
echo "Checking for mctest executable..."
test -f ${CONDA_PREFIX}/bin/mctest.bat || { echo "ERROR: mctest.bat not found"; ls -la ${CONDA_PREFIX}/bin/ | grep -i mctest || echo "No mctest found"; exit 1; }
else
echo "Validating Unix build output..."
test -f ${CONDA_PREFIX}/bin/mcstas || { echo "ERROR: mcstas not found"; exit 1; }
test -f ${CONDA_PREFIX}/bin/mctest || { echo "ERROR: mctest not found"; exit 1; }
fi
- name: Post install openmpi hacks macOS
id: post-install-openmpi-hacks-macOS
if: runner.os == 'macOS'
run: |
if [ "${{ matrix.mpi }}" == "openmpi" ]; then
sed -i.bak 's+mpirun+mpirun\ -mca\ regx\ naive\ --verbose\ --mca\ btl_tcp_if_include\ lo0+g' ${CONDA_PREFIX}/share/mcstas/tools/Python/mccodelib/mccode_config.json
fi
- name: Test suite, up to 2-core MPI
id: test-suite
run: |
# Create and cd to directory for test output data
mkdir run_test-suite && cd run_test-suite
# Test script name
export MCTEST_EXECUTABLE="mctest"
if [ "$RUNNER_OS" == "Windows" ];
then
export MCTEST_EXECUTABLE="mctest.bat"
fi
# Workaround for warning about "too long" tmpdir name on macOS/openmpi
if [ "$RUNNER_OS" == "macOS" ];
then
mkdir ${HOME}/tmp
export TMPDIR=${HOME}/tmp
fi
if [ "${{ matrix.method }}" == "debian" ];
then
# Use the system python3 the .deb tools are installed for, and make
# sure the resource dir is NOT given via the environment
export PATH=/usr/bin:$PATH
unset MCSTAS
test "$(command -v mctest)" == "/usr/bin/mctest"
fi
# Run the test with 2 core mpi
${MCTEST_EXECUTABLE} --verbose --nsigma 5 --testdir $PWD --suffix ${{ matrix.cogen }}_${{ matrix.os }}_${{ matrix.mpi }}${{ matrix.method == 'debian' && '_debian' || '' }} --mpi=${{ matrix.nmpi }} --uid=${MYWORKERID}
- name: 'Tar output files'
id: tar-package
if: always()
run: |
set -e
set -u
set -x
# Clear out binaries from sim dir and tar up artifact
ls | grep run_ | xargs -n1 ./src/devel/bin/mccode-simdir-cleanfiles -d
tar cvfz mcstas-${{ matrix.cogen }}.${{ matrix.os }}.${{ matrix.mpi }}${{ matrix.method == 'debian' && '.debian' || '' }}.conda-testsuite_output.tgz run_test-suite
- name: 'Upload Artifact'
id: tar-upload
uses: actions/upload-artifact@v6
if: always()
with:
name: mcstas-artefacts-${{ matrix.os }}.${{ matrix.cogen }}.${{ matrix.mpi }}${{ matrix.method == 'debian' && '.debian' || '' }}.conda-testsuite
path: "mcstas-${{ matrix.cogen }}.${{ matrix.os }}.${{ matrix.mpi }}${{ matrix.method == 'debian' && '.debian' || '' }}.conda-testsuite_output.tgz"
- name: Setup tmate session for manual debugging
uses: mxschmitt/action-tmate@v3
if: always() && (inputs.manual-debugging == true)
with:
limit-access-to-actor: true
compare:
name: mcstas-conda-testsuite-comparison
needs: build
if: always()
runs-on: ubuntu-latest
defaults:
run:
shell: bash -el {0}
steps:
- name: Checkout
uses: actions/checkout@v6
with:
path: src
- name: Get conda dependency list
id: conda-deps
run: |
./src/devel/bin/mccode-create-conda-yml -m mcstas -n mcstas -o dependencies.yml
- uses: mamba-org/setup-micromamba@v3
with:
environment-name: mcstas
environment-file: dependencies.yml
- name: Configure build and install mcstas
id: mcstas-install
run: |
# Only the Python tooling (mcviewtest, mcplotdiff-html, mcplot-html) is
# actually needed here - the diff/report generation is platform-agnostic
# regardless of which OS originally produced the monitor data - but we
# reuse the exact same install path as the build job for consistency,
# rather than maintaining a second, lighter-weight install mechanism.
./src/devel/bin/mccode-build-conda -m mcstas -s $PWD/src -b $PWD/build_mcstas
- name: 'Download all platform test artifacts'
id: download
uses: actions/download-artifact@v6
with:
# matches mcstas-artefacts-ubuntu-latest.openmpi.conda-testsuite,
# mcstas-artefacts-macos-latest.openmpi.conda-testsuite,
# mcstas-artefacts-windows-latest.msmpi.conda-testsuite - by pattern
# rather than hardcoded names, so this keeps working if the build
# matrix gains/loses a platform
pattern: mcstas-artefacts-*.conda-testsuite
path: downloaded_artifacts
- name: 'Merge platform columns into one shared testdir'
id: merge
run: |
set -e
set -u
set -x
mkdir mcstas-nightly
REFLABEL=""
# Each platform's tarball contains exactly one label directory
# directly under run_test-suite/ (e.g.
# mcstas-3.99.99_mpi_x_2_ubuntu-latest_openmpi_<ncount>_Linux_<datetime>).
# mcviewtest treats each such directory as one comparison "column",
# so merging them as siblings under one shared testdir is all that's
# needed to make them comparable.
for tgz in downloaded_artifacts/*/*.tgz; do
work=$(mktemp -d)
tar xzf "$tgz" -C "$work"
artifact_name=$(basename "$(dirname "$tgz")")
for labeldir in "$work"/run_test-suite/*/; do
if [[ "$artifact_name" == *"ubuntu-latest"* ]]; then
REFLABEL=$(basename "$labeldir")
fi
mv $labeldir mcstas-nightly/
done
done
rm -rf "$work"
if [ -z "$REFLABEL" ]; then
echo "WARNING: could not identify the ubuntu-latest/conda reference column"
else
echo "REFLABEL=$REFLABEL" >> "$GITHUB_ENV"
echo "Reference column: $REFLABEL"
fi
- name: 'Run mcviewtest across all platform columns'
id: viewtest
run: |
cd "$PWD/mcstas-nightly"
if [ -z "$REFLABEL" ]; then
mcviewtest --reflabel "$REFLABEL" --nobrowse
else
mcviewtest --reflabel --nobrowse
fi
- name: 'Tar mcstas-nightly output (all platform folders + comparison table)'
id: tar-package
if: always()
run: |
tar cvfz mcstas-conda-testsuite-comparison.tgz mcstas-nightly
- name: 'Upload comparison artifact'
id: comparison-upload
uses: actions/upload-artifact@v6
if: always()
with:
name: mcstas-testsuite-comparison
path: mcstas-conda-testsuite-comparison.tgz
- name: Setup tmate session for manual debugging
uses: mxschmitt/action-tmate@v3
if: always() && (inputs.manual-debugging == true)
with:
limit-access-to-actor: true