1+ #! /bin/bash
2+
3+ # End-to-end test for the reference application using docker-compose
4+ # This test verifies that the full stack works correctly with OpenTelemetry
5+
6+ set -euo pipefail
7+
8+ SCRIPT_DIR=" $( cd " $( dirname " ${BASH_SOURCE[0]} " ) " && pwd) "
9+ cd " $SCRIPT_DIR "
10+
11+ # Colors for output
12+ RED=' \033[0;31m'
13+ GREEN=' \033[0;32m'
14+ YELLOW=' \033[1;33m'
15+ NC=' \033[0m' # No Color
16+
17+ # Function to print colored output
18+ print_status () {
19+ echo -e " ${GREEN} [INFO]${NC} $1 "
20+ }
21+
22+ print_warning () {
23+ echo -e " ${YELLOW} [WARN]${NC} $1 "
24+ }
25+
26+ print_error () {
27+ echo -e " ${RED} [ERROR]${NC} $1 "
28+ }
29+
30+ # Function to wait for a service to be ready
31+ wait_for_service () {
32+ local url=$1
33+ local service_name=$2
34+ local max_attempts=30
35+ local attempt=1
36+
37+ print_status " Waiting for $service_name to be ready at $url ..."
38+
39+ while [ $attempt -le $max_attempts ]; do
40+ if curl -sf " $url " > /dev/null 2>&1 ; then
41+ print_status " $service_name is ready!"
42+ return 0
43+ fi
44+
45+ if [ $attempt -eq $max_attempts ]; then
46+ print_error " $service_name failed to start within $max_attempts attempts"
47+ return 1
48+ fi
49+
50+ print_status " Attempt $attempt /$max_attempts : $service_name not ready yet, waiting..."
51+ sleep 2
52+ (( attempt++ ))
53+ done
54+ }
55+
56+ # Function to test application endpoints
57+ test_endpoints () {
58+ print_status " Testing application endpoints..."
59+
60+ # Test basic dice roll
61+ print_status " Testing /rolldice endpoint..."
62+ response=$( curl -sf http://localhost:8080/rolldice)
63+ if echo " $response " | jq -e ' .result' > /dev/null && echo " $response " | jq -e ' .player' > /dev/null; then
64+ print_status " ✓ /rolldice endpoint working"
65+ else
66+ print_error " ✗ /rolldice endpoint failed"
67+ return 1
68+ fi
69+
70+ # Test dice roll with player
71+ print_status " Testing /rolldice?player=testuser endpoint..."
72+ response=$( curl -sf " http://localhost:8080/rolldice?player=testuser" )
73+ if echo " $response " | jq -r ' .player' | grep -q " testuser" ; then
74+ print_status " ✓ /rolldice with player working"
75+ else
76+ print_error " ✗ /rolldice with player failed"
77+ return 1
78+ fi
79+
80+ # Test fibonacci endpoint
81+ print_status " Testing /fibonacci?n=10 endpoint..."
82+ response=$( curl -sf " http://localhost:8080/fibonacci?n=10" )
83+ if echo " $response " | jq -r ' .result' | grep -q " 55" ; then
84+ print_status " ✓ /fibonacci endpoint working"
85+ else
86+ print_error " ✗ /fibonacci endpoint failed"
87+ return 1
88+ fi
89+
90+ # Test health endpoint
91+ print_status " Testing /health endpoint..."
92+ response=$( curl -sf http://localhost:8080/health)
93+ if echo " $response " | jq -r ' .status' | grep -q " UP" ; then
94+ print_status " ✓ /health endpoint working"
95+ else
96+ print_error " ✗ /health endpoint failed"
97+ return 1
98+ fi
99+
100+ # Test metrics endpoint
101+ print_status " Testing /actuator/prometheus endpoint..."
102+ if curl -sf http://localhost:8080/actuator/prometheus | grep -q " dice_rolls_total" ; then
103+ print_status " ✓ /actuator/prometheus endpoint working with custom metrics"
104+ else
105+ print_error " ✗ /actuator/prometheus endpoint failed or missing custom metrics"
106+ return 1
107+ fi
108+
109+ print_status " All endpoint tests passed!"
110+ }
111+
112+ # Function to test OpenTelemetry collector
113+ test_collector () {
114+ print_status " Testing OpenTelemetry collector..."
115+
116+ # Check collector health endpoint
117+ if curl -sf http://localhost:13133 > /dev/null; then
118+ print_status " ✓ OpenTelemetry collector health endpoint is accessible"
119+ else
120+ print_warning " ! OpenTelemetry collector health endpoint not accessible (this might be expected)"
121+ fi
122+
123+ # Check if collector is receiving and processing data by examining logs
124+ print_status " Checking collector logs for telemetry data processing..."
125+
126+ # Generate some telemetry data
127+ curl -sf http://localhost:8080/rolldice > /dev/null
128+ curl -sf http://localhost:8080/fibonacci? n=5 > /dev/null
129+
130+ # Wait a bit for data to be processed
131+ sleep 5
132+
133+ # Check collector logs for evidence of data processing
134+ if $compose_cmd logs otel-collector 2> /dev/null | grep -q -E " (spans|metrics|logs).*processed" ; then
135+ print_status " ✓ OpenTelemetry collector is processing telemetry data"
136+ else
137+ print_warning " ! Could not verify telemetry data processing in collector logs"
138+ fi
139+ }
140+
141+ # Function to test Prometheus integration
142+ test_prometheus () {
143+ print_status " Testing Prometheus integration..."
144+
145+ # Wait for Prometheus to be ready
146+ if wait_for_service " http://localhost:9090/-/ready" " Prometheus" ; then
147+ print_status " ✓ Prometheus is running"
148+
149+ # Check if Prometheus can scrape metrics from the collector
150+ if curl -sf " http://localhost:9090/api/v1/targets" | jq -r ' .data.activeTargets[].health' | grep -q " up" ; then
151+ print_status " ✓ Prometheus has healthy targets"
152+ else
153+ print_warning " ! Prometheus targets may not be healthy"
154+ fi
155+ else
156+ print_warning " ! Prometheus failed to start"
157+ fi
158+ }
159+
160+ # Function to get the docker compose command
161+ get_docker_compose_cmd () {
162+ if command -v " docker-compose" & > /dev/null; then
163+ echo " docker-compose"
164+ elif docker compose version & > /dev/null; then
165+ echo " docker compose"
166+ else
167+ return 1
168+ fi
169+ }
170+
171+ # Function to cleanup resources
172+ cleanup () {
173+ print_status " Cleaning up resources..."
174+ local compose_cmd
175+ if compose_cmd=$( get_docker_compose_cmd) ; then
176+ $compose_cmd down --volumes --remove-orphans || true
177+ fi
178+
179+ # Clean up any dangling resources
180+ docker system prune -f || true
181+ }
182+
183+ # Main execution
184+ main () {
185+ print_status " Starting end-to-end test for OpenTelemetry Reference Application"
186+
187+ # Handle dry-run mode for testing
188+ if [[ " ${1:- } " == " --dry-run" ]]; then
189+ print_status " Running in dry-run mode - skipping actual Docker operations"
190+ print_status " ✅ Script validation passed"
191+ return 0
192+ fi
193+
194+ # Ensure we're in the right directory
195+ if [[ ! -f " docker-compose.yml" ]]; then
196+ print_error " docker-compose.yml not found. Please run this script from the reference-application directory."
197+ exit 1
198+ fi
199+
200+ # Ensure required tools are available
201+ for tool in docker curl jq; do
202+ if ! command -v " $tool " & > /dev/null; then
203+ print_error " $tool is required but not installed."
204+ exit 1
205+ fi
206+ done
207+
208+ # Check for docker compose command
209+ if ! compose_cmd=$( get_docker_compose_cmd) ; then
210+ print_error " docker-compose or 'docker compose' is required but not available."
211+ exit 1
212+ fi
213+
214+ print_status " Using Docker Compose command: $compose_cmd "
215+
216+ # Build and start services
217+ print_status " Building and starting services with docker-compose..."
218+ $compose_cmd down --volumes --remove-orphans || true
219+ $compose_cmd up --build -d
220+
221+ # Wait for services to be ready
222+ if ! wait_for_service " http://localhost:8080/health" " Reference Application" ; then
223+ print_error " Reference application failed to start"
224+ cleanup
225+ exit 1
226+ fi
227+
228+ if ! wait_for_service " http://localhost:4318/v1/traces" " OpenTelemetry Collector OTLP HTTP" ; then
229+ print_warning " OpenTelemetry Collector OTLP HTTP endpoint not accessible"
230+ fi
231+
232+ # Run tests
233+ if test_endpoints; then
234+ print_status " ✅ Application endpoint tests passed"
235+ else
236+ print_error " ❌ Application endpoint tests failed"
237+ cleanup
238+ exit 1
239+ fi
240+
241+ test_collector
242+ test_prometheus
243+
244+ print_status " 🎉 End-to-end test completed successfully!"
245+ print_status " The reference application is working correctly with OpenTelemetry stack"
246+
247+ # Cleanup
248+ cleanup
249+
250+ print_status " ✅ All tests passed and cleanup completed"
251+ }
252+
253+ # Trap to ensure cleanup on script exit
254+ trap cleanup EXIT
255+
256+ # Run main function
257+ main " $@ "
0 commit comments