Skip to content

Commit 20d96d6

Browse files
committed
ci: added integration tests.
1 parent 0873bce commit 20d96d6

File tree

3 files changed

+195
-0
lines changed

3 files changed

+195
-0
lines changed

.github/workflows/ci.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,19 @@ jobs:
2121
- name: Install helm-unittest plugin
2222
run: helm plugin install https://github.com/helm-unittest/helm-unittest --verify=false
2323
- uses: pre-commit/action@v3.0.1
24+
25+
integration-test:
26+
runs-on: ubuntu-latest
27+
steps:
28+
- uses: actions/checkout@v6
29+
- uses: jupyterhub/action-k3s-helm@v4
30+
with:
31+
k3s-channel: latest
32+
- name: Run integration test
33+
run: ./scripts/integration-test.sh
34+
- name: Debug on failure
35+
if: failure()
36+
run: kubectl get all -n test
37+
- name: Cleanup
38+
if: always()
39+
run: k3d cluster delete pgstac-test || true

scripts/README.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Integration Tests
2+
3+
Kubernetes integration test using k3d for pgstac-geoparquet-exporter.
4+
5+
## Requirements
6+
7+
- Docker
8+
- [k3d](https://k3d.io)
9+
- kubectl
10+
- helm
11+
12+
## Run
13+
14+
```bash
15+
./scripts/integration-test.sh
16+
```
17+
18+
## What it does
19+
20+
1. Creates k3d cluster
21+
2. Installs PostgreSQL Operator + pgSTAC database
22+
3. Deploys MinIO (S3)
23+
4. Installs helm chart
24+
5. Verifies CronJobs are created
25+
26+
## Cleanup
27+
28+
```bash
29+
k3d cluster delete pgstac-test
30+
```

scripts/integration-test.sh

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
CLUSTER_NAME="${CLUSTER_NAME:-pgstac-test}"
5+
NAMESPACE="${NAMESPACE:-test}"
6+
7+
# Cluster
8+
if ! kubectl cluster-info &>/dev/null; then
9+
if command -v k3d &>/dev/null; then
10+
echo "Creating k3d cluster..."
11+
k3d cluster create "$CLUSTER_NAME" --agents 1 --wait
12+
else
13+
echo "Error: No Kubernetes cluster found and k3d is not installed" >&2
14+
exit 1
15+
fi
16+
else
17+
echo "Using existing cluster..."
18+
fi
19+
20+
# PGO
21+
echo "Installing PostgreSQL Operator..."
22+
helm upgrade --install pgo oci://registry.developers.crunchydata.com/crunchydata/pgo \
23+
--version 5.8.0 --wait --timeout 3m
24+
25+
# Namespace
26+
kubectl create namespace "$NAMESPACE" --dry-run=client -o yaml | kubectl apply -f -
27+
28+
# pgSTAC
29+
echo "Deploying pgSTAC..."
30+
cat <<EOF | kubectl apply -f -
31+
apiVersion: postgres-operator.crunchydata.com/v1beta1
32+
kind: PostgresCluster
33+
metadata:
34+
name: pgstac
35+
namespace: $NAMESPACE
36+
spec:
37+
image: registry.developers.crunchydata.com/crunchydata/crunchy-postgres:ubi8-15.10-0
38+
postgresVersion: 15
39+
instances:
40+
- name: instance1
41+
replicas: 1
42+
dataVolumeClaimSpec:
43+
accessModes: ["ReadWriteOnce"]
44+
resources:
45+
requests:
46+
storage: 1Gi
47+
backups:
48+
pgbackrest:
49+
repos:
50+
- name: repo1
51+
volume:
52+
volumeClaimSpec:
53+
accessModes: ["ReadWriteOnce"]
54+
resources:
55+
requests:
56+
storage: 1Gi
57+
users:
58+
- name: eoapi
59+
databases: ["pgstac"]
60+
EOF
61+
62+
echo "Waiting for pgSTAC pods..."
63+
for i in {1..60}; do
64+
if kubectl get pod -l postgres-operator.crunchydata.com/cluster=pgstac -n "$NAMESPACE" 2>/dev/null | grep -q pgstac; then
65+
break
66+
fi
67+
sleep 2
68+
done
69+
kubectl wait --for=condition=Ready pod -l postgres-operator.crunchydata.com/cluster=pgstac -n "$NAMESPACE" --timeout=3m
70+
71+
# pgSTAC extension
72+
PGSTAC_POD=$(kubectl get pod -l postgres-operator.crunchydata.com/cluster=pgstac,postgres-operator.crunchydata.com/instance -n "$NAMESPACE" -o jsonpath='{.items[0].metadata.name}')
73+
echo "Installing extensions..."
74+
for i in {1..30}; do
75+
if kubectl exec -n "$NAMESPACE" "$PGSTAC_POD" -- psql -U eoapi -d pgstac -c \
76+
"CREATE EXTENSION IF NOT EXISTS postgis; CREATE EXTENSION IF NOT EXISTS pgstac;" 2>/dev/null; then
77+
break
78+
fi
79+
sleep 2
80+
done
81+
82+
# MinIO
83+
echo "Deploying MinIO..."
84+
kubectl create secret generic minio-secret -n "$NAMESPACE" \
85+
--from-literal=accesskey=minioadmin \
86+
--from-literal=secretkey=minioadmin \
87+
--dry-run=client -o yaml | kubectl apply -f -
88+
89+
cat <<EOF | kubectl apply -f -
90+
apiVersion: apps/v1
91+
kind: Deployment
92+
metadata:
93+
name: minio
94+
namespace: $NAMESPACE
95+
spec:
96+
replicas: 1
97+
selector:
98+
matchLabels:
99+
app: minio
100+
template:
101+
metadata:
102+
labels:
103+
app: minio
104+
spec:
105+
containers:
106+
- name: minio
107+
image: minio/minio:latest
108+
args: ["server", "/data"]
109+
env:
110+
- name: MINIO_ROOT_USER
111+
value: minioadmin
112+
- name: MINIO_ROOT_PASSWORD
113+
value: minioadmin
114+
ports:
115+
- containerPort: 9000
116+
---
117+
apiVersion: v1
118+
kind: Service
119+
metadata:
120+
name: minio
121+
namespace: $NAMESPACE
122+
spec:
123+
ports:
124+
- port: 9000
125+
selector:
126+
app: minio
127+
EOF
128+
129+
kubectl wait --for=condition=available deployment/minio -n "$NAMESPACE" --timeout=2m
130+
131+
# Deploy chart
132+
echo "Deploying helm chart..."
133+
helm upgrade --install exporter charts/pgstac-geoparquet-exporter -n "$NAMESPACE" \
134+
--set database.existingSecret=pgstac-pguser-eoapi \
135+
--set storage.outputPath=s3://test/geoparquet \
136+
--set storage.existingSecret=minio-secret \
137+
--set storage.secretKeys.accessKeyId=accesskey \
138+
--set storage.secretKeys.secretAccessKey=secretkey \
139+
--set storage.endpoint=http://minio:9000 \
140+
--set exportConfig.collections[0].name=test-collection \
141+
--wait --timeout 2m
142+
143+
# Verify
144+
echo "Verifying CronJobs..."
145+
kubectl get cronjobs -n "$NAMESPACE"
146+
[ "$(kubectl get cronjobs -n "$NAMESPACE" --no-headers | wc -l)" -ge 2 ] || exit 1
147+
148+
echo "✓ Tests passed"
149+
echo "Cleanup: k3d cluster delete $CLUSTER_NAME"

0 commit comments

Comments
 (0)