Skip to content

Commit 0d09eb1

Browse files
[CI] Split E2E/CTS tests into composite action (#16739)
Two reasons: * Make the workflow more maintainable as we're in the process of adding another option (benchmarks) * I want to move E2E build-only from a separate job to a step during `sycl-linux-build.yml`. My first thought was to use in-tree E2E configuration but then it mismatches how we'd run the tests (in a standalone mode) and we have a bunch of tests using `rpath` during compilation which can't work with such mismatch. As such, outlining E2E support into a composite action would allow to share code between build/run e2e tests in distinct jobs (build vs matrix run-tests).
1 parent 34ef866 commit 0d09eb1

File tree

3 files changed

+262
-190
lines changed

3 files changed

+262
-190
lines changed

.github/workflows/sycl-linux-run-tests.yml

Lines changed: 17 additions & 190 deletions
Original file line numberDiff line numberDiff line change
@@ -210,27 +210,6 @@ jobs:
210210
devops
211211
- name: Register cleanup after job is finished
212212
uses: ./devops/actions/cleanup
213-
- name: Checkout E2E tests
214-
if: inputs.tests_selector == 'e2e'
215-
uses: ./devops/actions/cached_checkout
216-
with:
217-
path: llvm
218-
ref: ${{ inputs.ref || github.sha }}
219-
merge_ref: ${{ inputs.merge_ref }}
220-
cache_path: "/__w/repo_cache/"
221-
- name: Checkout SYCL CTS tests
222-
if: inputs.tests_selector == 'cts' && inputs.cts_testing_mode != 'run-only'
223-
uses: ./devops/actions/cached_checkout
224-
with:
225-
path: khronos_sycl_cts
226-
repository: 'KhronosGroup/SYCL-CTS'
227-
ref: 'main'
228-
default_branch: 'main'
229-
cache_path: "/__w/repo_cache/"
230-
- name: SYCL CTS GIT submodules init
231-
if: inputs.tests_selector == 'cts' && inputs.cts_testing_mode != 'run-only'
232-
run: |
233-
git -C khronos_sycl_cts submodule update --init
234213
- name: Install drivers
235214
if: inputs.install_igc_driver == 'true' || inputs.install_dev_igc_driver == 'true'
236215
env:
@@ -312,178 +291,26 @@ jobs:
312291
cat /usr/local/lib/igc/IGCTAG.txt
313292
fi
314293
315-
- name: Download E2E Binaries
316-
if: inputs.e2e_binaries_artifact != ''
317-
uses: actions/download-artifact@v4
318-
with:
319-
name: ${{ inputs.e2e_binaries_artifact }}
320-
- name: Extract E2E Binaries
321-
if: inputs.e2e_binaries_artifact != ''
322-
run: |
323-
mkdir build-e2e
324-
tar -I 'zstd' -xf e2e_binaries.tar.zst -C build-e2e
325-
326-
- name: Deduce E2E CMake options
327-
if: inputs.tests_selector == 'e2e' && inputs.e2e_binaries_artifact == ''
328-
id: cmake_opts
329-
shell: bash
330-
env:
331-
CMAKE_EXTRA_ARGS: ${{ inputs.extra_cmake_args }}
332-
run: |
333-
if [ -n "$CMAKE_EXTRA_ARGS" ]; then
334-
echo "opts=$CMAKE_EXTRA_ARGS" >> $GITHUB_OUTPUT
335-
fi
336-
- name: Configure E2E tests
337-
if: inputs.tests_selector == 'e2e' && inputs.e2e_binaries_artifact == ''
338-
run: |
339-
cmake -GNinja -B./build-e2e -S./llvm/sycl/test-e2e -DCMAKE_CXX_COMPILER="$(which clang++)" -DLLVM_LIT="$PWD/llvm/llvm/utils/lit/lit.py" ${{ steps.cmake_opts.outputs.opts }}
340-
- name: SYCL End-to-end tests
341-
shell: bash {0}
294+
- name: Run E2E Tests
342295
if: inputs.tests_selector == 'e2e'
343-
env:
344-
LIT_OPTS: -v --no-progress-bar --show-unsupported --show-pass --show-xfail --max-time 3600 --time-tests --param test-mode=${{ inputs.e2e_testing_mode }} --param sycl_devices=${{ inputs.target_devices }} ${{ inputs.extra_lit_opts }}
345-
run: |
346-
ninja -C build-e2e check-sycl-e2e > e2e.log 2>&1
347-
exit_code=$?
348-
cat e2e.log
349-
if [ $exit_code -ne 0 ]; then
350-
awk '/^Failed Tests|Unexpectedly Passed Tests|Unresolved tests|Testing Time/{flag=1}/FAILED: CMakeFiles/{flag=0}flag' e2e.log >> $GITHUB_STEP_SUMMARY
351-
fi
352-
exit $exit_code
353-
- name: Build SYCL CTS tests
354-
if: inputs.tests_selector == 'cts' && inputs.sycl_cts_artifact == ''
355-
env:
356-
CMAKE_EXTRA_ARGS: ${{ inputs.extra_cmake_args }}
357-
run: |
358-
cts_exclude_filter=""
359-
# If CTS_TESTS_TO_BUILD is null - use filter
360-
if [ -z "$CTS_TESTS_TO_BUILD" ]; then
361-
if [ "${{ contains(inputs.cts_testing_mode, 'build-only') }}" = "true" ]; then
362-
cts_exclude_filter=$PWD/devops/cts_exclude_filter_compfails
363-
elif [ "${{ contains(inputs.target_devices, 'opencl:cpu') }}" = "true" ]; then
364-
cts_exclude_filter=$PWD/devops/cts_exclude_filter_OCL_CPU
365-
elif [ "${{ contains(inputs.target_devices, 'level_zero:gpu') }}" = "true" ]; then
366-
cts_exclude_filter=$PWD/devops/cts_exclude_filter_L0_GPU
367-
fi
368-
369-
# List excluded SYCL CTS categories:
370-
# SYCL_CTS_EXCLUDE_TEST_CATEGORIES - Optional file specifying a list
371-
# of test categories to be excluded from the build.
372-
echo "::group::Excluded test categories"
373-
cat $cts_exclude_filter
374-
echo "::endgroup::"
375-
fi
376-
377-
cmake -GNinja -B./build-cts -S./khronos_sycl_cts -DCMAKE_CXX_COMPILER=$(which clang++) \
378-
-DSYCL_IMPLEMENTATION=DPCPP \
379-
-DSYCL_CTS_EXCLUDE_TEST_CATEGORIES="$cts_exclude_filter" \
380-
-DSYCL_CTS_ENABLE_OPENCL_INTEROP_TESTS=OFF \
381-
-DDPCPP_INSTALL_DIR="$(dirname $(which clang++))/.." \
382-
$CMAKE_EXTRA_ARGS
383-
# Ignore errors so that if one category build fails others still have a
384-
# chance to finish and be executed at the run stage. Note that
385-
# "test_conformance" target skips building "test_all" executable.
386-
ninja -C build-cts -k0 $( [ -n "$CTS_TESTS_TO_BUILD" ] && echo "$CTS_TESTS_TO_BUILD" || echo "test_conformance")
387-
388-
- name: Pack SYCL-CTS binaries
389-
if: always() && !cancelled() && inputs.cts_testing_mode == 'build-only'
390-
run: tar -I 'zstd -9' -cf sycl_cts_bin.tar.zst -C ./build-cts/bin .
391-
392-
- name: Upload SYCL-CTS binaries
393-
if: always() && !cancelled() && inputs.cts_testing_mode == 'build-only'
394-
uses: actions/upload-artifact@v4
296+
uses: ./devops/actions/run-tests/e2e
395297
with:
396-
name: sycl_cts_bin
397-
path: sycl_cts_bin.tar.zst
298+
ref: ${{ inputs.ref || github.sha }}
299+
merge_ref: ${{ inputs.merge_ref }}
300+
e2e_binaries_artifact: ${{ inputs.e2e_binaries_artifact }}
301+
extra_cmake_args: ${{ inputs.extra_cmake_args }}
302+
e2e_testing_mode: ${{ inputs.e2e_testing_mode }}
303+
target_devices: ${{ inputs.target_devices }}
304+
extra_lit_opts: ${{ inputs.extra_lit_opts }}
305+
artifact_suffix: ${{ inputs.artifact_suffix }}
398306
retention-days: ${{ inputs.retention-days }}
399307

400-
- name: Download SYCL-CTS binaries
401-
if: inputs.sycl_cts_artifact != ''
402-
uses: actions/download-artifact@v4
403-
with:
404-
name: ${{ inputs.sycl_cts_artifact }}
405-
406-
- name: Extract SYCL-CTS binaries
407-
if: inputs.sycl_cts_artifact != ''
408-
run: |
409-
mkdir -p build-cts/bin
410-
tar -I 'zstd' -xf sycl_cts_bin.tar.zst -C build-cts/bin
411-
412-
- name: SYCL CTS List devices
413-
# Proceed with execution even if the 'build' step did not succeed.
414-
if: inputs.tests_selector == 'cts' && (always() && !cancelled()) && inputs.cts_testing_mode != 'build-only'
415-
env:
416-
ONEAPI_DEVICE_SELECTOR: ${{ inputs.target_devices }}
417-
run: |
418-
./build-cts/bin/* --list-devices
419-
420-
# If the suite was built on another machine then the build contains the full
421-
# set of tests. We have special files to filter out some test categories,
422-
# see "devops/cts_exclude_filter_*". Each configuration has its own file, e.g.
423-
# there is "cts_exclude_filter_OCL_CPU" for opencl:cpu device. Therefore,
424-
# these files may differ from each other, so when there is a pre-built set of
425-
# tests, we need to filter it according to the filter-file.
426-
- name: Filter SYCL CTS test categories
427-
if: inputs.sycl_cts_artifact != ''
428-
shell: bash
429-
run: |
430-
cts_exclude_filter=""
431-
if [ "${{ contains(inputs.target_devices, 'opencl:cpu') }}" = "true" ]; then
432-
cts_exclude_filter=$PWD/devops/cts_exclude_filter_OCL_CPU
433-
elif [ "${{ contains(inputs.target_devices, 'level_zero:gpu') }}" = "true" ]; then
434-
cts_exclude_filter=$PWD/devops/cts_exclude_filter_L0_GPU
435-
fi
436-
437-
while IFS= read -r line; do
438-
if [[ $line != \#* ]]; then
439-
rm "./build-cts/bin/test_$line"
440-
fi
441-
done < "$cts_exclude_filter"
442-
443-
- name: Run SYCL CTS tests
444-
# Proceed with execution even if the previous two steps did not succeed.
445-
if: inputs.tests_selector == 'cts' && (always() && !cancelled()) && inputs.cts_testing_mode != 'build-only'
446-
env:
447-
ONEAPI_DEVICE_SELECTOR: ${{ inputs.target_devices }}
448-
# This job takes ~100min usually. But sometimes some test isn't
449-
# responding, so the job reaches the 360min limit. Setting a lower one.
450-
timeout-minutes: 150
451-
# By-default GitHub actions execute the "run" shell script with -e option,
452-
# so the execution terminates if any command returns a non-zero status.
453-
# Since we're using a loop to run all test-binaries separately, some test
454-
# may fail and terminate the execution. Setting "shell" value to override
455-
# the default behavior.
456-
# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#custom-shell
457-
shell: bash {0}
458-
run: |
459-
# Run each test category separately so that
460-
# - crash on one would not affect others
461-
# - multiple tests could be run in parallel
462-
mkdir logs
463-
find build-cts/bin/ -type f -print | \
464-
xargs -t -I % -P 8 sh -c 'log=logs/$(basename %).log ; echo % >$log ; date >>$log ; timeout 60m % >>$log 2>&1 ; ret=$? ; echo "exit code: $ret" >>$log ; date >>$log ; exit $ret'
465-
ret=$?
466-
467-
for f in logs/* ; do
468-
echo "::group::$f"
469-
cat $f
470-
echo "::endgroup::"
471-
done
472-
473-
echo "::group::Fails:"
474-
grep 'exit code: [^0]' -r logs
475-
echo "::endgroup::"
476-
477-
grep 'exit code: [^0]' -r logs >> $GITHUB_STEP_SUMMARY
478-
479-
exit $ret
480-
- name: Pack E2E binaries
481-
if: ${{ always() && !cancelled() && inputs.e2e_testing_mode == 'build-only'}}
482-
run: tar -I 'zstd -9' -cf e2e_binaries.tar.zst -C ./build-e2e .
483-
- name: Upload E2E binaries
484-
if: ${{ always() && !cancelled() && inputs.e2e_testing_mode == 'build-only'}}
485-
uses: actions/upload-artifact@v4
308+
- name: Run SYCL CTS Tests
309+
if: inputs.tests_selector == 'cts'
310+
uses: ./devops/actions/run-tests/cts
486311
with:
487-
name: sycl_e2e_bin_${{ inputs.artifact_suffix }}
488-
path: e2e_binaries.tar.zst
312+
extra_cmake_args: ${{ inputs.extra_cmake_args }}
313+
cts_testing_mode: ${{ inputs.cts_testing_mode }}
314+
sycl_cts_artifact: ${{ inputs.sycl_cts_artifact }}
315+
target_devices: ${{ inputs.target_devices }}
489316
retention-days: ${{ inputs.retention-days }}
Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
name: 'Run SYCL CTS tests'
2+
3+
inputs:
4+
extra_cmake_args:
5+
required: false
6+
cts_testing_mode:
7+
required: true
8+
sycl_cts_artifact:
9+
require: false
10+
target_devices:
11+
required: true
12+
retention-days:
13+
required: false
14+
15+
runs:
16+
using: "composite"
17+
steps:
18+
- name: Checkout SYCL CTS tests
19+
if: inputs.cts_testing_mode != 'run-only'
20+
uses: ./devops/actions/cached_checkout
21+
with:
22+
path: khronos_sycl_cts
23+
repository: 'KhronosGroup/SYCL-CTS'
24+
ref: 'main'
25+
default_branch: 'main'
26+
cache_path: "/__w/repo_cache/"
27+
- name: SYCL CTS GIT submodules init
28+
if: inputs.cts_testing_mode != 'run-only'
29+
shell: bash
30+
run: |
31+
git -C khronos_sycl_cts submodule update --init
32+
- name: Build SYCL CTS tests
33+
if: inputs.sycl_cts_artifact == ''
34+
shell: bash
35+
env:
36+
CMAKE_EXTRA_ARGS: ${{ inputs.extra_cmake_args }}
37+
run: |
38+
cts_exclude_filter=""
39+
# If CTS_TESTS_TO_BUILD is null - use filter
40+
if [ -z "$CTS_TESTS_TO_BUILD" ]; then
41+
if [ "${{ contains(inputs.cts_testing_mode, 'build-only') }}" = "true" ]; then
42+
cts_exclude_filter=$PWD/devops/cts_exclude_filter_compfails
43+
elif [ "${{ contains(inputs.target_devices, 'opencl:cpu') }}" = "true" ]; then
44+
cts_exclude_filter=$PWD/devops/cts_exclude_filter_OCL_CPU
45+
elif [ "${{ contains(inputs.target_devices, 'level_zero:gpu') }}" = "true" ]; then
46+
cts_exclude_filter=$PWD/devops/cts_exclude_filter_L0_GPU
47+
fi
48+
49+
# List excluded SYCL CTS categories:
50+
# SYCL_CTS_EXCLUDE_TEST_CATEGORIES - Optional file specifying a list
51+
# of test categories to be excluded from the build.
52+
echo "::group::Excluded test categories"
53+
cat $cts_exclude_filter
54+
echo "::endgroup::"
55+
fi
56+
57+
cmake -GNinja -B./build-cts -S./khronos_sycl_cts -DCMAKE_CXX_COMPILER=$(which clang++) \
58+
-DSYCL_IMPLEMENTATION=DPCPP \
59+
-DSYCL_CTS_EXCLUDE_TEST_CATEGORIES="$cts_exclude_filter" \
60+
-DSYCL_CTS_ENABLE_OPENCL_INTEROP_TESTS=OFF \
61+
-DDPCPP_INSTALL_DIR="$(dirname $(which clang++))/.." \
62+
$CMAKE_EXTRA_ARGS
63+
# Ignore errors so that if one category build fails others still have a
64+
# chance to finish and be executed at the run stage. Note that
65+
# "test_conformance" target skips building "test_all" executable.
66+
ninja -C build-cts -k0 $( [ -n "$CTS_TESTS_TO_BUILD" ] && echo "$CTS_TESTS_TO_BUILD" || echo "test_conformance")
67+
68+
- name: Pack SYCL-CTS binaries
69+
if: always() && !cancelled() && inputs.cts_testing_mode == 'build-only'
70+
shell: bash
71+
run: tar -I 'zstd -9' -cf sycl_cts_bin.tar.zst -C ./build-cts/bin .
72+
73+
- name: Upload SYCL-CTS binaries
74+
if: always() && !cancelled() && inputs.cts_testing_mode == 'build-only'
75+
uses: actions/upload-artifact@v4
76+
with:
77+
name: sycl_cts_bin
78+
path: sycl_cts_bin.tar.zst
79+
retention-days: ${{ inputs.retention-days }}
80+
81+
- name: Download SYCL-CTS binaries
82+
if: inputs.sycl_cts_artifact != ''
83+
uses: actions/download-artifact@v4
84+
with:
85+
name: ${{ inputs.sycl_cts_artifact }}
86+
87+
- name: Extract SYCL-CTS binaries
88+
if: inputs.sycl_cts_artifact != ''
89+
shell: bash
90+
run: |
91+
mkdir -p build-cts/bin
92+
tar -I 'zstd' -xf sycl_cts_bin.tar.zst -C build-cts/bin
93+
94+
- name: SYCL CTS List devices
95+
# Proceed with execution even if the 'build' step did not succeed.
96+
if: (always() && !cancelled()) && inputs.cts_testing_mode != 'build-only'
97+
shell: bash
98+
env:
99+
ONEAPI_DEVICE_SELECTOR: ${{ inputs.target_devices }}
100+
run: |
101+
./build-cts/bin/* --list-devices
102+
103+
# If the suite was built on another machine then the build contains the full
104+
# set of tests. We have special files to filter out some test categories,
105+
# see "devops/cts_exclude_filter_*". Each configuration has its own file, e.g.
106+
# there is "cts_exclude_filter_OCL_CPU" for opencl:cpu device. Therefore,
107+
# these files may differ from each other, so when there is a pre-built set of
108+
# tests, we need to filter it according to the filter-file.
109+
- name: Filter SYCL CTS test categories
110+
if: inputs.sycl_cts_artifact != ''
111+
shell: bash
112+
run: |
113+
cts_exclude_filter=""
114+
if [ "${{ contains(inputs.target_devices, 'opencl:cpu') }}" = "true" ]; then
115+
cts_exclude_filter=$PWD/devops/cts_exclude_filter_OCL_CPU
116+
elif [ "${{ contains(inputs.target_devices, 'level_zero:gpu') }}" = "true" ]; then
117+
cts_exclude_filter=$PWD/devops/cts_exclude_filter_L0_GPU
118+
fi
119+
120+
while IFS= read -r line; do
121+
if [[ $line != \#* ]]; then
122+
rm "./build-cts/bin/test_$line"
123+
fi
124+
done < "$cts_exclude_filter"
125+
126+
- name: Run SYCL CTS tests
127+
# Proceed with execution even if the previous two steps did not succeed.
128+
if: (always() && !cancelled()) && inputs.cts_testing_mode != 'build-only'
129+
env:
130+
ONEAPI_DEVICE_SELECTOR: ${{ inputs.target_devices }}
131+
# By-default GitHub actions execute the "run" shell script with -e option,
132+
# so the execution terminates if any command returns a non-zero status.
133+
# Since we're using a loop to run all test-binaries separately, some test
134+
# may fail and terminate the execution. Setting "shell" value to override
135+
# the default behavior.
136+
# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#custom-shell
137+
shell: bash {0}
138+
run: |
139+
# Run each test category separately so that
140+
# - crash on one would not affect others
141+
# - multiple tests could be run in parallel
142+
mkdir logs
143+
find build-cts/bin/ -type f -print | \
144+
xargs -t -I % -P 8 sh -c 'log=logs/$(basename %).log ; echo % >$log ; date >>$log ; timeout 60m % >>$log 2>&1 ; ret=$? ; echo "exit code: $ret" >>$log ; date >>$log ; exit $ret'
145+
ret=$?
146+
147+
for f in logs/* ; do
148+
echo "::group::$f"
149+
cat $f
150+
echo "::endgroup::"
151+
done
152+
153+
echo "::group::Fails:"
154+
grep 'exit code: [^0]' -r logs
155+
echo "::endgroup::"
156+
157+
grep 'exit code: [^0]' -r logs >> $GITHUB_STEP_SUMMARY
158+
159+
exit $ret

0 commit comments

Comments
 (0)