123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345 |
- name: build-and-test
- description: Build YDB and run Tests
- inputs:
- log_suffix:
- required: true
- type: string
- test_label_regexp:
- required: false
- type: string
- aws_key_id:
- required: true
- type: string
- aws_key_value:
- required: true
- type: string
- testman_token:
- required: false
- type: string
- testman_url:
- required: false
- type: string
- testman_project_id:
- required: false
- type: string
- aws_bucket:
- required: true
- type: string
- aws_endpoint:
- required: true
- type: string
- run_unit_tests:
- required: true
- type: string
- run_functional_tests:
- required: true
- type: string
- runs:
- using: "composite"
- steps:
- - name: Init
- id: init
- shell: bash
- run: |
- rm -rf artifacts tmp test_reports
- mkdir -p artifacts tmp/pytest test_reports/pytest
- echo "WORKDIR=$(pwd)" >> $GITHUB_ENV
- echo "TESTREPDIR=$(pwd)/test_reports" >> $GITHUB_ENV
- echo "TMPDIR=$(pwd)/tmp" >> $GITHUB_ENV
- echo "PYTESTREPDIR=$(pwd)/test_reports/pytest/" >> $GITHUB_ENV
- echo "TESTMO_TOKEN=${{inputs.testman_token}}" >> $GITHUB_ENV
- echo "TESTMO_URL=${{inputs.testman_url}}" >> $GITHUB_ENV
- echo "ARTIFACTS_DIR=$(pwd)/artifacts" >> $GITHUB_ENV
- echo "SUMMARY_LINKS=$(mktemp)" >> $GITHUB_ENV
- echo "logfilename=${{inputs.log_suffix}}-ctest-stdout.gz" >> $GITHUB_OUTPUT
- echo "testfilterfile=$(pwd)/.github/config/muted_test.txt" >> $GITHUB_OUTPUT
- echo "testshardfilterfile=$(pwd)/.github/config/muted_shard.txt" >> $GITHUB_OUTPUT
- echo "functestfilterfile=$(pwd)/.github/config/muted_functest.txt" >> $GITHUB_OUTPUT
- echo "pytest-logfilename=${{inputs.log_suffix}}-pytest-stdout.log" >> $GITHUB_OUTPUT
- echo "PORT_SYNC_PATH=$(mktemp -d -p $(pwd)/tmp port-sync-XXXXXX)" >> $GITHUB_ENV
- - name: configure s3cmd
- shell: bash
- run: |
- cat <<EOF > $TMPDIR/s3cfg
- [default]
- access_key = ${aws_key_id}
- secret_key = ${aws_secret_access_key}
- bucket_location = ru-central1
- host_base = storage.yandexcloud.net
- host_bucket = %(bucket)s.storage.yandexcloud.net
- EOF
- echo "S3CMD_CONFIG=$TMPDIR/s3cfg" >> $GITHUB_ENV
- echo "S3_BUCKET_PATH=s3://${{ inputs.aws_bucket }}/${{ github.repository }}/${{github.workflow}}/${{ github.run_id }}/${{inputs.log_suffix}}/" >> $GITHUB_ENV
- echo "S3_URL_PREFIX=${{inputs.aws_endpoint}}/${{inputs.aws_bucket}}/${{ github.repository }}/${{github.workflow}}/${{github.run_id}}/${{inputs.log_suffix}}" >> $GITHUB_ENV
- env:
- aws_key_id: ${{inputs.AWS_KEY_ID }}
- aws_secret_access_key: ${{inputs.AWS_KEY_VALUE}}
- - name: Install Node required for Testmo CLI
- uses: actions/setup-node@v3
- with:
- node-version: 19
- - name: Install Testmo CLI
- shell: bash
- run: npm install -g @testmo/testmo-cli
- - name: Test history run create
- id: th
- if: inputs.testman_token
- shell: bash
- env:
- PR_NUMBER: ${{ github.event.number }}
- run: |
- RUN_URL="$GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID"
- BRANCH_TAG="$GITHUB_REF_NAME"
- ARCH="${{ runner.arch == 'X64' && 'x86-64' || runner.arch == 'ARM64' && 'arm64' || 'unknown' }}"
- LOG_SUFFIX="${{ inputs.log_suffix }}"
- TESTMO_SOURCE="cmake-${ARCH}"
- if [ ! -z "${LOG_SUFFIX}" ]; then
- TESTMO_SOURCE="${TESTMO_SOURCE}-${LOG_SUFFIX/_/-}"
- fi
- case $GITHUB_EVENT_NAME in
- workflow_dispatch)
- TESTMO_RUN_NAME="${{ github.run_id }} manual"
- EXTRA_TAG="manual"
- ;;
- pull_request | pull_request_target)
- TESTMO_RUN_NAME="${{ github.run_id }} PR #${PR_NUMBER}"
- EXTRA_TAG="pr"
- BRANCH_TAG=""
- ;;
- schedule)
- TESTMO_RUN_NAME="${{ github.run_id }} schedule"
- EXTRA_TAG="schedule"
- ;;
- *)
- TESTMO_RUN_NAME="${{ github.run_id }}"
- EXTRA_TAG=""
- ;;
- esac
- testmo automation:resources:add-link --name build --url $RUN_URL --resources testmo.json
- testmo automation:resources:add-field --name git-sha --type string --value ${GITHUB_SHA:0:7} --resources testmo.json
-
- RUN_ID=$(
- testmo automation:run:create --instance "$TESTMO_URL" --project-id ${{inputs.testman_project_id}} \
- --name "$TESTMO_RUN_NAME" --source "$TESTMO_SOURCE" --resources testmo.json \
- --tags "$BRANCH_TAG" --tags "$EXTRA_TAG"
- )
- echo "runid=${RUN_ID}" >> $GITHUB_OUTPUT
- echo "TEST_HISTORY_URL=${TESTMO_URL}/automation/runs/view/${RUN_ID}" >> $GITHUB_ENV
- - name: Print test history link
- shell: bash
- run: |
- echo "10 [Test history](${TEST_HISTORY_URL})" >> $SUMMARY_LINKS
- - name: set environment variables required by some tests
- shell: bash
- run: |
- echo "PSQL_BINARY=/usr/bin/psql" >> $GITHUB_ENV
- - name: Run unit tests
- id: ctest
- if: inputs.run_unit_tests == 'true'
- shell: bash
- run: |
- cd $WORKDIR/../build/ydb
- echo "20 [Unittest log]($S3_URL_PREFIX/${{steps.init.outputs.logfilename}})" >> $SUMMARY_LINKS
- # Sed removes coloring from the output
-
- GTEST_OUTPUT="xml:$TESTREPDIR/unittests/" Y_UNITTEST_OUTPUT="xml:$TESTREPDIR/unittests/" \
- ctest -j28 --timeout 1200 --force-new-ctest-process --output-on-failure \
- --output-junit $TESTREPDIR/suites/ctest_report.xml \
- -L '${{inputs.test_label_regexp}}' -E "${CTEST_SKIP_SHARDS:-}" | \
- sed -u -e 's/\x1b\[[0-9;]*m//g' | \
- tee >(gzip --stdout > $ARTIFACTS_DIR/${{steps.init.outputs.logfilename}}) | \
- grep --line-buffered -E '(Test\s*#.*\*\*\*|\[FAIL\])|.*tests passed,.*tests failed out of' | \
- tee $WORKDIR/short.log || (
- RC=$?
- if [ $RC == 8 ]; then
- echo "ctest returned TEST_ERRORS, recovering.."
- else
- exit $RC
- fi
- )
- - name: archive unitest reports (orig)
- if: inputs.run_unit_tests == 'true'
- shell: bash
- run: |
- tar -C $TESTREPDIR/ -czf $ARTIFACTS_DIR/xml_orig.tar.gz .
- - name: postprocess xml reports
- if: inputs.run_unit_tests == 'true'
- shell: bash
- run: |
- echo "::group::extract-logs"
- mkdir $ARTIFACTS_DIR/logs/
- .github/scripts/tests/attach-logs.py \
- --url-prefix $S3_URL_PREFIX/logs/ \
- --ctest-report $TESTREPDIR/suites/ctest_report.xml \
- --junit-reports-path $TESTREPDIR/unittests/ \
- --decompress \
- $ARTIFACTS_DIR/${{steps.init.outputs.logfilename}} \
- $ARTIFACTS_DIR/logs/
- echo "::endgroup::"
- echo "::group::junit-postprocess"
-
- .github/scripts/tests/junit-postprocess.py \
- --filter-file ${{steps.init.outputs.testfilterfile}} \
- $TESTREPDIR/unittests/
- echo "::endgroup::"
- echo "::group::ctest-postprocess"
- .github/scripts/tests/ctest-postprocess.py \
- --filter-file ${{steps.init.outputs.testshardfilterfile}} \
- --decompress \
- $ARTIFACTS_DIR/${{steps.init.outputs.logfilename}} \
- $TESTREPDIR/suites/ctest_report.xml
- tar -C $TESTREPDIR/ -czf $ARTIFACTS_DIR/reports.tar.gz .
- echo "90 [XML reports archive]($S3_URL_PREFIX/reports.tar.gz)" >> $SUMMARY_LINKS
- echo "::endgroup::"
- - name: sync test results to s3
- if: always() && inputs.run_unit_tests == 'true'
- shell: bash
- run: |
- echo "::group::s3-sync"
- s3cmd sync -P --no-progress --stats --no-check-md5 -P $ARTIFACTS_DIR/ $S3_BUCKET_PATH
- echo "::endgroup::"
- - name: Unit test history upload results
- if: always() && inputs.run_unit_tests == 'true' && inputs.testman_token
- shell: bash
- run: |
- testmo automation:run:submit-thread \
- --instance "$TESTMO_URL" --run-id ${{steps.th.outputs.runid}} \
- --results "$TESTREPDIR/unittests/*.xml"
- testmo automation:run:submit-thread \
- --exec-suppress \
- --instance "$TESTMO_URL" --run-id ${{steps.th.outputs.runid}} \
- --results "$TESTREPDIR/suites/*.xml" \
- -- cat $WORKDIR/short.log
- - name: Run functional tests
- if: inputs.run_functional_tests == 'true' && (success() || failure())
- shell: bash
- run: |
- export source_root=$WORKDIR
- export build_root=$WORKDIR/../build/
- echo "30 [Functional test log]($S3_URL_PREFIX/${{steps.init.outputs.pytest-logfilename}})" >> $SUMMARY_LINKS
- source $WORKDIR/ydb/tests/oss/launch/prepare.sh
-
- rm -rf $ARTIFACTS_DIR/pytest/
- mkdir $ARTIFACTS_DIR/pytest/
-
- cd $WORKDIR/ydb/tests/functional/
-
- pytest \
- -p xdist -n 24 --dist worksteal \
- --timeout_method signal \
- -o junit_logging=log -o junit_log_passing_tests=False --junit-xml=$PYTESTREPDIR/pytest.xml \
- -ra --tb=no --show-capture=no \
- --github-repo $GITHUB_REPOSITORY --github-ref $GITHUB_SHA \
- --source-root $source_root \
- --build-root $build_root \
- --output-dir $TMPDIR/pytest/ \
- . | tee $ARTIFACTS_DIR/${{steps.init.outputs.pytest-logfilename}} || {
- RC=$?
- if [ $RC == 1 ]; then
- echo "pytest: tests were collected and run but some of the tests failed"
- else
- exit $RC
- fi;
- }
- # --artifacts-dir $ARTIFACTS_DIR/pytest/ \
- # --artifacts-url $S3_URL_PREFIX/pytest/ \
- - name: postprocess functional test reports
- if: always() && inputs.run_functional_tests == 'true'
- shell: bash
- run: |
- echo "::group::junit-postprocess"
-
- # append orig pytest reports
- if [ -f "$ARTIFACTS_DIR/xml_orig.tar.gz" ]; then
- echo "add pytest to xml_orig.tar.gz"
- gzip -d $ARTIFACTS_DIR/xml_orig.tar.gz
- tar -C $TESTREPDIR/ -rvf $ARTIFACTS_DIR/xml_orig.tar pytest
- gzip -v $ARTIFACTS_DIR/xml_orig.tar
- fi
-
- .github/scripts/tests/pytest-postprocess.py \
- --filter-file ${{ steps.init.outputs.functestfilterfile }} \
- $PYTESTREPDIR/
- # make archive again with pytest reports
- tar -C $TESTREPDIR/ -czf $ARTIFACTS_DIR/reports.tar.gz .
- ls -la $ARTIFACTS_DIR/reports.tar.gz
- echo "::endgroup::"
- - name: Functional tests history upload results
- if: always() && inputs.run_functional_tests == 'true' && inputs.testman_token
- shell: bash
- run: |
- testmo automation:run:submit-thread \
- --instance "$TESTMO_URL" --run-id ${{steps.th.outputs.runid}} \
- --results "$PYTESTREPDIR/*.xml" \
- -- cat $ARTIFACTS_DIR/${{steps.init.outputs.pytest-logfilename}}
- - name: Test history run complete
- if: always() && inputs.testman_token
- shell: bash
- run: |
- testmo automation:run:complete --instance "$TESTMO_URL" --run-id ${{steps.th.outputs.runid}}
- - name: write tests summary
- if: always()
- shell: bash
- env:
- GITHUB_TOKEN: ${{ github.token }}
- run: |
-
- cat $SUMMARY_LINKS | python3 -c 'import sys; print(" | ".join([v for _, v in sorted([l.strip().split(" ", 1) for l in sys.stdin], key=lambda a: (int(a[0]), a))]))' >> $GITHUB_STEP_SUMMARY
-
- mkdir $ARTIFACTS_DIR/summary/
-
- .github/scripts/tests/generate-summary.py \
- --summary-out-path $ARTIFACTS_DIR/summary/ \
- --summary-url-prefix $S3_URL_PREFIX/summary/ \
- --test-history-url $TEST_HISTORY_URL \
- "Unittests" unittest.html $TESTREPDIR/unittests \
- "Unittest binary runs" ctest.html $TESTREPDIR/suites \
- "Functional tests" functional.html $PYTESTREPDIR
- - name: sync test results to s3
- if: always()
- shell: bash
- run: |
- echo "::group::s3-sync"
- s3cmd sync -P --no-progress --stats --no-check-md5 -P $ARTIFACTS_DIR/ $S3_BUCKET_PATH
- echo "::endgroup::"
- - name: finish
- shell: bash
- run: |
- .github/scripts/tests/fail-checker.py $TESTREPDIR/unittests/ $TESTREPDIR/suites/ $PYTESTREPDIR/
|