diff --git a/.github/workflows/code-coverage-test.yml b/.github/workflows/code-coverage-test.yml new file mode 100644 index 00000000000..804ef1d6b1b --- /dev/null +++ b/.github/workflows/code-coverage-test.yml @@ -0,0 +1,418 @@ +name: Code Coverage Test + +env: + # TODO: we really need to define a list of supported versions (ideally it's no more than 2) + # build is done on the lowest version and test on the highest with a "sanity test" + # stage done on all versions in the list except the highest + EL8_BUILD_VERSION: 8.6 + EL8_VERSION: 8.8 + EL9_BUILD_VERSION: 9 + EL9_VERSION: 9 + LEAP15_VERSION: 15.5 + + JENKINS_URL: https://build.hpdd.intel.com/ + +on: + pull_request: # Remove after testing + schedule: + - cron: "0 0 * * 6" # Every Saturday + +concurrency: + group: code-coverage-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +defaults: + run: + shell: bash --noprofile --norc -ueo pipefail {0} + +permissions: {} + +jobs: + + Build-RPM: + name: Bullseye Build RPM + permissions: + statuses: write + runs-on: [self-hosted, docker] + if: ((!cancelled()) || success() || failure()) + strategy: + matrix: + distro: ["el8"] + fail-fast: false + env: + ARTIFACTORY_URL: https://artifactory.dc.hpdd.intel.com/ + DAOS_EMAIL: phil.henderson@intel.com + DAOS_FULLNAME: daos-stack + DISTRO: ${{ matrix.distro }} + DISTRO_REPOS: disabled + # DOCKER_BUILDKIT: 0 + ARTIFACTS_URL: file:///scratch/job_repos/ + MOCK_OPTIONS: --uniqueext=${{ github.run_id }} + PR_NUM: ${{ github.event.pull_request.number }} + # TODO -- this should be on stable, backed up storage, not /scratch + # yamllint disable-line rule:line-length + REPO_PATH: /scratch/job_repos/daos-stack/job/daos/job/PR-${{ github.event.pull_request.number }}/ + REPO_FILE_URL: https://artifactory.dc.hpdd.intel.com/artifactory/repo-files/ + RUN_ID: ${{ github.run_id }} + TARGET: ${{ matrix.distro }} + # keep VS Code's GHA linting happy + STAGE_NAME: + DISTRO_NAME: + DISTRO_VERSION: + CP_LEAP15_VERSION: + COMMIT_STATUS_DISTRO_VERSION: + FVERSION: + steps: + # - name: Import commit pragmas + # uses: ./.github/actions/import-commit-pragmas + - name: Set variables + run: | + FVERSION="38" + case ${{ matrix.distro }} in + 'el8') + CHROOT_NAME="rocky+epel-8-x86_64" + DISTRO_NAME="EL" + DISTRO_VERSION="${{ env.EL8_BUILD_VERSION }}" + COMMIT_STATUS_DISTRO_VERSION="8" + ;; + 'el9') + CHROOT_NAME="rocky+epel-9-x86_64" + DISTRO_NAME="EL" + DISTRO_VERSION="${{ env.EL9_BUILD_VERSION }}" + ;; + 'leap15') + CHROOT_NAME="opensuse-leap-${{ env.CP_LEAP15_VERSION && + env.CP_LEAP15_VERSION || + env.LEAP15_VERSION }}-x86_64" + DISTRO_NAME="Leap" + DISTRO_VERSION="${{ env.CP_LEAP15_VERSION && + env.CP_LEAP15_VERSION || env.LEAP15_VERSION }}" + ;; + esac + echo "CHROOT_NAME=$CHROOT_NAME" >> $GITHUB_ENV + echo "DISTRO_NAME=$DISTRO_NAME" >> $GITHUB_ENV + echo "DISTRO_VERSION=$DISTRO_VERSION" >> $GITHUB_ENV + echo "BUILD_CHROOT=/var/lib/mock/$CHROOT_NAME-${{ github.run_id }}/" >> $GITHUB_ENV + echo "STAGE_NAME=Build RPM on $DISTRO_NAME $DISTRO_VERSION" >> $GITHUB_ENV + echo "FVERSION=$FVERSION" >> $GITHUB_ENV + echo "COMMIT_STATUS_DISTRO_VERSION=$COMMIT_STATUS_DISTRO_VERSION" >> $GITHUB_ENV + echo "COVFN_DISABLED=false" >> $GITHUB_ENV + echo "BULLSEYE=yes" >> $GITHUB_ENV + - name: Checkout code + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} + - name: Build RPM Docker image + id: build-rpm-docker-image + continue-on-error: true + run: docker build --file utils/rpms/packaging/Dockerfile.mockbuild + --build-arg CACHEBUST=$(date +%s%3N) + --build-arg CB0=$(date +%V) + --build-arg REPO_FILE_URL=$REPO_FILE_URL + --build-arg UID=$(id -u) + --build-arg FVERSION=${{ env.FVERSION }} + --build-arg JENKINS_URL=${{ env.JENKINS_URL }} + --build-arg BULLSEYE_KEY=${{ secrets.BULLSEYE_LICENSE_KEY }} + --tag mock-build + utils/rpms + - name: Build RPM + id: build-rpm + continue-on-error: true + # yamllint disable rule:line-length + run: rm -rf mock_result; + mkdir -p mock_result; + docker run --name mock-build-${{ github.run_id }}-${{ github.run_attempt }}-${{ matrix.distro }} + --user build + -v "$PWD":"$PWD" -w "$PWD" + -v "$PWD"/mock_result:/var/lib/mock/$CHROOT_NAME/result + --privileged=true + -e DAOS_FULLNAME="$DAOS_FULLNAME" + -e DAOS_EMAIL="$DAOS_EMAIL" + -e DISTRO_VERSION="$DISTRO_VERSION" + -e STAGE_NAME="$STAGE_NAME" + -e CHROOT_NAME="$CHROOT_NAME" + -e ARTIFACTORY_URL="$ARTIFACTORY_URL" + -e REPO_FILE_URL="$REPO_FILE_URL" + -e JENKINS_URL=${{ env.JENKINS_URL }} + -e TARGET="$TARGET" + -e COVFN_DISABLED="$COVFN_DISABLED" + mock-build ci/rpm/build.sh + # yamllint enable rule:line-length + - name: Build RPM failure log + id: build-rpm-fail-log + continue-on-error: true + if: steps.build-rpm.outcome != 'success' + run: cat mock_result/root.log; + cat mock_result/build.log + - name: Save RPM build logs + continue-on-error: true + uses: actions/upload-artifact@v4 + with: + name: ${{ env.STAGE_NAME }} logs + path: | + mock_result/root.log + mock_result/build.log + - name: Create lastBuild and lastSuccessfulBuild symlinks + if: steps.build-rpm.outcome == 'success' + run: . ci/gha_functions.sh; + mkdir -p ${REPO_PATH}; + rm -f ${REPO_PATH}last{,Successful}Build; + ln -s ${{ github.run_number }} ${REPO_PATH}lastBuild; + ln -s ${{ github.run_number }} ${REPO_PATH}lastSuccessfulBuild + - name: Create repo + id: create-repo + if: steps.build-rpm.outcome == 'success' + continue-on-error: true + run: CHROOT_NAME=$CHROOT_NAME ci/rpm/create_repo.sh + - name: Test repo + id: test-repo + if: steps.create-repo.outcome == 'success' + continue-on-error: true + run: . ci/gha_functions.sh; + dnf --disablerepo=\* --repofrompath + testrepo,file://${REPO_PATH}${{ github.run_number }}/artifact/artifacts/$TARGET + repoquery -a + - name: Remove lastSuccessfulBuild link and exit failure + if: steps.test-repo.outcome != 'success' + run: rm -f ${REPO_PATH}lastSuccessfulBuild; + exit 1 + - name: Publish RPMs + uses: actions/upload-artifact@v4 + with: + name: ${{ env.DISTRO_NAME }} ${{ env.DISTRO_VERSION }} RPM repository + path: ${{ env.REPO_PATH}}${{ github.run_number }}/artifact/artifacts/${{ env.TARGET }} + - name: Update commit status + uses: ouzi-dev/commit-status-updater@v2 + with: + # yamllint disable-line rule:line-length + name: 'build/Build RPM on ${{ env.DISTRO_NAME }} ${{ env.COMMIT_STATUS_DISTRO_VERSION && env.COMMIT_STATUS_DISTRO_VERSION || env.DISTRO_VERSION }}' + status: "${{ job.status }}" + + # Unit-Test: + # name: Bullseye Unit Test + # runs-on: [self-hosted, docker] + # steps: + # - name: Checkout code + # uses: actions/checkout@v4 + # with: + # submodules: true + # ref: ${{ github.event.pull_request.head.sha }} + # - name: Build deps in Docker + # run: docker build . --file utils/docker/Dockerfile.el.8 + # --build-arg DAOS_BUILD=no + # --build-arg DEPS_JOBS=50 + # - name: Build daos in Docker + # run: docker build . --file utils/docker/Dockerfile.el.8 + # --build-arg DEPS_JOBS=50 + # --build-arg DAOS_KEEP_SRC=yes + # --build-arg DAOS_TARGET_TYPE=debug + # --build-arg DAOS_JAVA_BUILD=yes + # --build-arg JENKINS_URL=${{ env.JENKINS_URL }} + # --build-arg BULLSEYE=${{ secrets.BULLSEYE_LICENSE_KEY }} + # --tag build-image-${{github.run_id}}-${{github.run_attempt}} + # - name: Run Unit Testing + # run: docker exec -t build-image-${{github.run_id}}-${{github.run_attempt}} + # sh -c "ls -al"; + # docker run --name unit-test-${{github.run_id}}-${{github.run_attempt}} + # -e STAGE_NAME="Unit Test Bullseye" + # -e BULLSEYE=${{ secrets.BULLSEYE_LICENSE_KEY }} + # build-image-${{github.run_id}}-${{github.run_attempt}} + # ci/unit/test_main_node.sh + # - name: Fetch test results + # run: docker cp unit-test-${{github.run_id}}-${{github.run_attempt}}:/covc_test_logs + # ./artifacts; + # docker cp unit-test-${{github.run_id}}-${{github.run_attempt}}:/covc_vm_test + # ./artifacts + # - name: Upload test results + # uses: actions/upload-artifact@v4 + # with: + # name: Bullseye Unit Testing test-results + # path: ./artifacts/ + + Functional-Test: + name: Bullseye Functional Test + runs-on: [self-hosted, wolf] + permissions: + statuses: write + # https://github.com/EnricoMi/publish-unit-test-result-action#permissions + checks: write + pull-requests: write + timeout-minutes: 7200 + needs: [Build-RPM] + strategy: + matrix: + distro: ["el8"] + fail-fast: false + # https://github.com/actions/runner/issues/491#issuecomment-926924523 + if: | + (!cancelled()) && + (needs.Build-RPM.result == 'success' || + needs.Build-RPM.result == 'skipped') + env: + CONFIG_POWER_ONLY: false + PRAGMA_SUFFIX: -vm + OPERATIONS_EMAIL: phil.henderson@intel.com + TEST_RPMS: true + COMMIT_MESSAGE: + JENKINS_URL: https://build.hpdd.intel.com/ + REPOSITORY_URL: https://repo.dc.hpdd.intel.com/ + REMOVE_EXISTING_RPMS: false + # TODO -- this should be on stable, backedup storage + ARTIFACTS_URL: file:///scratch/job_repos/ + REPO_FILE_URL: https://artifactory.dc.hpdd.intel.com/artifactory/repo-files/ + # keep VS Code's GHA linting happy + NODESTRING: + CP_PR_REPOS: + CP_FEATURES: + CP_TEST_TAG: + CP_EL8_VM9_LABEL: + CP_EL9_VM9_LABEL: + CP_LEAP15_VM9_LABEL: + CP_PRIORITY: + CP_EL8_VERSION: + CP_EL9_VERSION: + CP_LEAP15_VERSION: + DISTRO: + CLUSTER_REQUEST_reqid: + STAGE_NAME: + QUEUE_URL: + LABEL: + DISTRO_NAME: + DISTRO_VERSION: + COMMIT_STATUS_DISTRO_VERSION: + FTEST_ARG: + steps: + # - name: Import commit pragmas + # uses: ./.github/actions/import-commit-pragmas + - name: Set variables + run: | + set -eux + env + STAGE_TAGS="vm" + FTEST_ARG="--nvme=auto" + INST_RPMS="daos-client daos-tests daos-server daos-serialize daos-tests-internal" + case "${{ matrix.distro }}" in + 'el8') + CHROOT_NAME="rocky+epel-8-x86_64" + DISTRO_NAME="EL" + DISTRO_NAME_UPPER="EL" + DISTRO_NAME_LOWER="el" + DISTRO_VERSION="${{ env.CP_EL8_VERSION && + env.CP_EL8_VERSION || env.EL8_VERSION }}" + DISTRO_VERSION_MAJOR="8" + OPENMPI="openmpi" + LABEL="${{ env.CP_EL8_VM9_LABEL && + env.CP_EL8_VM9_LABEL || 'ci_vm9' }}" + ;; + 'el9') + CHROOT_NAME="rocky+epel-9-x86_64" + DISTRO_NAME="EL" + DISTRO_NAME_UPPER="EL" + DISTRO_NAME_LOWER="el" + DISTRO_VERSION="${{ env.CP_EL9_VERSION && + env.CP_EL9_VERSION || env.EL9_VERSION }}" + DISTRO_VERSION_MAJOR="9" + PROV_DISTRO_VERSION_MAJOR="8" + OPENMPI="openmpi" + LABEL="${{ env.CP_EL9_VM9_LABEL && + env.CP_EL9_VM9_LABEL || 'ci_vm9' }}" + ;; + 'leap15') + CHROOT_NAME="opensuse-leap-${{ env.CP_LEAP15_VERSION && + env.CP_LEAP15_VERSION || + env.LEAP15_VERSION }}-x86_64" + DISTRO_NAME="Leap" + DISTRO_NAME_UPPER="LEAP" + DISTRO_NAME_LOWER="leap" + DISTRO_VERSION="${{ env.CP_LEAP15_VERSION && + env.CP_LEAP15_VERSION || env.LEAP15_VERSION }}" + DISTRO_VERSION_MAJOR="15" + OPENMPI="openmpi3" + LABEL="${{ env.CP_LEAP15_VM9_LABEL && + env.CP_LEAP15_VM9_LABEL || 'ci_vm9' }}" + ;; + esac + echo "CHROOT_NAME=$CHROOT_NAME" >> $GITHUB_ENV + echo "DISTRO_NAME=$DISTRO_NAME" >> $GITHUB_ENV + echo "DISTRO_VERSION=$DISTRO_VERSION" >> $GITHUB_ENV + echo "DISTRO_WITH_VERSION=$DISTRO_NAME_LOWER$DISTRO_VERSION" >> $GITHUB_ENV + echo "BUILD_CHROOT=/var/lib/mock/$CHROOT_NAME-${{ github.run_id }}/" >> $GITHUB_ENV + echo "STAGE_NAME=Functional on $DISTRO_NAME $DISTRO_VERSION" >> $GITHUB_ENV + echo "STAGE_TAGS=$STAGE_TAGS" >> $GITHUB_ENV + echo "FTEST_ARG=$FTEST_ARG" >> $GITHUB_ENV + echo "DISTRO=${DISTRO_NAME_UPPER}_$DISTRO_VERSION_MAJOR" >> $GITHUB_ENV + echo -n "PROVISION_DISTRO=${DISTRO_NAME_UPPER}_" >> $GITHUB_ENV + echo "${PROV_DISTRO_VERSION_MAJOR:-$DISTRO_VERSION_MAJOR}" >> $GITHUB_ENV + echo -n "DAOS_STACK_${DISTRO_NAME_UPPER}_" >> $GITHUB_ENV + echo "${PROV_DISTRO_VERSION_MAJOR:-$DISTRO_VERSION_MAJOR}_LOCAL_REPO=not_used" >> \ + $GITHUB_ENV + echo "LABEL=$LABEL" >> $GITHUB_ENV + echo "INST_RPMS=$INST_RPMS" >> $GITHUB_ENV + - name: Checkout code + uses: actions/checkout@v4 + with: + submodules: true + fetch-depth: 500 + ref: ${{ github.event.pull_request.head.sha }} + - name: Request and Provision a Cluster + timeout-minutes: 7200 + uses: ./.github/actions/provision-cluster + with: + condition: env.CP_SKIP_FUNC_TEST-${{ env.DISTRO }} != 'true' && \ + env.CP_SKIP_FUNC_TEST != 'true' + - name: Run Test + timeout-minutes: 7200 + if: env.CP_SKIP_FUNC_TEST-${{ env.DISTRO }} != 'true' && env.CP_SKIP_FUNC_TEST != 'true' + id: run-test + run: | + . ci/gha_functions.sh + NODE_COUNT="$NODE_COUNT" \ + TEST_TAG="pr,vm" \ + FTEST_ARG="${{ env.FTEST_ARG }}" ci/functional/test_main.sh + - name: Cancel cluster request (if cancelled after requesting) + if: cancelled() + run: | + set -eux + . ci/gha_functions.sh + if ! JENKINS_URL="${{ env.JENKINS_URL }}" QUEUE_URL="${{ env.QUEUE_URL }}" \ + cancel_provision; then + # probably already provisioned and needs unprovisioning + if ! cleanup_provision_request "${{ env.CLUSTER_REQUEST_reqid }}"; then + exit 1 + fi + fi + - name: Job cleanup + if: (!cancelled() && (success() || failure())) + run: | + set -eux + . ci/gha_functions.sh + NODELIST=${{ env.NODESTRING }} ci/functional/job_cleanup.sh || true + cleanup_provision_request "${{ env.CLUSTER_REQUEST_reqid }}" + - name: Publish test results + if: (!cancelled()) && (success() || failure()) && + steps.run-test.outcome != 'skipped' + uses: EnricoMi/publish-unit-test-result-action@v2 + with: + check_name: ${{ env.STAGE_NAME }} Test Results (old) + github_token: ${{ secrets.GITHUB_TOKEN }} + junit_files: ${{ env.STAGE_NAME }}/**/results.xml + - name: Publish artifacts + if: (!cancelled()) && (success() || failure()) && + steps.run-test.outcome != 'skipped' + uses: actions/upload-artifact@v4 + with: + name: ${{ env.STAGE_NAME }} artifacts + path: ${{ env.STAGE_NAME }}/** + - name: Upload test results + if: (success() || failure()) && + steps.run-test.outcome != 'skipped' + uses: actions/upload-artifact@v4 + with: + name: ${{ env.STAGE_NAME }} test-results + path: ${{ env.STAGE_NAME }}/**/results.xml + - name: Update commit status + uses: ouzi-dev/commit-status-updater@v2 + with: + # yamllint disable-line rule:line-length + name: 'test/Functional on ${{ env.DISTRO_NAME }} ${{ env.COMMIT_STATUS_DISTRO_VERSION && env.COMMIT_STATUS_DISTRO_VERSION || env.DISTRO_VERSION }}' + status: "${{ job.status }}"