Skip to content

Commit 64da5fc

Browse files
committed
foo
1 parent daffc6a commit 64da5fc

File tree

4 files changed

+200
-95
lines changed

4 files changed

+200
-95
lines changed

.github/workflows/ci.yml

Lines changed: 14 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -79,26 +79,10 @@ jobs:
7979

8080
- name: Wait for K3s readiness
8181
run: |
82-
echo "=== Waiting for K3s cluster to be ready ==="
83-
84-
# The action already sets up kubectl context, just verify it works
85-
kubectl cluster-info
86-
kubectl get nodes
87-
88-
# Wait for core components
89-
kubectl wait --for=condition=Ready pod -l k8s-app=kube-dns -n kube-system --timeout=300s
90-
kubectl wait --for=condition=Ready pod -l app.kubernetes.io/name=traefik -n kube-system --timeout=300s
91-
92-
# Verify Traefik CRDs
93-
timeout=300; counter=0
94-
for crd in "middlewares.traefik.io" "ingressroutes.traefik.io"; do
95-
while [ $counter -lt $timeout ] && ! kubectl get crd "$crd" &>/dev/null; do
96-
sleep 3; counter=$((counter + 3))
97-
done
98-
[ $counter -ge $timeout ] && { echo "❌ Timeout waiting for $crd"; exit 1; }
99-
done
100-
101-
echo "✅ K3s cluster ready"
82+
# Source validation library and use K3s readiness check
83+
source ./scripts/lib/common.sh
84+
source ./scripts/lib/validation.sh
85+
validate_k3s_readiness
10286
10387
- name: Deploy eoAPI
10488
id: deploy
@@ -155,65 +139,19 @@ jobs:
155139
156140
- name: Wait for services to be ready
157141
run: |
158-
set -e # Exit on any error
159-
160-
echo "=== Waiting for Services to be Ready ==="
161-
echo "RELEASE_NAME: ${RELEASE_NAME}"
162-
163-
# Verify namespace exists first
164-
if ! kubectl get namespace "${RELEASE_NAME}" >/dev/null 2>&1; then
165-
echo "❌ Namespace ${RELEASE_NAME} does not exist!"
166-
kubectl get namespaces
167-
exit 1
168-
fi
169-
170-
echo "Waiting for deployments in namespace ${RELEASE_NAME}..."
171-
kubectl wait --for=condition=available deployment/"${RELEASE_NAME}"-stac -n "${RELEASE_NAME}" --timeout=300s
172-
kubectl wait --for=condition=available deployment/"${RELEASE_NAME}"-raster -n "${RELEASE_NAME}" --timeout=300s
173-
kubectl wait --for=condition=available deployment/"${RELEASE_NAME}"-vector -n "${RELEASE_NAME}" --timeout=300s
174-
175-
# Get the K3s node IP and set up host entry
176-
NODE_IP=$(kubectl get nodes -o jsonpath='{.items[0].status.addresses[?(@.type=="InternalIP")].address}')
177-
echo "Node IP: $NODE_IP"
178-
179-
# Add eoapi.local to /etc/hosts for ingress access
180-
echo "$NODE_IP eoapi.local" | sudo tee -a /etc/hosts
181-
182-
# Wait for ingress to be ready
183-
echo "=== Waiting for Ingress to be Ready ==="
184-
kubectl get ingress -n "${RELEASE_NAME}"
142+
# Export RELEASE_NAME to satisfy shellcheck
143+
export RELEASE_NAME="${RELEASE_NAME}"
185144
186-
# Wait for Traefik to pick up the ingress rules
187-
sleep 10
145+
# Source validation library and use service readiness checks
146+
source ./scripts/lib/common.sh
147+
source ./scripts/lib/validation.sh
188148
189-
# Test connectivity through ingress using eoapi.local
190-
echo "=== Testing API connectivity through ingress ==="
191-
for i in {1..30}; do
192-
if curl -s "http://eoapi.local/stac/_mgmt/ping" 2>/dev/null; then
193-
echo "✅ STAC API accessible through ingress"
194-
break
195-
fi
196-
echo "Waiting for STAC API... (attempt $i/30)"
197-
sleep 3
198-
done
149+
# Wait for deployments to be ready
150+
validate_deployments_ready "${RELEASE_NAME}" "${RELEASE_NAME}"
199151
200-
for i in {1..30}; do
201-
if curl -s "http://eoapi.local/raster/healthz" 2>/dev/null; then
202-
echo "✅ Raster API accessible through ingress"
203-
break
204-
fi
205-
echo "Waiting for Raster API... (attempt $i/30)"
206-
sleep 3
207-
done
208-
209-
for i in {1..30}; do
210-
if curl -s "http://eoapi.local/vector/healthz" 2>/dev/null; then
211-
echo "✅ Vector API accessible through ingress"
212-
break
213-
fi
214-
echo "Waiting for Vector API... (attempt $i/30)"
215-
sleep 3
216-
done
152+
# Wait for ingress and test API connectivity
153+
validate_ingress_ready "${RELEASE_NAME}"
154+
validate_api_connectivity "eoapi.local"
217155
218156
- name: Run integration tests
219157
run: |

CHANGELOG.md

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10-
### Fixed
11-
- Fixed integration tests failing with pagination URLs by:
12-
- Using Traefik ingress in CI instead of port-forwarding to properly test ingress configuration
13-
- Adding `ROOT_PATH` environment variable to services (stac, raster, vector, multidim) when ingress is enabled
14-
- This ensures services generate correct URLs with path prefixes (e.g., `/raster/searches/list`) in pagination links
15-
- Added test script `scripts/tests/test-ingress-paths.sh` to validate ROOT_PATH behavior with ingress
16-
1710
### Changed
18-
- CI workflow now deploys with Traefik ingress enabled (`--set ingress.className=traefik`) for more realistic testing
19-
- Services now automatically receive their path prefix via `ROOT_PATH` environment variable when behind an ingress
2011
- Refactored test and deployment scripts
2112

2213
## [0.7.13] - 2025-11-04

scripts/lib/validation.sh

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,8 +302,187 @@ validate_helm_chart() {
302302
return 0
303303
}
304304

305+
# Validate K3s cluster readiness (extracted from CI workflow)
306+
validate_k3s_readiness() {
307+
log_info "=== Waiting for K3s cluster to be ready ==="
308+
309+
# Verify kubectl works
310+
if ! kubectl cluster-info >/dev/null 2>&1; then
311+
log_error "Cannot connect to K3s cluster"
312+
return 1
313+
fi
314+
315+
if ! kubectl get nodes >/dev/null 2>&1; then
316+
log_error "Cannot get cluster nodes"
317+
return 1
318+
fi
319+
320+
# Wait for core components
321+
log_info "Waiting for core DNS..."
322+
if ! kubectl wait --for=condition=Ready pod -l k8s-app=kube-dns -n kube-system --timeout=300s 2>/dev/null; then
323+
log_error "Core DNS not ready"
324+
return 1
325+
fi
326+
327+
log_info "Waiting for Traefik..."
328+
if ! kubectl wait --for=condition=Ready pod -l app.kubernetes.io/name=traefik -n kube-system --timeout=300s 2>/dev/null; then
329+
log_error "Traefik not ready"
330+
return 1
331+
fi
332+
333+
# Verify Traefik CRDs
334+
log_info "Verifying Traefik CRDs..."
335+
local timeout=300
336+
local counter=0
337+
for crd in "middlewares.traefik.io" "ingressroutes.traefik.io"; do
338+
while [ $counter -lt $timeout ] && ! kubectl get crd "$crd" &>/dev/null; do
339+
sleep 3
340+
counter=$((counter + 3))
341+
done
342+
if [ $counter -ge $timeout ]; then
343+
log_error "Timeout waiting for CRD: $crd"
344+
return 1
345+
fi
346+
done
347+
348+
log_info "✅ K3s cluster ready"
349+
return 0
350+
}
351+
352+
# Wait for eoAPI deployments to be available
353+
validate_deployments_ready() {
354+
local namespace="$1"
355+
local release_name="$2"
356+
local timeout="${3:-300s}"
357+
358+
log_info "=== Waiting for deployments to be ready ==="
359+
360+
# Verify namespace exists
361+
if ! kubectl get namespace "$namespace" >/dev/null 2>&1; then
362+
log_error "Namespace $namespace does not exist"
363+
return 1
364+
fi
365+
366+
# Wait for core deployments
367+
local deployments=("${release_name}-stac" "${release_name}-raster" "${release_name}-vector")
368+
local failed=false
369+
370+
for deployment in "${deployments[@]}"; do
371+
log_info "Waiting for deployment: $deployment"
372+
if ! kubectl wait --for=condition=available "deployment/$deployment" -n "$namespace" --timeout="$timeout" 2>/dev/null; then
373+
log_error "Deployment $deployment not ready"
374+
failed=true
375+
fi
376+
done
377+
378+
if [ "$failed" = true ]; then
379+
return 1
380+
fi
381+
382+
log_info "✅ All deployments ready"
383+
return 0
384+
}
385+
386+
# Validate API connectivity through ingress
387+
validate_api_connectivity() {
388+
local ingress_host="${1:-eoapi.local}"
389+
local max_attempts="${2:-30}"
390+
391+
log_info "=== Testing API connectivity through ingress ==="
392+
393+
# Add ingress host to /etc/hosts if needed and not already present
394+
if [[ "$ingress_host" == *.local ]] && ! grep -q "$ingress_host" /etc/hosts 2>/dev/null; then
395+
local node_ip
396+
node_ip=$(kubectl get nodes -o jsonpath='{.items[0].status.addresses[?(@.type=="InternalIP")].address}' 2>/dev/null)
397+
if [ -n "$node_ip" ]; then
398+
log_info "Adding $ingress_host to /etc/hosts with IP $node_ip"
399+
echo "$node_ip $ingress_host" | sudo tee -a /etc/hosts >/dev/null
400+
fi
401+
fi
402+
403+
# Test STAC API
404+
log_info "Testing STAC API..."
405+
local i
406+
for i in $(seq 1 "$max_attempts"); do
407+
if curl -s "http://${ingress_host}/stac/_mgmt/ping" >/dev/null 2>&1; then
408+
log_info "✅ STAC API accessible through ingress"
409+
break
410+
fi
411+
log_debug "Waiting for STAC API... (attempt $i/$max_attempts)"
412+
sleep 3
413+
done
414+
if [ "$i" -eq "$max_attempts" ]; then
415+
log_error "STAC API not accessible after $max_attempts attempts"
416+
return 1
417+
fi
418+
419+
# Test Raster API
420+
log_info "Testing Raster API..."
421+
for i in $(seq 1 "$max_attempts"); do
422+
if curl -s "http://${ingress_host}/raster/healthz" >/dev/null 2>&1; then
423+
log_info "✅ Raster API accessible through ingress"
424+
break
425+
fi
426+
log_debug "Waiting for Raster API... (attempt $i/$max_attempts)"
427+
sleep 3
428+
done
429+
if [ "$i" -eq "$max_attempts" ]; then
430+
log_error "Raster API not accessible after $max_attempts attempts"
431+
return 1
432+
fi
433+
434+
# Test Vector API
435+
log_info "Testing Vector API..."
436+
for i in $(seq 1 "$max_attempts"); do
437+
if curl -s "http://${ingress_host}/vector/healthz" >/dev/null 2>&1; then
438+
log_info "✅ Vector API accessible through ingress"
439+
break
440+
fi
441+
log_debug "Waiting for Vector API... (attempt $i/$max_attempts)"
442+
sleep 3
443+
done
444+
if [ "$i" -eq "$max_attempts" ]; then
445+
log_error "Vector API not accessible after $max_attempts attempts"
446+
return 1
447+
fi
448+
449+
log_info "✅ All APIs accessible through ingress"
450+
return 0
451+
}
452+
453+
# Wait for ingress to be ready
454+
validate_ingress_ready() {
455+
local namespace="$1"
456+
local ingress_name="${2:-}"
457+
local timeout="${3:-60s}"
458+
459+
log_info "Waiting for ingress to be ready..."
460+
461+
# Get ingress resources
462+
if ! kubectl get ingress -n "$namespace" >/dev/null 2>&1; then
463+
log_warn "No ingress resources found in namespace $namespace"
464+
return 0
465+
fi
466+
467+
# If specific ingress name provided, wait for it
468+
if [ -n "$ingress_name" ]; then
469+
if kubectl get ingress "$ingress_name" -n "$namespace" >/dev/null 2>&1; then
470+
log_debug "Ingress $ingress_name exists in namespace $namespace"
471+
else
472+
log_warn "Ingress $ingress_name not found in namespace $namespace"
473+
fi
474+
fi
475+
476+
# Wait for Traefik to pick up ingress rules
477+
sleep 10
478+
479+
log_info "✅ Ingress ready"
480+
return 0
481+
}
482+
305483
# Export validation functions
306484
export -f validate_kubectl validate_helm validate_python3 validate_jq
307485
export -f validate_deploy_tools validate_test_tools validate_local_cluster_tools
308486
export -f validate_cluster_connection validate_cluster_permissions
309487
export -f validate_file_readable validate_json_file validate_yaml_file validate_helm_chart
488+
export -f validate_k3s_readiness validate_deployments_ready validate_api_connectivity validate_ingress_ready

scripts/test.sh

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
# Source shared utilities
66
SCRIPT_DIR="$(dirname "$(readlink -f "$0")")"
77
source "$SCRIPT_DIR/lib/common.sh"
8+
source "$SCRIPT_DIR/lib/validation.sh"
89

910
# Global variables
1011
DEBUG_MODE=false
@@ -69,8 +70,8 @@ log_info "eoAPI Test Suite - Command: $COMMAND | Debug: $DEBUG_MODE | Release: $
6970
# Check dependencies
7071
check_dependencies() {
7172
log_info "Checking dependencies..."
72-
command -v helm >/dev/null 2>&1 || { log_error "helm required"; exit 1; }
73-
command -v kubectl >/dev/null 2>&1 || { log_error "kubectl required"; exit 1; }
73+
validate_kubectl || exit 1
74+
validate_helm || exit 1
7475
log_info "✅ Dependencies OK"
7576
}
7677

@@ -195,14 +196,10 @@ run_integration_tests() {
195196
fi
196197
fi
197198

198-
# Wait for pods to be ready - try standard labels first, fallback to legacy
199-
if kubectl get pods -n "$NAMESPACE" >/dev/null 2>&1; then
200-
if ! wait_for_pods "$NAMESPACE" "app.kubernetes.io/name=eoapi,app.kubernetes.io/component=stac" "300s" 2>/dev/null; then
201-
if ! wait_for_pods "$NAMESPACE" "app=${RELEASE_NAME}-stac" "300s"; then
202-
log_error "STAC pods not ready"
203-
exit 1
204-
fi
205-
fi
199+
# Wait for deployments to be ready using validation function
200+
if ! validate_deployments_ready "$NAMESPACE" "$RELEASE_NAME" "300s"; then
201+
log_error "Deployments not ready"
202+
exit 1
206203
fi
207204

208205
# Wait for Knative services to be ready if they exist

0 commit comments

Comments
 (0)