From b8d47b5acf70f50f97e2f65e680582a8e661ceb5 Mon Sep 17 00:00:00 2001 From: a-masterov <72613290+a-masterov@users.noreply.github.com> Date: Mon, 28 Apr 2025 10:13:49 +0200 Subject: [PATCH] Run the extensions' tests on staging (#11164) ## Problem We currently don't run end-to-end tests for PostgreSQL extensions on our cloud infrastructure, which means we might miss problems that only occur in a real cloud environment. ## Summary of changes - Added a workflow to run extension tests against a cloud staging instance - Set up proper project configuration for extension testing - Implemented test execution with appropriate environment settings - Added error handling and reporting for test failures --------- Co-authored-by: Alexander Bayandin Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- .../actions/neon-project-create/action.yml | 34 +- .github/workflows/cloud-extensions.yml | 112 +++++++ compute/compute-node.Dockerfile | 4 +- docker-compose/docker_compose_test.sh | 2 +- docker-compose/ext-src/README.md | 99 ++++++ .../ext-src/hll-src/regular-test.sh | 7 + .../ext-src/hypopg-src/regular-test.sh | 7 + .../ext-src/ip4r-src/regular-test.sh | 7 + .../ext-src/pg_cron-src/regular-test.sh | 7 + .../ext-src/pg_graphql-src/regular-test.sh | 23 ++ .../ext-src/pg_hint_plan-src/regular-test.sh | 7 + .../ext-src/pg_ivm-src/regular-test.sh | 9 + .../ext-src/pg_ivm-src/regular.patch | 309 ++++++++++++++++++ .../ext-src/pg_jsonschema-src/Makefile | 9 +- .../pg_roaringbitmap-src/regular-test.sh | 7 + .../ext-src/pg_semver-src/regular-test.sh | 12 + .../ext-src/pg_session_jwt-src/Makefile | 8 +- .../ext-src/pg_tiktoken-src/Makefile | 4 +- .../ext-src/pg_uuidv7-src/regular-test.sh | 7 + docker-compose/ext-src/pgjwt-src/neon-test.sh | 4 +- .../ext-src/pgrag-src/regular-test.sh | 8 + .../ext-src/pgtap-src/regular-test.sh | 10 + .../ext-src/pgvector-src/regular-test.sh | 8 + docker-compose/ext-src/pgx_ulid-src/Makefile | 14 +- .../ext-src/plv8-src/regular-test.sh | 12 + .../postgresql-unit-src/regular-test.sh | 7 + .../ext-src/prefix-src/regular-test.sh | 7 + .../ext-src/rag_bge_small_en_v15-src/Makefile | 9 +- .../rag_jina_reranker_v1_tiny_en-src/Makefile | 9 +- .../expected/reranking_functions.out | 36 +- .../expected/reranking_functions_enhanced.out | 104 +++--- .../sql/reranking_functions.sql | 10 +- .../sql/reranking_functions_enhanced.sql | 32 +- .../ext-src/rum-src/regular-test.sh | 7 + docker-compose/run-tests.sh | 44 +++ 35 files changed, 889 insertions(+), 106 deletions(-) create mode 100644 .github/workflows/cloud-extensions.yml create mode 100644 docker-compose/ext-src/README.md create mode 100755 docker-compose/ext-src/hll-src/regular-test.sh create mode 100755 docker-compose/ext-src/hypopg-src/regular-test.sh create mode 100755 docker-compose/ext-src/ip4r-src/regular-test.sh create mode 100755 docker-compose/ext-src/pg_cron-src/regular-test.sh create mode 100755 docker-compose/ext-src/pg_graphql-src/regular-test.sh create mode 100755 docker-compose/ext-src/pg_hint_plan-src/regular-test.sh create mode 100755 docker-compose/ext-src/pg_ivm-src/regular-test.sh create mode 100644 docker-compose/ext-src/pg_ivm-src/regular.patch create mode 100755 docker-compose/ext-src/pg_roaringbitmap-src/regular-test.sh create mode 100755 docker-compose/ext-src/pg_semver-src/regular-test.sh create mode 100755 docker-compose/ext-src/pg_uuidv7-src/regular-test.sh create mode 100755 docker-compose/ext-src/pgrag-src/regular-test.sh create mode 100755 docker-compose/ext-src/pgtap-src/regular-test.sh create mode 100755 docker-compose/ext-src/pgvector-src/regular-test.sh create mode 100755 docker-compose/ext-src/plv8-src/regular-test.sh create mode 100755 docker-compose/ext-src/postgresql-unit-src/regular-test.sh create mode 100755 docker-compose/ext-src/prefix-src/regular-test.sh create mode 100755 docker-compose/ext-src/rum-src/regular-test.sh mode change 100644 => 100755 docker-compose/run-tests.sh diff --git a/.github/actions/neon-project-create/action.yml b/.github/actions/neon-project-create/action.yml index a393aa6106..a5b4104908 100644 --- a/.github/actions/neon-project-create/action.yml +++ b/.github/actions/neon-project-create/action.yml @@ -49,6 +49,10 @@ inputs: description: 'A JSON object with project settings' required: false default: '{}' + default_endpoint_settings: + description: 'A JSON object with the default endpoint settings' + required: false + default: '{}' outputs: dsn: @@ -66,9 +70,9 @@ runs: # A shell without `set -x` to not to expose password/dsn in logs shell: bash -euo pipefail {0} run: | - project=$(curl \ + res=$(curl \ "https://${API_HOST}/api/v2/projects" \ - --fail \ + -w "%{http_code}" \ --header "Accept: application/json" \ --header "Content-Type: application/json" \ --header "Authorization: Bearer ${API_KEY}" \ @@ -83,6 +87,15 @@ runs: \"settings\": ${PROJECT_SETTINGS} } }") + + code=${res: -3} + if [[ ${code} -ge 400 ]]; then + echo Request failed with error code ${code} + echo ${res::-3} + exit 1 + else + project=${res::-3} + fi # Mask password echo "::add-mask::$(echo $project | jq --raw-output '.roles[] | select(.name != "web_access") | .password')" @@ -126,6 +139,22 @@ runs: -H "Accept: application/json" -H "Content-Type: application/json" -H "Authorization: Bearer ${ADMIN_API_KEY}" \ -d "{\"scheduling\": \"Essential\"}" fi + # XXX + # This is a workaround for the default endpoint settings, which currently do not allow some settings in the public API. + # https://github.com/neondatabase/cloud/issues/27108 + if [[ -n ${DEFAULT_ENDPOINT_SETTINGS} && ${DEFAULT_ENDPOINT_SETTINGS} != "{}" ]] ; then + PROJECT_DATA=$(curl -X GET \ + "https://${API_HOST}/regions/${REGION_ID}/api/v1/admin/projects/${project_id}" \ + -H "Accept: application/json" -H "Content-Type: application/json" -H "Authorization: Bearer ${ADMIN_API_KEY}" \ + -d "{\"scheduling\": \"Essential\"}" + ) + NEW_DEFAULT_ENDPOINT_SETTINGS=$(echo ${PROJECT_DATA} | jq -rc ".project.default_endpoint_settings + ${DEFAULT_ENDPOINT_SETTINGS}") + curl -X POST --fail \ + "https://${API_HOST}/regions/${REGION_ID}/api/v1/admin/projects/${project_id}/default_endpoint_settings" \ + -H "Accept: application/json" -H "Content-Type: application/json" -H "Authorization: Bearer ${ADMIN_API_KEY}" \ + --data "${NEW_DEFAULT_ENDPOINT_SETTINGS}" + fi + env: API_HOST: ${{ inputs.api_host }} @@ -142,3 +171,4 @@ runs: PSQL: ${{ inputs.psql_path }} LD_LIBRARY_PATH: ${{ inputs.libpq_lib_path }} PROJECT_SETTINGS: ${{ inputs.project_settings }} + DEFAULT_ENDPOINT_SETTINGS: ${{ inputs.default_endpoint_settings }} diff --git a/.github/workflows/cloud-extensions.yml b/.github/workflows/cloud-extensions.yml new file mode 100644 index 0000000000..7d60469f92 --- /dev/null +++ b/.github/workflows/cloud-extensions.yml @@ -0,0 +1,112 @@ +name: Cloud Extensions Test +on: + schedule: + # * is a special character in YAML so you have to quote this string + # ┌───────────── minute (0 - 59) + # │ ┌───────────── hour (0 - 23) + # │ │ ┌───────────── day of the month (1 - 31) + # │ │ │ ┌───────────── month (1 - 12 or JAN-DEC) + # │ │ │ │ ┌───────────── day of the week (0 - 6 or SUN-SAT) + - cron: '45 1 * * *' # run once a day, timezone is utc + workflow_dispatch: # adds ability to run this manually + inputs: + region_id: + description: 'Project region id. If not set, the default region will be used' + required: false + default: 'aws-us-east-2' + +defaults: + run: + shell: bash -euxo pipefail {0} + +permissions: + id-token: write # aws-actions/configure-aws-credentials + statuses: write + contents: write + +jobs: + regress: + env: + POSTGRES_DISTRIB_DIR: /tmp/neon/pg_install + TEST_OUTPUT: /tmp/test_output + BUILD_TYPE: remote + strategy: + fail-fast: false + matrix: + pg-version: [16, 17] + + runs-on: [ self-hosted, small ] + container: + # We use the neon-test-extensions image here as it contains the source code for the extensions. + image: ghcr.io/neondatabase/neon-test-extensions-v${{ matrix.pg-version }}:latest + credentials: + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + options: --init + + steps: + - name: Harden the runner (Audit all outbound calls) + uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0 + with: + egress-policy: audit + + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - name: Evaluate the settings + id: project-settings + run: | + if [[ $((${{ matrix.pg-version }})) -lt 17 ]]; then + ULID=ulid + else + ULID=pgx_ulid + fi + LIBS=timescaledb:rag_bge_small_en_v15,rag_jina_reranker_v1_tiny_en:$ULID + settings=$(jq -c -n --arg libs $LIBS '{preload_libraries:{use_defaults:false,enabled_libraries:($libs| split(":"))}}') + echo settings=$settings >> $GITHUB_OUTPUT + + - name: Create Neon Project + id: create-neon-project + uses: ./.github/actions/neon-project-create + with: + region_id: ${{ inputs.region_id }} + postgres_version: ${{ matrix.pg-version }} + project_settings: ${{ steps.project-settings.outputs.settings }} + # We need these settings to get the expected output results. + # We cannot use the environment variables e.g. PGTZ due to + # https://github.com/neondatabase/neon/issues/1287 + default_endpoint_settings: > + { + "pg_settings": { + "DateStyle": "Postgres,MDY", + "TimeZone": "America/Los_Angeles", + "compute_query_id": "off", + "neon.allow_unstable_extensions": "on" + } + } + api_key: ${{ secrets.NEON_STAGING_API_KEY }} + admin_api_key: ${{ secrets.NEON_STAGING_ADMIN_API_KEY }} + + - name: Run the regression tests + run: /run-tests.sh -r /ext-src + env: + BENCHMARK_CONNSTR: ${{ steps.create-neon-project.outputs.dsn }} + SKIP: "pg_hint_plan-src,pg_repack-src,pg_cron-src,plpgsql_check-src" + + - name: Delete Neon Project + if: ${{ always() }} + uses: ./.github/actions/neon-project-delete + with: + project_id: ${{ steps.create-neon-project.outputs.project_id }} + api_key: ${{ secrets.NEON_STAGING_API_KEY }} + + - name: Post to a Slack channel + if: ${{ github.event.schedule && failure() }} + uses: slackapi/slack-github-action@fcfb566f8b0aab22203f066d80ca1d7e4b5d05b3 # v1.27.1 + with: + channel-id: ${{ vars.SLACK_ON_CALL_QA_STAGING_STREAM }} + slack-message: | + Periodic extensions test on staging: ${{ job.status }} + <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|GitHub Run> + env: + SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} + diff --git a/compute/compute-node.Dockerfile b/compute/compute-node.Dockerfile index d8db627521..b9299eee90 100644 --- a/compute/compute-node.Dockerfile +++ b/compute/compute-node.Dockerfile @@ -1800,8 +1800,8 @@ COPY compute/patches/pg_repack.patch /ext-src RUN cd /ext-src/pg_repack-src && patch -p1