OTEL E2E Testing
This guide explains how to run the automated OTEL E2E test locally and in CI to validate that Porch components (porch-server, porch-controllers, porch-function-runner) correctly export traces and metrics to observability backends.
Overview
The OTEL E2E testing validates:
- ✅ All Porch components export traces to Jaeger
- ✅ All components export metrics to Prometheus
- ✅ OTEL SDK initializes without errors
- ✅ Real Porch operations are properly instrumented
Scope: v1alpha2 CRD test suite
- Both v1alpha1 and v1alpha2 APIs use the same underlying server and controller components (porch-server, porch-controllers, function-runner)
- OTEL instrumentation is at the component level, not the API layer
- A single v1alpha2 test suite is sufficient to validate telemetry export from all shared components
- Uses lightweight “Init” specs and one render test to exercise core operations efficiently
Prerequisites
- Running Kind cluster with Porch deployed (see Local Development Environment)
- kubectl configured to access the cluster
jqcommand-line JSON processor (for validation output)
Resource Requirements
Note on resource bumps: Porch components have increased resource allocations to accommodate OTEL telemetry collection:
- porch-server: 500m CPU request, 512Mi memory request (was lower; increased to prevent timeout issues during telemetry export)
- porch-function-runner: Similar increases to ensure stable operation while exporting traces/metrics
These resource changes apply system-wide (not just OTEL tests) to provide stable baseline capacity for observability operations.
If tighter resource constraints are needed for your environment, adjust deployments/porch/*.yaml before deploying.
Local Testing
Run OTEL E2E Test
Single command deploys Porch, monitoring stack, runs E2E test, and validates OTEL:
make test-e2e-otel
This:
- Deploys v1alpha2 stack with DB cache
- Deploys monitoring (Prometheus, Grafana, Jaeger)
- Runs lightweight E2E test (~20-30 sec) to exercise components
- Validates traces/metrics from all 3 components
- Leaves deployment running for manual debugging (see Access Observability UIs)
Total time: ~25-30 minutes
Validation Steps
The validate-otel.sh script checks:
- ✅ Jaeger pod is running
- ✅ porch-server metrics endpoint responds (port 9464)
- ✅ OTEL initialized in logs (no critical errors)
- ✅ Traces exist in Jaeger (with retries)
- ✅ Prometheus has scraped all 3 components
- ✅ Lists all components exporting traces
Example output:
=== OTEL Validation Checks ===
=== 1. Checking Jaeger availability ===
✓ Jaeger pod found: jaeger-66f5c97cb8-skllc
=== 2. Checking porch-server metrics endpoint ===
✓ Metrics endpoint responding
=== 6. Services reporting traces to Jaeger ===
✓ Porch components exporting traces:
- porch-server
- porch-controllers
- porch-function-runner
Access Observability UIs
While the test stack is running, access services via port-forward:
Jaeger (Distributed Tracing)
# Terminal 1
kubectl port-forward -n porch-monitoring deployment/jaeger 16686:16686
# Terminal 2 - visit http://localhost:16686
# Query service: "porch-server", "porch-controllers", or "porch-function-runner"
Prometheus (Metrics)
# Terminal 1
kubectl port-forward -n porch-monitoring deployment/prometheus 9092:9090
# Terminal 2 - visit http://localhost:9092
# Query: http_server_requests_total, grpc_server_requests_total
Grafana (Dashboards)
# Terminal 1
kubectl port-forward -n porch-monitoring deployment/grafana 3001:3000
# Terminal 2 - visit http://localhost:3001
# Default credentials:
# User: porch
# Password: retrieve from secret using:
# kubectl get secret -n porch-monitoring grafana-admin-creds \
# -o jsonpath='{.data.password}' | base64 -d
CI Integration
GitHub Actions Workflow
The OTEL E2E tests run automatically in GitHub Actions.
File: .github/workflows/porch-e2e-otel-weekly.yaml
Triggers:
- Scheduled: Every Sunday at 2 AM UTC
- Manual: Trigger via GitHub Actions UI (
workflow_dispatch)
What it does:
- Builds Porch images (parallel)
- Deploys v1alpha2 stack
- Deploys monitoring
- Runs lightweight E2E test
- Validates OTEL infrastructure
- Reports which components export traces/metrics
Duration: ~45 minutes total
Test Selection
Init and Render tests (v1alpha2 CRD):
- Operations: Create/initialize packages + simple render pipeline
- Why: Lightweight, exercises core package operations and function-runner traces, no heavy rendering overhead
- Duration: ~30-45 seconds
- Traces generated: API calls, package initialization, status updates, function-runner invocations
- Function-runner coverage: Render pipeline test invokes the set-namespace KRM function, generating function-runner traces
This test suite is sufficient to verify that:
- All components are healthy and receiving traffic
- All components export traces and metrics
- OTEL pipeline works end-to-end
- Server-level and function-runner instrumentation is working
Make Targets
# Deploy + test + validate + leave running for debugging
make test-e2e-otel
Troubleshooting
No traces in Jaeger
Check Porch components are running:
kubectl get pods -n porch-systemCheck OTEL env vars are set:
kubectl get deployment porch-server -n porch-system \ -o jsonpath='{.spec.template.spec.containers[0].env[?(@.name=="OTEL_EXPORTER_OTLP_TRACES_ENDPOINT")].value}'Should output:
http://jaeger-otlp.porch-monitoring.svc.cluster.local:4317Check Jaeger OTLP endpoint is reachable:
kubectl logs -n porch-system deployment/porch-server | grep -i "jaeger\|otlp\|export"
Metrics endpoint not responding
Check porch-server pod is healthy:
kubectl get pod -n porch-system -l app=porch-server kubectl logs -n porch-system -l app=porch-server | grep "ERROR\|error"Verify port-forward is working:
kubectl port-forward -n porch-system deployment/porch-server 9464:9464 & curl http://localhost:9464/metrics | head -10
Validation script fails
- Prometheus metrics query fails: Metrics may still be collecting. Check manually at
http://localhost:9092(Prometheus UI) - No services in Jaeger: E2E test may not have exercised components. Check test logs for errors
- Export errors in logs: Usually transient (connection timeout during startup). Check if components eventually recover
Cleanup
# Remove monitoring stack
./scripts/monitoring/deploy-monitoring.sh remove
# Destroy Porch deployment
make destroy
Next Steps
- Configure OTEL exporters: OpenTelemetry Configuration
- Deploy monitoring stack: Local Performance Monitoring Deployment
- Run performance tests: Performance Tests