Skip to content

Commit fb57f89

Browse files
committed
commit
1 parent 00a877a commit fb57f89

10 files changed

Lines changed: 724 additions & 0 deletions

File tree

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
name: Test Latest Citus Package Installation on Supported PostgreSQL Versions
2+
3+
on:
4+
workflow_dispatch:
5+
6+
env:
7+
# Branch whose build-package.yml, postgres-matrix.yml and pkgvars files are the source of truth
8+
SOURCE_BRANCH: "all-citus"
9+
10+
jobs:
11+
discover:
12+
name: Discover platforms & versions
13+
runs-on: ubuntu-latest
14+
outputs:
15+
matrix: ${{ steps.build_matrix.outputs.matrix }}
16+
citus_version: ${{ steps.resolve_versions.outputs.citus_version }}
17+
steps:
18+
- name: Checkout repository
19+
uses: actions/checkout@v4
20+
21+
- name: Fetch source branch
22+
run: git fetch origin "${SOURCE_BRANCH}" --depth=1
23+
24+
- name: Extract platform list
25+
id: extract_platforms
26+
run: |
27+
git show "origin/${SOURCE_BRANCH}:.github/workflows/build-package.yml" \
28+
> /tmp/build-package.yml
29+
30+
platforms=$(
31+
yq -o=json '.jobs.build_package.strategy.matrix.platform' /tmp/build-package.yml \
32+
| jq -c '.'
33+
)
34+
35+
echo "Discovered platforms: ${platforms}"
36+
echo "platforms=${platforms}" >> "$GITHUB_OUTPUT"
37+
38+
- name: Resolve Citus & PG versions
39+
id: resolve_versions
40+
run: |
41+
git show "origin/${SOURCE_BRANCH}:pkgvars" > /tmp/pkgvars
42+
git show "origin/${SOURCE_BRANCH}:postgres-matrix.yml" > /tmp/postgres-matrix.yml
43+
44+
# Extract version from pkglatest (e.g. "14.0.0.citus-1" -> "14.0.0")
45+
citus_version=$(grep '^pkglatest=' /tmp/pkgvars | sed 's/^pkglatest=//;s/\.citus-.*//')
46+
47+
# postgres-matrix.yml keys use major.minor (e.g. "14.0"), strip patch
48+
citus_major_minor=$(echo "${citus_version}" | cut -d. -f1,2)
49+
50+
pg_versions=$(
51+
yq -o=json \
52+
".version_matrix[-1].\"${citus_major_minor}\".postgres_versions" \
53+
/tmp/postgres-matrix.yml \
54+
| jq -c '[.[] | tostring]'
55+
)
56+
57+
echo "Latest Citus version: ${citus_version}"
58+
echo "Supported PG versions: ${pg_versions}"
59+
echo "citus_version=${citus_version}" >> "$GITHUB_OUTPUT"
60+
echo "pg_versions=${pg_versions}" >> "$GITHUB_OUTPUT"
61+
62+
- name: Build matrix
63+
id: build_matrix
64+
run: |
65+
matrix=$(jq -cn \
66+
--argjson platforms '${{ steps.extract_platforms.outputs.platforms }}' \
67+
--argjson pg_versions '${{ steps.resolve_versions.outputs.pg_versions }}' \
68+
'{"platform": $platforms, "pg_version": $pg_versions}')
69+
echo "Matrix: ${matrix}"
70+
echo "matrix=${matrix}" >> "$GITHUB_OUTPUT"
71+
72+
test_package:
73+
name: "PG${{ matrix.pg_version }}/Citus${{ needs.discover.outputs.citus_version }} - ${{ matrix.platform }}"
74+
needs: discover
75+
runs-on: ubuntu-latest
76+
strategy:
77+
fail-fast: false
78+
matrix: ${{ fromJson(needs.discover.outputs.matrix) }}
79+
steps:
80+
- name: Checkout repository
81+
uses: actions/checkout@v4
82+
83+
- name: Set up Python
84+
uses: actions/setup-python@v5
85+
with:
86+
python-version: ">=3.10"
87+
88+
- name: Run package installation test
89+
run: |
90+
python3 test_package_installation/run_test.py \
91+
"${{ matrix.platform }}" \
92+
"${{ matrix.pg_version }}" \
93+
"${{ needs.discover.outputs.citus_version }}"

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@
77

88
# package output directory
99
/packages
10+
11+
.vscode
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Package Installation Tests
2+
3+
Verifies that Citus packages can be installed from the package repository on all supported platforms.
4+
5+
Each test:
6+
* spins up a Docker container for the target OS
7+
* installs the PostgreSQL and Citus packages
8+
* sets up a cluster and runs very basic tests
9+
* runs `make check-multi` regression tests from the Citus repository against the installed Citus version
10+
11+
## Running locally
12+
13+
Requires **Python 3.10+** and **Docker**. No additional Python packages needed.
14+
15+
```bash
16+
python3 test_package_installation/run_test.py <platform> <pg_major_version> <citus_full_version>
17+
```
18+
19+
Examples:
20+
21+
```bash
22+
python3 test_package_installation/run_test.py ubuntu/noble 18 14.0.0
23+
python3 test_package_installation/run_test.py el/9 17 14.0.0
24+
python3 test_package_installation/run_test.py debian/bookworm 16 14.0.0
25+
```
26+
27+
## Running via GitHub Actions
28+
29+
You can manually trigger the workflow using [this GitHub Actions tab](https://github.com/citusdata/packaging/actions/workflows/test-package-installation.yml).
30+
31+
It automatically discovers the supported platforms, latest Citus version that we published
32+
packages for, and compatible PostgreSQL versions from the `all-citus` branch, using
33+
[pkgvars](https://github.com/citusdata/packaging/blob/all-citus/pkgvars),
34+
[.github/workflows/build-package.yml](https://github.com/citusdata/packaging/blob/all-citus/.github/workflows/build-package.yml) and
35+
[postgres-matrix.yml](https://github.com/citusdata/packaging/blob/all-citus/postgres-matrix.yml) files.
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#!/bin/bash
2+
3+
# Runs "make check-multi" (multi_schedule).
4+
#
5+
# Expects the Citus source to be cloned at /citus and pg_regress
6+
# to be available in the PostgreSQL binary path.
7+
#
8+
# Usage: run_multi_schedule.sh <pg_binary_path>
9+
# Example: run_multi_schedule.sh /usr/lib/postgresql/18/bin
10+
11+
set -euo pipefail
12+
13+
if [ "$#" -ne 1 ]; then
14+
echo "Error: some arguments are missing." >&2
15+
echo "Usage: $0 <pg_binary_path>" >&2
16+
exit 1
17+
fi
18+
19+
PG_BIN="$1"
20+
21+
## suppress some of the regression test failures
22+
23+
# On rpm based distros, Postgres package might be linked against a newer ICU
24+
# than the one used to generate expected test output. To avoid test failures
25+
# due to this, patch the expected output to match the newer ICU version.
26+
# Without this, today pg18.sql fails.
27+
echo 's/und-u-kc-true-ks-level1/und-u-kc-ks-level1/g' >> /citus/src/test/regress/bin/normalize.sed
28+
29+
## run "make check-multi"
30+
31+
export PATH="${PG_BIN}:${PATH}"
32+
33+
cd /citus
34+
35+
# we don't need lz4 and zstd as none of the tests in multi_schedule depend on them
36+
./configure PG_CONFIG="${PG_BIN}/pg_config" --without-libcurl --without-lz4 --without-zstd
37+
38+
chown -R postgres:postgres /citus
39+
40+
echo "Running make check-multi ..."
41+
42+
if ! su - postgres -c "make check-multi -C /citus/src/test/regress"; then
43+
echo "make check-multi failed. Printing regression.diffs ..."
44+
cat /citus/src/test/regress/regression.diffs
45+
exit 1
46+
fi
47+
48+
echo "make check-multi completed successfully."
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
#!/bin/bash
2+
3+
# Sets up a multi-node Citus cluster, creates a distributed table,
4+
# rebalances shards, and verifies even distribution.
5+
#
6+
# Note: need to run this as root
7+
#
8+
# Usage: test_basics.sh <expected_pg_major_version> <expected_citus_full_version> <pg_binary_path>
9+
# Example: test_basics.sh 18 14.0.0 /usr/lib/postgresql/17/bin
10+
11+
set -euo pipefail
12+
13+
if [ "$#" -ne 3 ]; then
14+
echo "Error: some arguments are missing." >&2
15+
echo "Usage: $0 <expected_pg_major_version> <expected_citus_full_version> <pg_binary_path>" >&2
16+
exit 1
17+
fi
18+
19+
EXPECTED_PG_MAJOR_VERSION="$1"
20+
EXPECTED_CITUS_FULL_VERSION="$2"
21+
PG_BIN="$3"
22+
23+
## constants and helpers
24+
25+
NODE_COUNT=3
26+
SHARDS_PER_NODE=5
27+
FIRST_NODE_PORT=9700
28+
29+
run_psql_cmd() {
30+
if [ "$#" -ne 2 ]; then
31+
echo "Error: some arguments are missing." >&2
32+
echo "Usage: run_psql_cmd <port_number> <sql_command>" >&2
33+
exit 1
34+
fi
35+
36+
PORT_NUMBER="$1"
37+
SQL_COMMAND="$2"
38+
39+
su - postgres -c "${PG_BIN}/psql -X -qAt -p ${PORT_NUMBER} -c \"${SQL_COMMAND}\""
40+
}
41+
42+
## initialize all nodes and create citus extension on them
43+
44+
echo "Initializing nodes and creating citus extension on them ..."
45+
46+
mkdir -p /test_cluster
47+
chown postgres:postgres /test_cluster
48+
chmod 755 /test_cluster
49+
50+
for i in $(seq 0 $((NODE_COUNT - 1))); do
51+
node_name="node${i}"
52+
echo "Creating node: $node_name"
53+
54+
su - postgres -c "mkdir -p /test_cluster/${node_name}"
55+
56+
port_number=$((FIRST_NODE_PORT + i))
57+
58+
su - postgres -c "${PG_BIN}/initdb -D /test_cluster/${node_name}"
59+
su - postgres -c "echo \"shared_preload_libraries = 'citus'\" >> /test_cluster/${node_name}/postgresql.conf"
60+
su - postgres -c "${PG_BIN}/pg_ctl -D /test_cluster/${node_name} -o \"-p $port_number\" -l /test_cluster/${node_name}/logfile start"
61+
run_psql_cmd "$port_number" "CREATE EXTENSION citus;"
62+
done
63+
64+
## verify PG version
65+
66+
pg_version=$(run_psql_cmd "$FIRST_NODE_PORT" "SELECT version();")
67+
if [[ "$pg_version" != "PostgreSQL ${EXPECTED_PG_MAJOR_VERSION}."* ]]; then
68+
echo "Error: PostgreSQL version verification failed. Expected version to start with 'PostgreSQL ${EXPECTED_PG_MAJOR_VERSION}.', got: $pg_version" >&2
69+
exit 1
70+
else
71+
echo "Verified PostgreSQL version: $pg_version"
72+
fi
73+
74+
## verify Citus extension version
75+
76+
citus_version=$(run_psql_cmd "$FIRST_NODE_PORT" "SHOW citus.version;")
77+
if [[ "$citus_version" != "${EXPECTED_CITUS_FULL_VERSION}"* ]]; then
78+
echo "Error: Citus version verification failed. Expected version to start with '${EXPECTED_CITUS_FULL_VERSION}', got: $citus_version" >&2
79+
exit 1
80+
else
81+
echo "Verified Citus version: $citus_version"
82+
fi
83+
84+
## create a distributed table
85+
86+
echo "Creating a distributed table ..."
87+
88+
shard_count=$((NODE_COUNT * SHARDS_PER_NODE))
89+
run_psql_cmd "$FIRST_NODE_PORT" "CREATE TABLE test_table (id INT); SELECT create_distributed_table('test_table', 'id', shard_count => $shard_count);"
90+
91+
## add worker nodes
92+
93+
echo "Adding worker nodes ..."
94+
95+
for i in $(seq 1 $((NODE_COUNT - 1))); do
96+
port_number=$((FIRST_NODE_PORT + i))
97+
run_psql_cmd "$FIRST_NODE_PORT" "SELECT citus_add_node('localhost', $port_number);"
98+
done
99+
100+
## run rebalancer
101+
102+
echo "Running shard rebalancer ..."
103+
104+
run_psql_cmd "$FIRST_NODE_PORT" "SELECT rebalance_table_shards(shard_transfer_mode =>'block_writes');"
105+
106+
## verify that shards are distributed evenly across nodes
107+
108+
echo "Verifying that shards are distributed evenly across nodes ..."
109+
110+
result=$(
111+
run_psql_cmd "$FIRST_NODE_PORT" "
112+
SELECT bool_and(cnt = $SHARDS_PER_NODE)
113+
FROM (
114+
SELECT nodeport,
115+
COUNT(shardid) AS cnt
116+
FROM pg_dist_node
117+
LEFT JOIN pg_dist_shard_placement USING (nodeport)
118+
GROUP BY nodeport
119+
) t;
120+
"
121+
)
122+
123+
if [ "$result" = "t" ]; then
124+
echo "Verified cluster creation, distributed table creation and shard rebalancing. Shards are distributed evenly across nodes."
125+
else
126+
echo "Error: Failed. Shards are not distributed evenly across nodes, see below for details:" >&2
127+
run_psql_cmd "$FIRST_NODE_PORT" "
128+
SELECT nodeport,
129+
COUNT(shardid) AS cnt
130+
FROM pg_dist_node
131+
LEFT JOIN pg_dist_shard_placement USING (nodeport)
132+
GROUP BY nodeport;
133+
"
134+
exit 1
135+
fi
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#!/bin/bash
2+
3+
# Installs PostgreSQL and Citus packages on a Debian/Ubuntu system.
4+
#
5+
# Note: need to run this as root
6+
#
7+
# Usage: install_package.sh <pg_major_version> <citus_full_version>
8+
# Example: install_package.sh 18 14.0.0
9+
10+
set -euo pipefail
11+
12+
if [ "$#" -ne 2 ]; then
13+
echo "Error: some arguments are missing." >&2
14+
echo "Usage: $0 <pg_major_version> <citus_full_version>" >&2
15+
exit 1
16+
fi
17+
18+
PG_MAJOR_VERSION="$1"
19+
CITUS_FULL_VERSION="$2"
20+
21+
export DEBIAN_FRONTEND=noninteractive
22+
23+
apt-get -y update
24+
25+
## install postgres
26+
27+
echo "Installing PostgreSQL ..."
28+
29+
apt-get -y install curl ca-certificates
30+
31+
install -d /usr/share/postgresql-common/pgdg
32+
curl -o /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc --fail https://www.postgresql.org/media/keys/ACCC4CF8.asc
33+
. /etc/os-release
34+
sh -c "echo 'deb [signed-by=/usr/share/postgresql-common/pgdg/apt.postgresql.org.asc] https://apt.postgresql.org/pub/repos/apt $VERSION_CODENAME-pgdg main' > /etc/apt/sources.list.d/pgdg.list"
35+
36+
apt -y update
37+
apt-get -y install postgresql-${PG_MAJOR_VERSION}
38+
39+
## install citus
40+
41+
echo "Installing Citus ..."
42+
43+
curl --fail https://install.citusdata.com/community/deb.sh > add-citus-repo.sh
44+
bash add-citus-repo.sh
45+
46+
citus_major_minor_version="${CITUS_FULL_VERSION%.*}"
47+
apt-get -y install postgresql-${PG_MAJOR_VERSION}-citus-${citus_major_minor_version}=${CITUS_FULL_VERSION}.citus-1
48+
49+
echo "PostgreSQL and Citus packages installed successfully."

0 commit comments

Comments
 (0)