A Rust application to showcase badge awards in the AT Protocol ecosystem.
1#!/bin/bash
2# PostgreSQL Integration Test Script
3# This script sets up PostgreSQL in Docker and runs the test suite
4
5set -e
6
7# Colors for output
8RED='\033[0;31m'
9GREEN='\033[0;32m'
10YELLOW='\033[1;33m'
11BLUE='\033[0;34m'
12NC='\033[0m' # No Color
13
14# Configuration
15POSTGRES_CONTAINER="showcase_postgres"
16TEST_DATABASE="showcase_test"
17POSTGRES_PORT="5433"
18MAX_WAIT_TIME=60
19
20# Function to print colored output
21print_info() {
22 echo -e "${BLUE}[INFO]${NC} $1"
23}
24
25print_success() {
26 echo -e "${GREEN}[SUCCESS]${NC} $1"
27}
28
29print_warning() {
30 echo -e "${YELLOW}[WARNING]${NC} $1"
31}
32
33print_error() {
34 echo -e "${RED}[ERROR]${NC} $1"
35}
36
37# Function to check if Docker is running
38check_docker() {
39 if ! docker info > /dev/null 2>&1; then
40 print_error "Docker is not running. Please start Docker and try again."
41 exit 1
42 fi
43 print_success "Docker is running"
44}
45
46# Function to check if .env.test exists
47check_env_file() {
48 if [[ ! -f ".env.test" ]]; then
49 print_warning ".env.test not found. Creating default test environment file..."
50 cat > .env.test << EOF
51DATABASE_URL=postgresql://showcase:showcase_dev_password@localhost:5433/showcase_test
52EXTERNAL_BASE=http://localhost:8080
53BADGE_ISSUERS=did:plc:test1;did:plc:test2
54HTTP_PORT=8080
55BADGE_IMAGE_STORAGE=./test_badges
56PLC_HOSTNAME=plc.directory
57HTTP_CLIENT_TIMEOUT=10s
58RUST_LOG=showcase=debug,info
59EOF
60 print_success "Created .env.test file"
61 fi
62}
63
64# Function to clean up existing container
65cleanup_container() {
66 if docker ps -a --format 'table {{.Names}}' | grep -q "^${POSTGRES_CONTAINER}$"; then
67 print_info "Stopping and removing existing PostgreSQL container..."
68 docker stop $POSTGRES_CONTAINER > /dev/null 2>&1 || true
69 docker rm $POSTGRES_CONTAINER > /dev/null 2>&1 || true
70 print_success "Cleaned up existing container"
71 fi
72}
73
74# Function to start PostgreSQL container
75start_postgres() {
76 print_info "Starting PostgreSQL container..."
77
78 if command -v docker-compose &> /dev/null && [[ -f "docker-compose.yml" ]]; then
79 # Use docker-compose if available
80 print_info "Using docker-compose to start PostgreSQL..."
81 docker-compose up -d postgres
82 else
83 # Use docker run as fallback
84 print_info "Using docker run to start PostgreSQL..."
85 docker run -d \
86 --name $POSTGRES_CONTAINER \
87 -e POSTGRES_DB=$TEST_DATABASE \
88 -e POSTGRES_USER=showcase \
89 -e POSTGRES_PASSWORD=showcase_dev_password \
90 -e POSTGRES_INITDB_ARGS="--encoding=UTF8 --locale=C" \
91 -p $POSTGRES_PORT:5432 \
92 -v showcase_postgres_data:/var/lib/postgresql/data \
93 postgres:17-alpine > /dev/null
94 fi
95
96 print_success "PostgreSQL container started"
97}
98
99# Function to wait for PostgreSQL to be ready
100wait_for_postgres() {
101 print_info "Waiting for PostgreSQL to be ready..."
102
103 local count=0
104 while [ $count -lt $MAX_WAIT_TIME ]; do
105 if docker exec $POSTGRES_CONTAINER pg_isready -U showcase -d $TEST_DATABASE > /dev/null 2>&1; then
106 print_success "PostgreSQL is ready!"
107 return 0
108 fi
109
110 printf "."
111 sleep 2
112 count=$((count + 2))
113 done
114
115 print_error "PostgreSQL failed to start within $MAX_WAIT_TIME seconds"
116 print_info "Container logs:"
117 docker logs $POSTGRES_CONTAINER
118 exit 1
119}
120
121# Function to load environment variables
122load_environment() {
123 print_info "Loading test environment variables..."
124
125 if [[ -f ".env.test" ]]; then
126 export $(cat .env.test | grep -v '^#' | xargs)
127 print_success "Environment variables loaded"
128 else
129 print_error ".env.test file not found"
130 exit 1
131 fi
132}
133
134# Function to verify database connection
135verify_connection() {
136 print_info "Verifying database connection..."
137
138 if docker exec $POSTGRES_CONTAINER psql -U showcase -d $TEST_DATABASE -c "SELECT version();" > /dev/null 2>&1; then
139 local pg_version=$(docker exec $POSTGRES_CONTAINER psql -U showcase -d $TEST_DATABASE -t -c "SELECT version();" | xargs)
140 print_success "Database connection verified: $pg_version"
141 else
142 print_error "Failed to connect to database"
143 exit 1
144 fi
145}
146
147# Function to run tests
148run_tests() {
149 print_info "Running tests with PostgreSQL backend..."
150
151 # Create test directories if they don't exist
152 mkdir -p ./test_badges
153
154 # Run the tests
155 if cargo test "$@"; then
156 print_success "All tests passed!"
157 else
158 print_error "Some tests failed"
159 return 1
160 fi
161}
162
163# Function to cleanup
164cleanup() {
165 print_info "Cleaning up..."
166
167 if command -v docker-compose &> /dev/null && [[ -f "docker-compose.yml" ]]; then
168 docker-compose down > /dev/null 2>&1 || true
169 else
170 docker stop $POSTGRES_CONTAINER > /dev/null 2>&1 || true
171 docker rm $POSTGRES_CONTAINER > /dev/null 2>&1 || true
172 fi
173
174 # Clean up test artifacts
175 rm -rf ./test_badges
176
177 print_success "Cleanup completed"
178}
179
180# Function to show usage
181usage() {
182 echo "Usage: $0 [OPTIONS] [TEST_ARGS]"
183 echo ""
184 echo "Options:"
185 echo " -h, --help Show this help message"
186 echo " -k, --keep Keep PostgreSQL container running after tests"
187 echo " -c, --clean Clean up containers and volumes before starting"
188 echo " -v, --verbose Enable verbose output"
189 echo ""
190 echo "Examples:"
191 echo " $0 # Run all tests"
192 echo " $0 storage::tests # Run only storage tests"
193 echo " $0 --keep # Run tests and keep container running"
194 echo " $0 --clean --verbose # Clean start with verbose output"
195 echo " $0 -- --nocapture # Pass --nocapture to cargo test"
196}
197
198# Parse command line arguments
199KEEP_CONTAINER=false
200CLEAN_START=false
201VERBOSE=false
202TEST_ARGS=()
203
204while [[ $# -gt 0 ]]; do
205 case $1 in
206 -h|--help)
207 usage
208 exit 0
209 ;;
210 -k|--keep)
211 KEEP_CONTAINER=true
212 shift
213 ;;
214 -c|--clean)
215 CLEAN_START=true
216 shift
217 ;;
218 -v|--verbose)
219 VERBOSE=true
220 shift
221 ;;
222 --)
223 shift
224 TEST_ARGS+=("$@")
225 break
226 ;;
227 *)
228 TEST_ARGS+=("$1")
229 shift
230 ;;
231 esac
232done
233
234# Enable verbose output if requested
235if [[ "$VERBOSE" == "true" ]]; then
236 set -x
237fi
238
239# Main execution
240main() {
241 print_info "Starting PostgreSQL integration tests..."
242
243 # Pre-flight checks
244 check_docker
245 check_env_file
246
247 # Clean up if requested
248 if [[ "$CLEAN_START" == "true" ]]; then
249 print_info "Performing clean start..."
250 cleanup_container
251 if command -v docker-compose &> /dev/null && [[ -f "docker-compose.yml" ]]; then
252 docker-compose down -v > /dev/null 2>&1 || true
253 fi
254 fi
255
256 # Setup
257 cleanup_container
258 start_postgres
259 wait_for_postgres
260 load_environment
261 verify_connection
262
263 # Run tests
264 local test_result=0
265 run_tests "${TEST_ARGS[@]}" || test_result=$?
266
267 # Cleanup unless keeping container
268 if [[ "$KEEP_CONTAINER" == "false" ]]; then
269 cleanup
270 else
271 print_info "PostgreSQL container is still running for debugging"
272 print_info "Connect with: docker exec -it $POSTGRES_CONTAINER psql -U showcase -d $TEST_DATABASE"
273 print_info "Stop with: docker stop $POSTGRES_CONTAINER"
274 fi
275
276 if [[ $test_result -eq 0 ]]; then
277 print_success "PostgreSQL integration tests completed successfully!"
278 else
279 print_error "PostgreSQL integration tests failed!"
280 exit $test_result
281 fi
282}
283
284# Trap to ensure cleanup on script exit
285trap 'if [[ "$KEEP_CONTAINER" == "false" ]]; then cleanup; fi' EXIT INT TERM
286
287# Run main function
288main "$@"