Skip to content

Shared env test

Shared env test #1

# Experiment: pay the environment setup ONCE and run every slice inside it.
#
# Today each of the 12 slices is its own job: fresh workspace, fresh
# containers, fresh waits - ~2-4 min of fixed overhead per slice around
# ~31 min of actual tests (serial total ~55 min). This workflow starts the
# containers once and calls the UNCHANGED Jenkins test script sequentially
# for slice 0..13 (12 hash slices + the two dedicated REST slices) in the
# same environment. Safe because the report compares by test NAME across
# XML files (PullRequestReport.py:171-186, layout-independent), the script
# writes one distinctly-named XML per slice, and per-test DB cleanup already
# handles state between tests. Expected: ~35-38 min instead of ~55.
#
# Dispatch from the branch copy:
# gh workflow run shared-env-test.yml -R Viphava280444/WMCore --ref ci-improve-exp
name: Shared env test
on:
workflow_dispatch:
permissions:
contents: read
concurrency:
group: shared-env-test
cancel-in-progress: false
env:
WMA_TAG: '2.3.3'
COUCH_TAG: '3.2.2'
MDB_TAG: '10.6.19'
TEST_SERVICE: 'wmcore-unittests'
# SLICES stays 12: slices 0..11 = hash split, 12 -> Api_t, 13 -> Simple_t
SLICES: '12'
WMCORE_DEV_TAG: 'py3.12-2.4.4rc5-stable'
BUILD_ID: ${{ github.run_id }}
ghprbPullId: ''
ghprbTargetBranch: ''
WMA_CONFIG_FILE: ''
DMWMBOT_TOKEN: ''
WMCORE_JENKINS_ORG: dmwm
WMCORE_JENKINS_REF: main
WMCORE_JENKINS_HOST_DIR: /data/vkhlaisu/WMCore-Jenkins
jobs:
all-slices-one-env:
runs-on: [self-hosted, Linux, X64]
timeout-minutes: 75
steps:
- name: Checkout this repo (CI glue)
uses: actions/checkout@v4
with:
path: wmcore-src
- name: Runtime environment
run: |
echo "MY_HOSTNAME=$(hostname -f)" >> "$GITHUB_ENV"
echo "MY_ID=$(id -u)" >> "$GITHUB_ENV"
echo "MY_GROUP=$(id -g)" >> "$GITHUB_ENV"
echo "HOST_MOUNT_DIR=$GITHUB_WORKSPACE/ci-workspace" >> "$GITHUB_ENV"
echo "COMPOSE_FILE=$GITHUB_WORKSPACE/wmcore-src/.github/ci/docker-compose.yml:$GITHUB_WORKSPACE/wmcore-src/.github/ci/docker-compose.override.yml" >> "$GITHUB_ENV"
docker version
- name: Prepare workspace (fork twin of setup-env.sh)
run: bash wmcore-src/.github/ci/setup-env-gha.sh
- name: Stop leftover containers
run: |
[ -n "$COMPOSE_FILE" ] && docker compose down --remove-orphans || true
- name: Start containers (ONCE)
run: |
docker compose up --quiet-pull -d mariadb couchdb "$TEST_SERVICE"
sleep 20
docker ps
docker compose logs mariadb | tail -5
docker compose logs couchdb | tail -5
- name: Wait for container CI setup
run: |
ready=""
for i in $(seq 1 60); do
if docker compose exec -T "$TEST_SERVICE" test -f /home/cmsbld/TestScripts/test-wmcorepy3.sh; then ready=1; break; fi
sleep 5
done
[ -n "$ready" ] || { docker compose logs "$TEST_SERVICE"; exit 1; }
- name: Point dmwm/WMCore at this fork
run: |
docker compose exec -T -u "$MY_ID" -e GIT_CONFIG_GLOBAL=/tmp/wmci-gitconfig -e GITHUB_REPOSITORY="$GITHUB_REPOSITORY" "$TEST_SERVICE" bash -c '
git config --file "$GIT_CONFIG_GLOBAL" url."https://github.com/$GITHUB_REPOSITORY.git".insteadOf "https://github.com/dmwm/WMCore.git"
git config --file "$GIT_CONFIG_GLOBAL" user.name "wmcore-fork-ci"
git config --file "$GIT_CONFIG_GLOBAL" user.email "wmcore-fork-ci@users.noreply.github.com"
git config --file "$GIT_CONFIG_GLOBAL" --add safe.directory "*"'
- name: Run ALL slices in the shared environment (timed)
run: |
overall=$(date +%s)
for S in 0 1 2 3 4 5 6 7 8 9 10 11 12 13; do
start=$(date +%s)
docker compose exec -T -u "$MY_ID" \
-e BUILD_ID="$BUILD_ID" -e SLICES="$SLICES" -e SLICE="$S" \
-e GIT_CONFIG_GLOBAL=/tmp/wmci-gitconfig \
"$TEST_SERVICE" /home/cmsbld/TestScripts/test-wmcorepy3.sh
echo "SHARED_ENV slice=$S wall_seconds=$(( $(date +%s) - start ))" | tee -a ci-workspace/artifacts/shared-env-timing.txt
done
echo "SHARED_ENV total_wall_seconds=$(( $(date +%s) - overall ))" | tee -a ci-workspace/artifacts/shared-env-timing.txt
- name: Upload results
if: always()
uses: actions/upload-artifact@v4
with:
name: shared-env-results
path: |
ci-workspace/artifacts/nosetests*.xml
ci-workspace/artifacts/shared-env-timing.txt
if-no-files-found: warn
- name: Stop containers
if: always()
run: |
[ -n "$COMPOSE_FILE" ] && docker compose down || true
- name: Integrity summary
if: always()
run: |
python3 - <<'EOF'
import glob, os, re
try:
from defusedxml import ElementTree as ET
except ImportError:
import xml.etree.ElementTree as ET
total = fails = errs = 0
rows = []
for f in sorted(glob.glob('ci-workspace/artifacts/nosetests*.xml')):
try:
s = ET.parse(f).getroot()
except ET.ParseError:
continue
suites = [s] if s.tag == 'testsuite' else s.findall('testsuite')
for su in suites:
total += int(su.get('tests', 0)); fails += int(su.get('failures', 0)); errs += int(su.get('errors', 0))
rows.append(f"- `{os.path.basename(f)}`: {su.get('tests')} tests, {su.get('failures')} failures, {su.get('errors')} errors")
timing = ''
tf = 'ci-workspace/artifacts/shared-env-timing.txt'
if os.path.exists(tf):
timing = open(tf).read()
lines = ['## Shared-environment run (setup paid once, slices 0-13)', '',
f'**Total tests: {total}** (expect 1653 = 1632 hash + 21 dedicated), failures {fails}, errors {errs}', ''] + rows + ['', '```', timing, '```']
with open(os.environ['GITHUB_STEP_SUMMARY'], 'a') as out:
out.write('\n'.join(lines) + '\n')
EOF