-
Notifications
You must be signed in to change notification settings - Fork 204
192 lines (179 loc) · 8.12 KB
/
Copy pathsim-tests.yml
File metadata and controls
192 lines (179 loc) · 8.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
---
name: Simulation tests
'on':
pull_request: {}
workflow_dispatch:
inputs:
tag:
description: 'O2PDPSuite tag to test against (default: newest daily)'
type: string
required: false
permissions: {}
concurrency:
group: sim-tests-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
sim-tests:
name: Simulation tests against CVMFS
runs-on: [self-hosted, cvmfs]
timeout-minutes: 180
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
# The changed-file logic diffs against the merge base, so the full
# history is needed, not a shallow clone.
fetch-depth: 0
- name: Resolve the diff base
id: base
if: github.event_name == 'pull_request'
env:
BASE_SHA: ${{ github.event.pull_request.base.sha }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
run: |
set -eu
git rev-parse --verify "$BASE_SHA^{commit}" >/dev/null || {
echo "::error title=Cannot resolve diff base::pull request base commit $BASE_SHA does not resolve in this checkout"
exit 1
}
git rev-parse --verify "$HEAD_SHA^{commit}" >/dev/null || {
echo "::error title=Cannot resolve diff head::pull request head commit $HEAD_SHA does not resolve in this checkout"
exit 1
}
merge_base=$(git merge-base "$BASE_SHA" "$HEAD_SHA") || {
echo "::error title=Cannot compute diff base::git merge-base failed"
exit 1
}
[ -n "$merge_base" ] || {
echo "::error title=Cannot compute diff base::merge base is empty"
exit 1
}
echo "sha=$merge_base" >> "$GITHUB_OUTPUT"
- name: Skip when not relevant or opted into the source build
id: gate
if: github.event_name == 'pull_request'
env:
BASE_SHA: ${{ steps.base.outputs.sha }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
run: |
set -eu
changed=$(git diff --name-only "$BASE_SHA" "$HEAD_SHA")
# Opting in means *editing* the existing sentinel, so only count it
# when it is Modified. A pull request that Adds it — which is what the
# pull request introducing the sentinel does — would otherwise trip its
# own opt-out and pass without testing anything.
opted=$(git diff --name-only --diff-filter=M "$BASE_SHA" "$HEAD_SHA")
if grep -qx 'test/needs-o2-dev' <<< "$opted" ; then
echo "::notice title=Skipped::this pull request touches test/needs-o2-dev, so it is tested by build/O2DPG/sim/o2dev against O2 dev instead"
echo "skip=true" >> "$GITHUB_OUTPUT"
elif ! grep -qE '^(DATA/|MC/|test/|RelVal/)' <<< "$changed" ; then
echo "::notice title=Skipped::no changed file matches DATA/, MC/, test/ or RelVal/"
echo "skip=true" >> "$GITHUB_OUTPUT"
else
echo "skip=false" >> "$GITHUB_OUTPUT"
fi
- name: Check the CVMFS environment
if: steps.gate.outputs.skip != 'true'
run: |
set -eu
test -d /cvmfs/alice.cern.ch || {
echo "::error title=CVMFS unavailable::/cvmfs/alice.cern.ch is not mounted on this runner"
exit 1
}
test -x /cvmfs/alice.cern.ch/bin/alienv || {
echo "::error title=CVMFS unavailable::/cvmfs/alice.cern.ch/bin/alienv is missing"
exit 1
}
- name: Check the AliEn token
if: steps.gate.outputs.skip != 'true'
env:
JALIEN_TOKEN_CERT: /run/alien-ci/tokencert.pem
JALIEN_TOKEN_KEY: /run/alien-ci/tokenkey.pem
run: |
set -eu
# DPL's CCDB backend refuses to talk to alice-ccdb.cern.ch without a
# token and aborts the whole device, so check up front rather than
# letting it surface as a confusing task crash deep in a workflow.
for f in "$JALIEN_TOKEN_CERT" "$JALIEN_TOKEN_KEY" ; do
test -r "$f" || {
echo "::error title=No AliEn token::$f is missing or unreadable. On the runner host: systemctl start alien-ci-token.service"
exit 1
}
done
if ! openssl x509 -in "$JALIEN_TOKEN_CERT" -noout -checkend 3600 >/dev/null 2>&1 ; then
echo "::error title=AliEn token expiring::the token expires within the hour. On the runner host: systemctl start alien-ci-token.service"
exit 1
fi
echo "AliEn token valid until $(openssl x509 -in "$JALIEN_TOKEN_CERT" -noout -enddate | cut -d= -f2)"
- name: Resolve the O2PDPSuite tag
id: tag
if: steps.gate.outputs.skip != 'true'
env:
REQUESTED_TAG: ${{ inputs.tag }}
PR_BODY: ${{ github.event.pull_request.body }}
run: |
set -eu
# shellcheck source=test/ci/resolve_tag.sh
. test/ci/resolve_tag.sh
moduledir=/cvmfs/alice.cern.ch/el9-x86_64/Modules/modulefiles/O2PDPSuite
requested=$REQUESTED_TAG
if [ -z "$requested" ]; then
# A PR can pin the release with a line "sim-tests-tag: <tag>".
requested=$(printf '%s\n' "$PR_BODY" |
sed -n 's/^[[:space:]]*sim-tests-tag:[[:space:]]*//p' | head -n 1 |
tr -d '[:space:]')
fi
tag=$(resolve_o2pdpsuite_tag "$moduledir" "$requested") || {
echo "::error title=No usable O2PDPSuite release::see the message above"
exit 1
}
echo "Testing against O2PDPSuite::$tag"
echo "tag=$tag" >> "$GITHUB_OUTPUT"
- name: Run the O2DPG tests
if: steps.gate.outputs.skip != 'true'
env:
O2PDPSUITE_TAG: ${{ steps.tag.outputs.tag }}
O2DPG_TEST_HASH_BASE: ${{ steps.base.outputs.sha }}
O2DPG_TEST_HASH_HEAD: ${{ github.event.pull_request.head.sha }}
JOBS: 8
# o2dpg_sim_workflow.py calls JAlien(['whoami']) purely to fill the
# AOD's --created-by field, and only when JALIEN_USER is unset. Setting
# it keeps the tests from needing a GRID credential at all, which
# matters here: anything readable by this account is readable by the
# fork-pull-request code that runs as it.
JALIEN_USER: alien-ci
# DPL's CCDB backend needs a GRID token for alice-ccdb.cern.ch. These
# are *paths* to a short-lived token minted from a service certificate
# by a root-owned timer on the runner host; the certificate itself is
# never readable by this account. Verified that paths work — the same
# variables also accept PEM content, which is what ali-bot passes.
JALIEN_TOKEN_CERT: /run/alien-ci/tokencert.pem
JALIEN_TOKEN_KEY: /run/alien-ci/tokenkey.pem
run: |
set -eu
# Everything after "-c" is joined into one string and re-evaluated
# by the CVMFS alienv via "bash -c \"$*\"". Quoting here is applied
# once then discarded, so it is safe for the runner's workspace path,
# but a path with a space or "$" would break or double-evaluate.
/cvmfs/alice.cern.ch/bin/alienv setenv "O2PDPSuite/$O2PDPSUITE_TAG" -c \
env O2DPG_ROOT="$PWD" O2DPG_MC_CONFIG_ROOT="$PWD" \
O2DPG_TEST_REPO_DIR="$PWD" \
O2DPG_TEST_HASH_BASE="$O2DPG_TEST_HASH_BASE" \
O2DPG_TEST_HASH_HEAD="$O2DPG_TEST_HASH_HEAD" \
JOBS="$JOBS" \
bash test/run_tests.sh
- name: Upload logs
if: always()
uses: actions/upload-artifact@v4
with:
name: o2dpg-test-logs
path: |
o2dpg_tests/**/*.log
o2dpg_tests/**/*serverlog*
o2dpg_tests/**/*workerlog*
o2dpg_tests/**/*mergerlog*
if-no-files-found: ignore
retention-days: 14
- name: Prune test artifacts
if: always()
run: find o2dpg_tests -type f ! -name '*.log' ! -name '*serverlog*' ! -name '*workerlog*' ! -name '*mergerlog*' -delete || true