From: Tom Hromatka Date: Tue, 8 Apr 2025 22:42:23 +0000 (-0600) Subject: github: dist: Rework the automated functional tests X-Git-Tag: v3.2.0~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8785d6e68bbb2e395ba51a97af79908d9a23b9e9;p=thirdparty%2Flibcgroup.git github: dist: Rework the automated functional tests Now that Github Actions don't support cgroup v1, we can make the github runners run the tests in a more granular fashion. Add a runner to individually run the containerized tests, the non-containerized tests, and the sudo tests. This simplifies the testing logic, and should help us better identify failures. As part of this, no longer run ftests-wrapper.sh when `make check` is invoked on the ftests directory. This is an undue burden for distros as it requires uncommon dependencies (lxc, etc.) and can adversely affect the cgroup sysfs filesystem on the build system. The onus is on upstream libcgroup to provide a well-tested and vetted *.tar.gz for the distros that they can then just package up and disseminate. They shouldn't have to deal with challenging tests and test configurations. Signed-off-by: Tom Hromatka Signed-off-by: Kamalesh Babulal --- diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 875e1401..c93960a4 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -94,7 +94,7 @@ jobs: publish_dir: ./doc/html publish_branch: doxygen/${{ github.ref_name }} - unittests: + unit-tests: name: Unit Tests runs-on: ubuntu-latest @@ -128,6 +128,99 @@ jobs: name: Unit Test Code Coverage path: lcov.* + container-tests: + name: Container Tests + runs-on: ubuntu-22.04 + + steps: + - uses: actions/checkout@v4 + with: + submodules: false + - name: Initialize the directory + uses: ./.github/actions/setup-libcgroup + - name: Run container tests + run: | + pushd tests/ftests + ./ftests-container.sh + popd + - name: Collate code coverage results + uses: ./.github/actions/code-coverage + - name: Upload code coverage results + uses: coverallsapp/github-action@master + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + path-to-lcov: ./lcov.total + flag-name: "Container Tests" + parallel: True + - name: Archive code coverage results + if: ${{ always() }} + uses: actions/upload-artifact@v4 + with: + name: Container Tests Code Coverage + path: lcov.* + + nocontainer-tests: + name: No Container Tests + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + with: + submodules: false + - name: Initialize the directory + uses: ./.github/actions/setup-libcgroup + - name: Run container tests + run: | + pushd tests/ftests + ./ftests-nocontainer.sh + popd + - name: Collate code coverage results + uses: ./.github/actions/code-coverage + - name: Upload code coverage results + uses: coverallsapp/github-action@master + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + path-to-lcov: ./lcov.total + flag-name: "No Container Tests" + parallel: True + - name: Archive code coverage results + if: ${{ always() }} + uses: actions/upload-artifact@v4 + with: + name: No Container Tests Code Coverage + path: lcov.* + + sudo-tests: + name: Sudo Tests + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + with: + submodules: false + - name: Initialize the directory + uses: ./.github/actions/setup-libcgroup + - name: Run sudo tests + run: | + pushd tests/ftests + ./ftests-sudo.sh + popd + - name: Collate code coverage results + uses: ./.github/actions/code-coverage + - name: Upload code coverage results + uses: coverallsapp/github-action@master + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + path-to-lcov: ./lcov.total + flag-name: "Sudo Tests" + parallel: True + - name: Archive code coverage results + if: ${{ always() }} + uses: actions/upload-artifact@v4 + with: + name: Sudo Tests Code Coverage + path: lcov.* + distcheckv2: name: Cgroup v2 Dist Check runs-on: ubuntu-22.04 @@ -223,8 +316,9 @@ jobs: export PYTHONPATH=$PYTHONPATH:$(pwd) popd pushd tests/ftests - ./ftests.py -l 10 -L ftests.log - ./ftests.py -l 10 -L ftests-nocontainer.log --skip 38,77,80,81 --no-container + ./ftests.py -l 10 -L ftests.log --skip 80 + ./ftests.py -l 10 -L ftests-nocontainer.log --skip 38,72,73,77,80,81,82 \ + --no-container popd - name: Archive test logs if: ${{ always() }} @@ -248,55 +342,10 @@ jobs: name: No systemd Code Coverage path: lcov.* - functionaltestsv2: - name: Cgroup v2 Functional Tests - runs-on: ubuntu-22.04 - - steps: - - name: Install container dependencies - run: | - sudo apt-get update - sudo apt-get install lxc lxd-installer - - uses: actions/checkout@v4 - with: - submodules: false - - name: Initialize the directory - uses: ./.github/actions/setup-libcgroup - - name: Run functional tests - run: | - pushd src/python/build/lib.* - export PYTHONPATH=$PYTHONPATH:$(pwd) - popd - pushd tests/ftests - ./ftests.py -l 10 -L ftests.log - ./ftests.py -l 10 -L ftests-nocontainer.log --no-container - popd - - name: Archive test logs - if: ${{ always() }} - uses: actions/upload-artifact@v4 - with: - name: Cgroup v2 test logs - path: ./*.log - - name: Collate code coverage results - uses: ./.github/actions/code-coverage - - name: Upload code coverage results - uses: coverallsapp/github-action@master - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - path-to-lcov: ./lcov.total - flag-name: "Cgroup v2 Functional Tests" - parallel: True - - name: Archive code coverage results - if: ${{ always() }} - uses: actions/upload-artifact@v4 - with: - name: Cgroup v2 Code Coverage - path: lcov.* - finalize: name: Finalize the test run if: ${{ always() }} - needs: [unittests, functionaltestsv2, nosystemd] + needs: [unit-tests, container-tests, nocontainer-tests, sudo-tests, nosystemd] runs-on: ubuntu-latest steps: - name: Finalize code coverage results diff --git a/tests/ftests/084-sudo-cgcreate_systemd_scope_pid.py b/tests/ftests/084-sudo-cgcreate_systemd_scope_pid.py index 82938669..5475989c 100755 --- a/tests/ftests/084-sudo-cgcreate_systemd_scope_pid.py +++ b/tests/ftests/084-sudo-cgcreate_systemd_scope_pid.py @@ -59,7 +59,7 @@ def test(config): Cgroup.create_and_validate(config, CONTROLLERS, CGNAME1, create_scope=True, scope_pid=1000000) except RunError as re: - if 'Process with ID 1000000 does not exist' not in str(re): + if 'Failed to set unit properties: No such process' not in str(re): raise re # diff --git a/tests/ftests/Makefile.am b/tests/ftests/Makefile.am index e38d641b..672e152d 100644 --- a/tests/ftests/Makefile.am +++ b/tests/ftests/Makefile.am @@ -2,11 +2,11 @@ # # libcgroup functional tests Makefile.am # -# Copyright (c) 2019-2021 Oracle and/or its affiliates. +# Copyright (c) 2019-2025 Oracle and/or its affiliates. # Author: Tom Hromatka # -TESTS = ftests-wrapper.sh +TESTS = EXTRA_DIST_PYTHON_UTILS = \ cgroup.py \ @@ -113,8 +113,12 @@ EXTRA_DIST_PYTHON_TESTS = \ # Intentionally omit the stress test from the extra dist # 999-stress-cgroup_init.py -EXTRA_DIST = README.md ftests-wrapper.sh \ - ${EXTRA_DIST_PYTHON_UTILS} ${EXTRA_DIST_PYTHON_TESTS} +EXTRA_DIST = README.md \ + ftests-container.sh \ + ftests-nocontainer.sh \ + ftests-sudo.sh \ + ${EXTRA_DIST_PYTHON_UTILS} \ + ${EXTRA_DIST_PYTHON_TESTS} clean-local: clean-local-check .PHONY: clean-local-check diff --git a/tests/ftests/ftests-container.sh b/tests/ftests/ftests-container.sh new file mode 100755 index 00000000..f1c463db --- /dev/null +++ b/tests/ftests/ftests-container.sh @@ -0,0 +1,45 @@ +#!/bin/bash +# SPDX-License-Identifier: LGPL-2.1-only + +AUTOMAKE_SKIPPED=77 +AUTOMAKE_HARD_ERROR=99 + +START_DIR=$PWD +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) + +if [ "$START_DIR" != "$SCRIPT_DIR" ]; then + cp "$SCRIPT_DIR"/*.py "$START_DIR" +fi + +PYTHON_LIBRARY_PATH=(../../src/python/build/lib*) +if [ -d "${PYTHON_LIBRARY_PATH[0]}" ]; then + pushd "${PYTHON_LIBRARY_PATH[0]}" || exit $AUTOMAKE_HARD_ERROR + PYTHONPATH="$PYTHONPATH:$(pwd)" + export PYTHONPATH + popd || exit $AUTOMAKE_HARD_ERROR +fi + +./ftests.py -l 10 -L "$START_DIR/ftests-container.py.log" -n Libcg"$RANDOM" +RET=$? + +if [ "$START_DIR" != "$SCRIPT_DIR" ]; then + rm -f "$START_DIR"/*.py + rm -fr "$START_DIR"/__pycache__ + rm -f ftests-container.py.log +fi + +if [[ $RET -ne $AUTOMAKE_SKIPPED ]] && [[ $RET -ne 0 ]]; then + # always return errors from the first test run + exit $RET +fi + +if [[ $RET -eq 0 ]]; then + exit 0 +fi + +if [[ $RET -eq $AUTOMAKE_SKIPPED ]]; then + exit $AUTOMAKE_SKIPPED +fi + +# I don't think we should ever get here, but better safe than sorry +exit $AUTOMAKE_HARD_ERROR diff --git a/tests/ftests/ftests-nocontainer.sh b/tests/ftests/ftests-nocontainer.sh new file mode 100755 index 00000000..e359998e --- /dev/null +++ b/tests/ftests/ftests-nocontainer.sh @@ -0,0 +1,45 @@ +#!/bin/bash +# SPDX-License-Identifier: LGPL-2.1-only + +AUTOMAKE_SKIPPED=77 +AUTOMAKE_HARD_ERROR=99 + +START_DIR=$PWD +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) + +if [ "$START_DIR" != "$SCRIPT_DIR" ]; then + cp "$SCRIPT_DIR"/*.py "$START_DIR" +fi + +PYTHON_LIBRARY_PATH=(../../src/python/build/lib*) +if [ -d "${PYTHON_LIBRARY_PATH[0]}" ]; then + pushd "${PYTHON_LIBRARY_PATH[0]}" || exit $AUTOMAKE_HARD_ERROR + PYTHONPATH="$PYTHONPATH:$(pwd)" + export PYTHONPATH + popd || exit $AUTOMAKE_HARD_ERROR +fi + +./ftests.py -l 10 -L "$START_DIR/ftests-nocontainer.py.log" --no-container +RET=$? + +if [ "$START_DIR" != "$SCRIPT_DIR" ]; then + rm -f "$START_DIR"/*.py + rm -fr "$START_DIR"/__pycache__ + rm -f ftests-nocontainer.py.log +fi + +if [[ $RET -ne $AUTOMAKE_SKIPPED ]] && [[ $RET -ne 0 ]]; then + # always return errors from the first test run + exit $RET +fi + +if [[ $RET -eq 0 ]]; then + exit 0 +fi + +if [[ $RET -eq $AUTOMAKE_SKIPPED ]]; then + exit $AUTOMAKE_SKIPPED +fi + +# I don't think we should ever get here, but better safe than sorry +exit $AUTOMAKE_HARD_ERROR diff --git a/tests/ftests/ftests-wrapper.sh b/tests/ftests/ftests-sudo.sh similarity index 53% rename from tests/ftests/ftests-wrapper.sh rename to tests/ftests/ftests-sudo.sh index c62e9e1f..af31457a 100755 --- a/tests/ftests/ftests-wrapper.sh +++ b/tests/ftests/ftests-sudo.sh @@ -19,13 +19,6 @@ if [ -d "${PYTHON_LIBRARY_PATH[0]}" ]; then popd || exit $AUTOMAKE_HARD_ERROR fi -./ftests.py -l 10 -L "$START_DIR/ftests.py.log" -n Libcg"$RANDOM" -RET1=$? - -./ftests.py -l 10 -L "$START_DIR/ftests-nocontainer.py.log" --no-container \ - -n Libcg"$RANDOM" -RET2=$? - if [ -z "$srcdir" ]; then # $srcdir is set by automake but will likely be empty when run by hand and # that's fine @@ -35,38 +28,29 @@ else fi sudo cp "$srcdir../../src/libcgroup_systemd_idle_thread" /bin -sudo PYTHONPATH="$PYTHONPATH" ./ftests.py -l 10 -s "sudo" \ - -L "$START_DIR/ftests-nocontainer.py.sudo.log" --no-container -n Libcg"$RANDOM" -RET3=$? + +sudo PYTHONPATH="$PYTHONPATH" ./ftests.py -l 10 -L "$START_DIR/ftests-sudo.py.log" \ + -s "sudo" --no-container +RET=$? + sudo rm /bin/libcgroup_systemd_idle_thread if [ "$START_DIR" != "$SCRIPT_DIR" ]; then rm -f "$START_DIR"/*.py rm -fr "$START_DIR"/__pycache__ - rm -f ftests.py.log - rm -f ftests-nocontainer.py.log - rm -f ftests-nocontainer.py.sudo.log + rm -f ftests-sudo.py.log fi -if [[ $RET1 -ne $AUTOMAKE_SKIPPED ]] && [[ $RET1 -ne 0 ]]; then +if [[ $RET -ne $AUTOMAKE_SKIPPED ]] && [[ $RET -ne 0 ]]; then # always return errors from the first test run - exit $RET1 -fi -if [[ $RET2 -ne $AUTOMAKE_SKIPPED ]] && [[ $RET2 -ne 0 ]]; then - # return errors from the second test run - exit $RET2 -fi -if [[ $RET3 -ne $AUTOMAKE_SKIPPED ]] && [[ $RET3 -ne 0 ]]; then - # return errors from the third test run - exit $RET3 + exit $RET fi -if [[ $RET1 -eq 0 ]] || [[ $RET2 -eq 0 ]] || [[ $RET3 -eq 0 ]]; then +if [[ $RET -eq 0 ]]; then exit 0 fi -if [[ $RET1 -eq $AUTOMAKE_SKIPPED ]] || [[ $RET2 -eq $AUTOMAKE_SKIPPED ]] || - [[ $RET3 -eq $AUTOMAKE_SKIPPED ]]; then +if [[ $RET -eq $AUTOMAKE_SKIPPED ]]; then exit $AUTOMAKE_SKIPPED fi