#!/bin/bash # Script de prueba para Cisco MAC Monitor # ====================================== set -e # Colores para output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Contadores TESTS_PASSED=0 TESTS_FAILED=0 # Función para logging log() { echo -e "${BLUE}[TEST]${NC} $1" } success() { echo -e "${GREEN}[PASS]${NC} $1" ((TESTS_PASSED++)) } error() { echo -e "${RED}[FAIL]${NC} $1" ((TESTS_FAILED++)) } warn() { echo -e "${YELLOW}[WARN]${NC} $1" } # Test 1: Verificar archivos necesarios test_files() { log "Verificando archivos necesarios..." local files=( "cisco_mac_monitor.py" "config.yaml" "requirements.txt" "Dockerfile" "docker-compose.yml" "entrypoint.sh" "README.md" ) for file in "${files[@]}"; do if [[ -f "$file" ]]; then success "Archivo encontrado: $file" else error "Archivo faltante: $file" fi done } # Test 2: Validar sintaxis Python test_python_syntax() { log "Validando sintaxis de Python..." if command -v python3 >/dev/null 2>&1; then if python3 -m py_compile cisco_mac_monitor.py; then success "Sintaxis de Python válida" else error "Error de sintaxis en Python" fi else warn "Python3 no disponible para test de sintaxis" fi } # Test 3: Validar archivo YAML test_yaml_syntax() { log "Validando sintaxis de YAML..." if command -v python3 >/dev/null 2>&1; then if python3 -c " import yaml try: with open('config.yaml', 'r') as f: yaml.safe_load(f) print('YAML syntax valid') except Exception as e: print(f'YAML error: {e}') exit(1) "; then success "Sintaxis de YAML válida" else error "Error de sintaxis en YAML" fi else warn "Python3 no disponible para test de YAML" fi } # Test 4: Validar Dockerfile test_dockerfile() { log "Validando Dockerfile..." if command -v docker >/dev/null 2>&1; then if docker build -t cisco-mac-monitor-test . >/dev/null 2>&1; then success "Dockerfile válido - imagen construida" # Limpiar imagen de test docker rmi cisco-mac-monitor-test >/dev/null 2>&1 || true else error "Error en construcción de Dockerfile" fi else warn "Docker no disponible para test de Dockerfile" fi } # Test 5: Validar docker-compose test_docker_compose() { log "Validando docker-compose.yml..." if command -v docker-compose >/dev/null 2>&1; then if docker-compose config >/dev/null 2>&1; then success "docker-compose.yml válido" else error "Error en docker-compose.yml" fi else warn "docker-compose no disponible para test" fi } # Test 6: Verificar dependencias Python test_python_deps() { log "Verificando dependencias de Python..." if command -v pip3 >/dev/null 2>&1; then # Crear entorno virtual temporal local temp_venv=$(mktemp -d) python3 -m venv "$temp_venv" >/dev/null 2>&1 if source "$temp_venv/bin/activate" && pip install -r requirements.txt >/dev/null 2>&1; then success "Dependencias de Python instalables" else error "Error instalando dependencias de Python" fi # Limpiar entorno temporal rm -rf "$temp_venv" deactivate 2>/dev/null || true else warn "pip3 no disponible para test de dependencias" fi } # Test 7: Validar permisos de entrypoint test_entrypoint_permissions() { log "Verificando permisos de entrypoint.sh..." if [[ -x "entrypoint.sh" ]]; then success "entrypoint.sh tiene permisos de ejecución" else warn "entrypoint.sh no tiene permisos de ejecución" chmod +x entrypoint.sh success "Permisos de ejecución agregados a entrypoint.sh" fi } # Test 8: Validar estructura de configuración test_config_structure() { log "Validando estructura de configuración..." if command -v python3 >/dev/null 2>&1; then if python3 -c " import yaml try: with open('config.yaml', 'r') as f: config = yaml.safe_load(f) # Verificar secciones requeridas required_sections = ['devices', 'monitoring'] for section in required_sections: if section not in config: print(f'Missing section: {section}') exit(1) # Verificar estructura de devices devices = config['devices'] if not isinstance(devices, list) or len(devices) == 0: print('Devices section must be a non-empty list') exit(1) # Verificar campos requeridos en devices required_device_fields = ['hostname', 'ip', 'username', 'password'] for i, device in enumerate(devices): for field in required_device_fields: if field not in device: print(f'Device {i} missing field: {field}') exit(1) print('Configuration structure valid') except Exception as e: print(f'Configuration error: {e}') exit(1) "; then success "Estructura de configuración válida" else error "Error en estructura de configuración" fi else warn "Python3 no disponible para test de configuración" fi } # Test 9: Validar JSON de ejemplo test_example_json() { log "Validando JSON de ejemplo..." if [[ -f "example_output.json" ]]; then if command -v python3 >/dev/null 2>&1; then if python3 -m json.tool example_output.json >/dev/null 2>&1; then success "JSON de ejemplo válido" else error "JSON de ejemplo inválido" fi else warn "Python3 no disponible para validación de JSON" fi else warn "Archivo example_output.json no encontrado" fi } # Test 10: Verificar documentación test_documentation() { log "Verificando documentación..." if [[ -f "README.md" ]]; then local readme_size=$(wc -c < README.md) if [[ $readme_size -gt 1000 ]]; then success "README.md presente y completo" else warn "README.md muy pequeño (${readme_size} bytes)" fi else error "README.md faltante" fi if [[ -f "zabbix_template_examples.md" ]]; then success "Documentación de Zabbix presente" else warn "Documentación de Zabbix faltante" fi } # Test de integración básica test_integration() { log "Ejecutando test de integración básica..." if command -v docker >/dev/null 2>&1; then # Construir imagen if docker build -t cisco-mac-monitor-test . >/dev/null 2>&1; then success "Imagen Docker construida correctamente" # Test de configuración en contenedor if docker run --rm cisco-mac-monitor-test test-config >/dev/null 2>&1; then success "Test de configuración en contenedor exitoso" else error "Test de configuración en contenedor falló" fi # Limpiar docker rmi cisco-mac-monitor-test >/dev/null 2>&1 || true else error "Error construyendo imagen para test de integración" fi else warn "Docker no disponible para test de integración" fi } # Función principal main() { echo "==========================================" echo " Cisco MAC Monitor - Test Suite" echo "==========================================" echo # Verificar que estamos en el directorio correcto if [[ ! -f "cisco_mac_monitor.py" ]]; then error "No se encontró cisco_mac_monitor.py. ¿Estás en el directorio correcto?" exit 1 fi # Ejecutar tests test_files test_python_syntax test_yaml_syntax test_config_structure test_entrypoint_permissions test_example_json test_documentation # Tests que requieren herramientas externas if command -v docker >/dev/null 2>&1; then test_dockerfile test_integration else warn "Docker no disponible - saltando tests de Docker" fi if command -v docker-compose >/dev/null 2>&1; then test_docker_compose else warn "docker-compose no disponible - saltando test" fi if command -v pip3 >/dev/null 2>&1; then test_python_deps else warn "pip3 no disponible - saltando test de dependencias" fi # Resumen echo echo "==========================================" echo " Resumen de Tests" echo "==========================================" echo -e "${GREEN}Tests exitosos: $TESTS_PASSED${NC}" echo -e "${RED}Tests fallidos: $TESTS_FAILED${NC}" echo if [[ $TESTS_FAILED -eq 0 ]]; then echo -e "${GREEN}🎉 Todos los tests pasaron exitosamente!${NC}" echo echo "El proyecto está listo para usar:" echo "1. Edita config.yaml con tus dispositivos" echo "2. Ejecuta: docker-compose up --build -d" echo "3. Verifica logs: docker-compose logs -f" exit 0 else echo -e "${RED}❌ Algunos tests fallaron. Revisa los errores arriba.${NC}" exit 1 fi } # Ejecutar tests main "$@"