All checks were successful
BCards Deployment Pipeline / Run Tests (push) Successful in 4s
BCards Deployment Pipeline / PR Validation (push) Has been skipped
BCards Deployment Pipeline / Build and Push Image (push) Successful in 15m22s
BCards Deployment Pipeline / Deploy to Production (ARM - OCI) (push) Successful in 1m54s
BCards Deployment Pipeline / Deploy to Test (x86 - Local) (push) Has been skipped
BCards Deployment Pipeline / Cleanup Old Resources (push) Has been skipped
BCards Deployment Pipeline / Deployment Summary (push) Successful in 0s
🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
495 lines
16 KiB
Bash
495 lines
16 KiB
Bash
#!/bin/bash
|
|
|
|
# MongoDB Connection Test Script for Release Environment
|
|
# Tests connectivity, database operations, and index validation
|
|
|
|
set -euo pipefail
|
|
|
|
# Configuration
|
|
readonly MONGODB_HOST="${MONGODB_HOST:-192.168.0.100}"
|
|
readonly MONGODB_PORT="${MONGODB_PORT:-27017}"
|
|
readonly DATABASE_NAME="${DATABASE_NAME:-BCardsDB}"
|
|
readonly CONNECTION_STRING="mongodb://${MONGODB_HOST}:${MONGODB_PORT}/${DATABASE_NAME}"
|
|
readonly TIMEOUT=30
|
|
|
|
# Colors for output
|
|
readonly RED='\033[0;31m'
|
|
readonly GREEN='\033[0;32m'
|
|
readonly YELLOW='\033[1;33m'
|
|
readonly BLUE='\033[0;34m'
|
|
readonly NC='\033[0m' # No Color
|
|
|
|
# Logging functions
|
|
log_info() {
|
|
echo -e "${BLUE}[INFO]${NC} $1"
|
|
}
|
|
|
|
log_success() {
|
|
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
|
}
|
|
|
|
log_warning() {
|
|
echo -e "${YELLOW}[WARNING]${NC} $1"
|
|
}
|
|
|
|
log_error() {
|
|
echo -e "${RED}[ERROR]${NC} $1"
|
|
}
|
|
|
|
# Test basic TCP connectivity
|
|
test_tcp_connection() {
|
|
log_info "Testing TCP connection to $MONGODB_HOST:$MONGODB_PORT..."
|
|
|
|
if timeout $TIMEOUT bash -c "</dev/tcp/$MONGODB_HOST/$MONGODB_PORT" 2>/dev/null; then
|
|
log_success "TCP connection successful"
|
|
return 0
|
|
else
|
|
log_error "TCP connection failed"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Test MongoDB connectivity using mongosh if available
|
|
test_mongodb_with_mongosh() {
|
|
if ! command -v mongosh >/dev/null 2>&1; then
|
|
log_warning "mongosh not available, skipping MongoDB shell tests"
|
|
return 1
|
|
fi
|
|
|
|
log_info "Testing MongoDB connection with mongosh..."
|
|
|
|
# Test basic connection
|
|
local test_output=$(timeout $TIMEOUT mongosh "$CONNECTION_STRING" --quiet --eval "db.runCommand({ping: 1})" 2>/dev/null || echo "FAILED")
|
|
|
|
if [[ "$test_output" == *"ok"* ]]; then
|
|
log_success "MongoDB ping successful"
|
|
else
|
|
log_error "MongoDB ping failed"
|
|
return 1
|
|
fi
|
|
|
|
# Test database access
|
|
log_info "Testing database operations..."
|
|
|
|
local db_test=$(timeout $TIMEOUT mongosh "$CONNECTION_STRING" --quiet --eval "
|
|
try {
|
|
// Test basic database operations
|
|
db.connection_test.insertOne({test: true, timestamp: new Date()});
|
|
var result = db.connection_test.findOne({test: true});
|
|
db.connection_test.deleteOne({test: true});
|
|
print('DATABASE_ACCESS_OK');
|
|
} catch (e) {
|
|
print('DATABASE_ACCESS_FAILED: ' + e.message);
|
|
}
|
|
" 2>/dev/null || echo "DATABASE_ACCESS_FAILED")
|
|
|
|
if [[ "$db_test" == *"DATABASE_ACCESS_OK"* ]]; then
|
|
log_success "Database operations test passed"
|
|
else
|
|
log_error "Database operations test failed: $db_test"
|
|
return 1
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
# Test MongoDB connectivity using Python if available
|
|
test_mongodb_with_python() {
|
|
if ! command -v python3 >/dev/null 2>&1; then
|
|
log_warning "Python3 not available, skipping Python MongoDB tests"
|
|
return 1
|
|
fi
|
|
|
|
log_info "Testing MongoDB connection with Python..."
|
|
|
|
python3 << EOF
|
|
import sys
|
|
try:
|
|
import pymongo
|
|
from pymongo import MongoClient
|
|
import socket
|
|
|
|
# Test connection
|
|
client = MongoClient("$CONNECTION_STRING", serverSelectionTimeoutMS=$((TIMEOUT * 1000)))
|
|
|
|
# Test ping
|
|
client.admin.command('ping')
|
|
print("MongoDB ping successful (Python)")
|
|
|
|
# Test database access
|
|
db = client["$DATABASE_NAME"]
|
|
|
|
# Insert test document
|
|
test_collection = db.connection_test
|
|
result = test_collection.insert_one({"test": True, "source": "python"})
|
|
|
|
# Read test document
|
|
doc = test_collection.find_one({"_id": result.inserted_id})
|
|
if doc:
|
|
print("Database read/write test passed (Python)")
|
|
|
|
# Cleanup
|
|
test_collection.delete_one({"_id": result.inserted_id})
|
|
|
|
client.close()
|
|
print("PYTHON_TEST_SUCCESS")
|
|
|
|
except ImportError:
|
|
print("PyMongo not installed, skipping Python tests")
|
|
sys.exit(1)
|
|
except Exception as e:
|
|
print(f"Python MongoDB test failed: {e}")
|
|
sys.exit(1)
|
|
EOF
|
|
|
|
local python_result=$?
|
|
if [ $python_result -eq 0 ]; then
|
|
log_success "Python MongoDB test passed"
|
|
return 0
|
|
else
|
|
log_error "Python MongoDB test failed"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Test using Docker MongoDB client
|
|
test_mongodb_with_docker() {
|
|
if ! command -v docker >/dev/null 2>&1; then
|
|
log_warning "Docker not available, skipping Docker MongoDB tests"
|
|
return 1
|
|
fi
|
|
|
|
log_info "Testing MongoDB connection using Docker MongoDB client..."
|
|
|
|
# Use official MongoDB image to test connection
|
|
local docker_test=$(timeout $TIMEOUT docker run --rm mongo:7.0 mongosh "$CONNECTION_STRING" --quiet --eval "
|
|
try {
|
|
db.runCommand({ping: 1});
|
|
db.connection_test.insertOne({test: true, source: 'docker', timestamp: new Date()});
|
|
var doc = db.connection_test.findOne({source: 'docker'});
|
|
db.connection_test.deleteOne({source: 'docker'});
|
|
print('DOCKER_TEST_SUCCESS');
|
|
} catch (e) {
|
|
print('DOCKER_TEST_FAILED: ' + e.message);
|
|
}
|
|
" 2>/dev/null || echo "DOCKER_TEST_FAILED")
|
|
|
|
if [[ "$docker_test" == *"DOCKER_TEST_SUCCESS"* ]]; then
|
|
log_success "Docker MongoDB test passed"
|
|
return 0
|
|
else
|
|
log_error "Docker MongoDB test failed: $docker_test"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Test MongoDB from application container
|
|
test_from_application_container() {
|
|
local container_name="bcards-staging"
|
|
|
|
if ! docker ps --format "{{.Names}}" | grep -q "^${container_name}$"; then
|
|
log_warning "Application container '$container_name' not running, skipping application test"
|
|
return 1
|
|
fi
|
|
|
|
log_info "Testing MongoDB connection from application container..."
|
|
|
|
# Test connection from the application container
|
|
local app_test=$(docker exec "$container_name" timeout 10 bash -c "
|
|
# Test TCP connection
|
|
if timeout 5 bash -c '</dev/tcp/$MONGODB_HOST/$MONGODB_PORT' 2>/dev/null; then
|
|
echo 'APP_TCP_OK'
|
|
else
|
|
echo 'APP_TCP_FAILED'
|
|
exit 1
|
|
fi
|
|
|
|
# Test HTTP health endpoint if available
|
|
if curl -f -s http://localhost:8080/health >/dev/null 2>&1; then
|
|
echo 'APP_HEALTH_OK'
|
|
else
|
|
echo 'APP_HEALTH_FAILED'
|
|
fi
|
|
" 2>/dev/null || echo "APP_TEST_FAILED")
|
|
|
|
if [[ "$app_test" == *"APP_TCP_OK"* ]]; then
|
|
log_success "Application container can connect to MongoDB"
|
|
|
|
if [[ "$app_test" == *"APP_HEALTH_OK"* ]]; then
|
|
log_success "Application health check passed"
|
|
else
|
|
log_warning "Application health check failed - app may still be starting"
|
|
fi
|
|
return 0
|
|
else
|
|
log_error "Application container cannot connect to MongoDB"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Check MongoDB server status and version
|
|
check_mongodb_status() {
|
|
log_info "Checking MongoDB server status..."
|
|
|
|
# Try multiple methods to check status
|
|
local status_checked=false
|
|
|
|
# Method 1: Using mongosh
|
|
if command -v mongosh >/dev/null 2>&1; then
|
|
local server_status=$(timeout $TIMEOUT mongosh "$CONNECTION_STRING" --quiet --eval "
|
|
try {
|
|
var status = db.runCommand({serverStatus: 1});
|
|
print('MongoDB Version: ' + status.version);
|
|
print('Uptime: ' + status.uptime + ' seconds');
|
|
print('Connections: ' + status.connections.current + '/' + status.connections.available);
|
|
print('STATUS_CHECK_OK');
|
|
} catch (e) {
|
|
print('STATUS_CHECK_FAILED: ' + e.message);
|
|
}
|
|
" 2>/dev/null || echo "STATUS_CHECK_FAILED")
|
|
|
|
if [[ "$server_status" == *"STATUS_CHECK_OK"* ]]; then
|
|
echo "$server_status" | grep -v "STATUS_CHECK_OK"
|
|
log_success "MongoDB server status check passed"
|
|
status_checked=true
|
|
fi
|
|
fi
|
|
|
|
# Method 2: Using Docker if mongosh failed
|
|
if [ "$status_checked" = false ] && command -v docker >/dev/null 2>&1; then
|
|
local docker_status=$(timeout $TIMEOUT docker run --rm mongo:7.0 mongosh "$CONNECTION_STRING" --quiet --eval "
|
|
try {
|
|
var status = db.runCommand({serverStatus: 1});
|
|
print('MongoDB Version: ' + status.version);
|
|
print('STATUS_CHECK_OK');
|
|
} catch (e) {
|
|
print('STATUS_CHECK_FAILED: ' + e.message);
|
|
}
|
|
" 2>/dev/null || echo "STATUS_CHECK_FAILED")
|
|
|
|
if [[ "$docker_status" == *"STATUS_CHECK_OK"* ]]; then
|
|
echo "$docker_status" | grep -v "STATUS_CHECK_OK"
|
|
log_success "MongoDB server status check passed (via Docker)"
|
|
status_checked=true
|
|
fi
|
|
fi
|
|
|
|
if [ "$status_checked" = false ]; then
|
|
log_warning "Could not retrieve MongoDB server status"
|
|
return 1
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
# Test BCards specific collections and indexes
|
|
test_bcards_collections() {
|
|
if ! command -v mongosh >/dev/null 2>&1 && ! command -v docker >/dev/null 2>&1; then
|
|
log_warning "Cannot test BCards collections - no MongoDB client available"
|
|
return 1
|
|
fi
|
|
|
|
log_info "Testing BCards specific collections and indexes..."
|
|
|
|
local mongo_cmd="mongosh"
|
|
local docker_prefix=""
|
|
|
|
if ! command -v mongosh >/dev/null 2>&1; then
|
|
mongo_cmd="docker run --rm mongo:7.0 mongosh"
|
|
docker_prefix="timeout $TIMEOUT "
|
|
fi
|
|
|
|
local collections_test=$(${docker_prefix}${mongo_cmd} "$CONNECTION_STRING" --quiet --eval "
|
|
try {
|
|
// Check required collections
|
|
var collections = db.listCollectionNames();
|
|
var requiredCollections = ['users', 'userpages', 'categories'];
|
|
var missingCollections = [];
|
|
|
|
requiredCollections.forEach(function(collection) {
|
|
if (collections.indexOf(collection) === -1) {
|
|
missingCollections.push(collection);
|
|
}
|
|
});
|
|
|
|
if (missingCollections.length > 0) {
|
|
print('Missing collections: ' + missingCollections.join(', '));
|
|
} else {
|
|
print('All required collections exist');
|
|
}
|
|
|
|
// Check indexes on userpages collection
|
|
if (collections.indexOf('userpages') !== -1) {
|
|
var indexes = db.userpages.getIndexes();
|
|
print('UserPages collection has ' + indexes.length + ' indexes');
|
|
|
|
// Check for important compound index
|
|
var hasCompoundIndex = indexes.some(function(index) {
|
|
return index.key && index.key.category && index.key.slug;
|
|
});
|
|
|
|
if (hasCompoundIndex) {
|
|
print('Required compound index (category, slug) exists');
|
|
} else {
|
|
print('WARNING: Compound index (category, slug) is missing');
|
|
}
|
|
}
|
|
|
|
print('COLLECTIONS_TEST_OK');
|
|
} catch (e) {
|
|
print('COLLECTIONS_TEST_FAILED: ' + e.message);
|
|
}
|
|
" 2>/dev/null || echo "COLLECTIONS_TEST_FAILED")
|
|
|
|
if [[ "$collections_test" == *"COLLECTIONS_TEST_OK"* ]]; then
|
|
echo "$collections_test" | grep -v "COLLECTIONS_TEST_OK"
|
|
log_success "BCards collections test passed"
|
|
return 0
|
|
else
|
|
log_warning "BCards collections test had issues: $collections_test"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Performance test
|
|
test_mongodb_performance() {
|
|
log_info "Running basic performance test..."
|
|
|
|
if ! command -v mongosh >/dev/null 2>&1; then
|
|
log_warning "mongosh not available, skipping performance test"
|
|
return 1
|
|
fi
|
|
|
|
local perf_test=$(timeout $TIMEOUT mongosh "$CONNECTION_STRING" --quiet --eval "
|
|
try {
|
|
var start = new Date();
|
|
|
|
// Insert test documents
|
|
var docs = [];
|
|
for (var i = 0; i < 100; i++) {
|
|
docs.push({test: true, index: i, timestamp: new Date()});
|
|
}
|
|
db.performance_test.insertMany(docs);
|
|
|
|
// Read test
|
|
var count = db.performance_test.countDocuments({test: true});
|
|
|
|
// Update test
|
|
db.performance_test.updateMany({test: true}, {\$set: {updated: true}});
|
|
|
|
// Delete test
|
|
db.performance_test.deleteMany({test: true});
|
|
|
|
var end = new Date();
|
|
var duration = end - start;
|
|
|
|
print('Performance test completed in ' + duration + 'ms');
|
|
print('Operations: 100 inserts, 1 count, 100 updates, 100 deletes');
|
|
|
|
if (duration < 5000) {
|
|
print('PERFORMANCE_TEST_OK');
|
|
} else {
|
|
print('PERFORMANCE_TEST_SLOW');
|
|
}
|
|
} catch (e) {
|
|
print('PERFORMANCE_TEST_FAILED: ' + e.message);
|
|
}
|
|
" 2>/dev/null || echo "PERFORMANCE_TEST_FAILED")
|
|
|
|
if [[ "$perf_test" == *"PERFORMANCE_TEST_OK"* ]]; then
|
|
echo "$perf_test" | grep -v "PERFORMANCE_TEST_OK"
|
|
log_success "Performance test passed"
|
|
return 0
|
|
elif [[ "$perf_test" == *"PERFORMANCE_TEST_SLOW"* ]]; then
|
|
echo "$perf_test" | grep -v "PERFORMANCE_TEST_SLOW"
|
|
log_warning "Performance test completed but was slow"
|
|
return 0
|
|
else
|
|
log_error "Performance test failed: $perf_test"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Display connection summary
|
|
display_summary() {
|
|
echo ""
|
|
log_info "MongoDB Connection Test Summary"
|
|
echo "=================================================="
|
|
echo "🏠 Host: $MONGODB_HOST:$MONGODB_PORT"
|
|
echo "🗄️ Database: $DATABASE_NAME"
|
|
echo "🔗 Connection String: $CONNECTION_STRING"
|
|
echo "⏱️ Timeout: ${TIMEOUT}s"
|
|
echo "📊 Tests completed: $(date)"
|
|
echo "=================================================="
|
|
}
|
|
|
|
# Main test function
|
|
main() {
|
|
log_info "Starting MongoDB connection tests for Release environment"
|
|
|
|
local test_results=()
|
|
local overall_success=true
|
|
|
|
# Run all tests
|
|
if test_tcp_connection; then
|
|
test_results+=("✅ TCP Connection")
|
|
else
|
|
test_results+=("❌ TCP Connection")
|
|
overall_success=false
|
|
fi
|
|
|
|
if test_mongodb_with_mongosh; then
|
|
test_results+=("✅ MongoDB Shell")
|
|
elif test_mongodb_with_docker; then
|
|
test_results+=("✅ MongoDB Docker")
|
|
elif test_mongodb_with_python; then
|
|
test_results+=("✅ MongoDB Python")
|
|
else
|
|
test_results+=("❌ MongoDB Client")
|
|
overall_success=false
|
|
fi
|
|
|
|
if test_from_application_container; then
|
|
test_results+=("✅ Application Container")
|
|
else
|
|
test_results+=("⚠️ Application Container")
|
|
fi
|
|
|
|
if check_mongodb_status; then
|
|
test_results+=("✅ Server Status")
|
|
else
|
|
test_results+=("⚠️ Server Status")
|
|
fi
|
|
|
|
if test_bcards_collections; then
|
|
test_results+=("✅ BCards Collections")
|
|
else
|
|
test_results+=("⚠️ BCards Collections")
|
|
fi
|
|
|
|
if test_mongodb_performance; then
|
|
test_results+=("✅ Performance Test")
|
|
else
|
|
test_results+=("⚠️ Performance Test")
|
|
fi
|
|
|
|
# Display results
|
|
display_summary
|
|
echo ""
|
|
log_info "Test Results:"
|
|
for result in "${test_results[@]}"; do
|
|
echo " $result"
|
|
done
|
|
|
|
echo ""
|
|
if [ "$overall_success" = true ]; then
|
|
log_success "All critical MongoDB tests passed!"
|
|
exit 0
|
|
else
|
|
log_error "Some critical MongoDB tests failed!"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# Run main function
|
|
main "$@" |