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