#!/usr/bin/env ruby # frozen_string_literal: true # tools/probar_buscador.rb — Script de prueba para sistema de búsqueda # ================================================================================ # Este script prueba la funcionalidad del sistema de búsqueda y filtrado # implementado en tools/bitacoras-db/core/buscador_bd.rb # # Uso: # ruby tools/probar_buscador.rb [OPCIONES] # # Opciones: # --test-all Ejecutar todas las pruebas # --test-entradas Probar búsqueda en entradas # --test-nodos Probar búsqueda en nodos # --test-temas Probar búsqueda en temas # --test-bitacoras Probar búsqueda en bitácoras # --test-avanzado Probar búsqueda avanzada # --test-indices Probar creación de índices # --test-metricas Probar métricas de rendimiento # --verbose Mostrar detalles de ejecución # --help Mostrar ayuda # # Ejemplos: # ruby tools/probar_buscador.rb --test-all # ruby tools/probar_buscador.rb --test-entradas --test-nodos # ruby tools/probar_buscador.rb --test-indices --verbose require 'pg' require 'yaml' require 'optparse' require 'json' # Cargar módulos locales $LOAD_PATH.unshift(File.join(__dir__, 'bitacoras-db', 'core')) require 'buscador_bd' class ProbadorBuscador def initialize(opciones) @opciones = opciones @config = cargar_configuracion @conn = nil @buscador = nil @resultados_pruebas = [] @tiempo_inicio = Time.now end def ejecutar puts "🔍 PROBANDO SISTEMA DE BÚSQUEDA ADN BITACORAS" puts "=" * 70 puts "Fecha: #{Time.now.strftime('%Y-%m-%d %H:%M:%S')}" puts "" conectar_bd inicializar_buscador # Ejecutar pruebas según opciones if @opciones[:test_all] || @opciones[:test_entradas] probar_busqueda_entradas end if @opciones[:test_all] || @opciones[:test_nodos] probar_busqueda_nodos end if @opciones[:test_all] || @opciones[:test_temas] probar_busqueda_temas end if @opciones[:test_all] || @opciones[:test_bitacoras] probar_busqueda_bitacoras end if @opciones[:test_all] || @opciones[:test_avanzado] probar_busqueda_avanzada end if @opciones[:test_all] || @opciones[:test_indices] probar_creacion_indices end if @opciones[:test_all] || @opciones[:test_metricas] probar_metricas_rendimiento end mostrar_resumen ensure desconectar_bd end private def cargar_configuracion config_path = File.join(__dir__, 'config', 'database.yml') unless File.exist?(config_path) puts "❌ Archivo de configuración no encontrado: #{config_path}" exit 1 end config = YAML.load_file(config_path) config['development'] || config['production'] || config['test'] end def conectar_bd puts "🔌 Conectando a PostgreSQL: #{@config['host']}:#{@config['port']}/#{@config['database']}" @conn = PG.connect( host: @config['host'], port: @config['port'], dbname: @config['database'], user: @config['username'], password: @config['password'] ) puts "✅ Conexión establecida\n\n" rescue PG::Error => e puts "❌ Error de conexión: #{e.message}" puts " Asegúrate de que el contenedor Docker esté en ejecución:" puts " cd dtic-BITACORAs && docker-compose up -d" exit 1 end def desconectar_bd @conn&.close puts "\n🔌 Conexión cerrada" end def inicializar_buscador puts "🚀 Inicializando BuscadorBD..." @buscador = BitacorasDB::BuscadorBD.new(@conn) puts "✅ BuscadorBD inicializado\n\n" end def probar_busqueda_entradas registrar_prueba("Búsqueda en entradas") do puts "📋 Probando búsqueda en entradas..." puts "-" * 50 # 1. Búsqueda simple por texto puts "1. Búsqueda simple por texto 'dashboard':" resultados = @buscador.buscar_entradas(texto: "dashboard", limite: 5, formato: :texto) mostrar_resultados(resultados, 5) # 2. Filtrado por estado puts "\n2. Filtrado por estado '✅' (completado):" resultados = @buscador.buscar_entradas(estado: "✅", limite: 3, formato: :texto) mostrar_resultados(resultados, 3) # 3. Filtrado por modo puts "\n3. Filtrado por modo 'P' (presencial):" resultados = @buscador.buscar_entradas(modo: "P", limite: 3, formato: :texto) mostrar_resultados(resultados, 3) # 4. Búsqueda combinada puts "\n4. Búsqueda combinada (texto + estado):" resultados = @buscador.buscar_entradas( texto: "sistema", estado: "⏳", limite: 3, formato: :texto ) mostrar_resultados(resultados, 3) # 5. Formato JSON puts "\n5. Búsqueda en formato JSON (primeros 2 resultados):" resultados_json = @buscador.buscar_entradas(limite: 2, formato: :json) if resultados_json && !resultados_json.empty? parsed = JSON.parse(resultados_json) puts " • Total resultados: #{parsed.size}" puts " • Primer resultado: #{parsed.first['descripcion'][0..50]}..." if parsed.any? end true end end def probar_busqueda_nodos registrar_prueba("Búsqueda en nodos") do puts "📋 Probando búsqueda en nodos..." puts "-" * 50 # 1. Búsqueda por nombre puts "1. Búsqueda por nombre 'ns8':" resultados = @buscador.buscar_nodos(texto: "ns8", limite: 5, formato: :texto) mostrar_resultados(resultados, 5) # 2. Filtrado por tipo puts "\n2. Filtrado por tipo 'servidor':" resultados = @buscador.buscar_nodos(tipo: "servidor", limite: 5, formato: :texto) mostrar_resultados(resultados, 5) # 3. Nodos activos puts "\n3. Nodos activos:" resultados = @buscador.buscar_nodos(activo: true, limite: 10, formato: :texto) mostrar_resultados(resultados, 10) true end end def probar_busqueda_temas registrar_prueba("Búsqueda en temas") do puts "📋 Probando búsqueda en temas..." puts "-" * 50 # 1. Búsqueda por texto puts "1. Búsqueda por texto 'implementación':" resultados = @buscador.buscar_temas(texto: "implementación", limite: 5, formato: :texto) mostrar_resultados(resultados, 5) # 2. Filtrado por estado puts "\n2. Temas con estado '✅':" resultados = @buscador.buscar_temas(estado: "✅", limite: 5, formato: :texto) mostrar_resultados(resultados, 5) true end end def probar_busqueda_bitacoras registrar_prueba("Búsqueda en bitácoras") do puts "📋 Probando búsqueda en bitácoras..." puts "-" * 50 # 1. Últimas bitácoras puts "1. Últimas 5 bitácoras:" resultados = @buscador.buscar_bitacoras(limite: 5, formato: :texto) mostrar_resultados(resultados, 5) # 2. Búsqueda en resumen puts "\n2. Búsqueda en resumen 'trabajo':" resultados = @buscador.buscar_bitacoras(texto: "trabajo", limite: 3, formato: :texto) mostrar_resultados(resultados, 3) true end end def probar_busqueda_avanzada registrar_prueba("Búsqueda avanzada") do puts "📋 Probando búsqueda avanzada..." puts "-" * 50 puts "Búsqueda en todas las tablas por 'sistema':" resultados = @buscador.buscar_avanzado( texto: "sistema", tipos: [:entradas, :temas, :nodos, :bitacoras], limite_por_tipo: 3, formato: :hash ) if resultados[:estadisticas] stats = resultados[:estadisticas] puts " • Total resultados: #{stats[:total_resultados]}" puts " • Tipos buscados: #{stats[:tipos_buscados].join(', ')}" puts " • Texto buscado: #{stats[:texto_buscado]}" end [:entradas, :temas, :nodos, :bitacoras].each do |tipo| if resultados[tipo] && resultados[tipo].any? puts " • #{tipo}: #{resultados[tipo].size} resultados" end end true end end def probar_creacion_indices registrar_prueba("Creación de índices") do puts "📋 Probando creación de índices recomendados..." puts "-" * 50 puts "Creando índices para optimización..." resultado = @buscador.crear_indices_recomendados if resultado puts " • Total índices: #{resultado[:total_indices]}" puts " • Índices creados: #{resultado[:creados]}" puts " • Errores: #{resultado[:errores]}" if @opciones[:verbose] && resultado[:detalles] puts "\n Detalles:" resultado[:detalles].each do |detalle| estado = detalle[:estado] == 'creado' ? '✅' : '❌' puts " #{estado} #{detalle[:indice].split(' ON ').first}" end end end true end end def probar_metricas_rendimiento registrar_prueba("Métricas de rendimiento") do puts "📋 Probando métricas de rendimiento..." puts "-" * 50 metricas = @buscador.metricas_rendimiento if metricas[:tamanos_tablas] puts "Tamaños de tablas:" metricas[:tamanos_tablas].each do |tabla| puts " • #{tabla['table_name']}: #{tabla['tamaño_total']} (#{tabla['registros']} registros)" end end if metricas[:indices_uso] && metricas[:indices_uso].any? puts "\nÍndices más usados:" metricas[:indices_uso].first(3).each do |indice| puts " • #{indice['nombre_indice']}: #{indice['escaneos']} escaneos" end end if metricas[:metricas_internas] puts "\nMétricas internas:" metricas[:metricas_internas].each do |key, value| puts " • #{key}: #{value}" end end true end end def registrar_prueba(nombre, &block) puts "\n🧪 PRUEBA: #{nombre}" inicio = Time.now begin resultado = block.call duracion = Time.now - inicio @resultados_pruebas << { nombre: nombre, estado: resultado ? '✅' : '❌', duracion: duracion.round(3), timestamp: Time.now.strftime('%H:%M:%S') } puts " Duración: #{duracion.round(3)}s" puts " Estado: #{resultado ? '✅ PASÓ' : '❌ FALLÓ'}" puts "" resultado rescue => e duracion = Time.now - inicio @resultados_pruebas << { nombre: nombre, estado: '💥', duracion: duracion.round(3), error: e.message, timestamp: Time.now.strftime('%H:%M:%S') } puts " ❌ ERROR: #{e.message}" puts " Backtrace: #{e.backtrace.first}" if @opciones[:verbose] puts " Duración: #{duracion.round(3)}s" puts "" false end end def mostrar_resultados(resultados, max_mostrar = 3) if resultados.is_a?(String) # Formato texto lineas = resultados.split("\n") lineas.first(max_mostrar * 5).each do |linea| puts " #{linea}" unless linea.strip.empty? end puts " ..." if lineas.size > max_mostrar * 5 elsif resultados.is_a?(Array) # Formato hash/array puts " • Total resultados: #{resultados.size}" resultados.first(max_mostrar).each_with_index do |resultado, idx| if resultado.is_a?(Hash) desc = resultado['descripcion'] || resultado['nombre'] || resultado['titulo'] || 'Sin título' puts " #{idx + 1}. #{desc[0..60]}..." end end puts " ..." if resultados.size > max_mostrar else puts " • Resultados: #{resultados.inspect[0..100]}..." end end def mostrar_resumen tiempo_total = Time.now - @tiempo_inicio puts "\n" + "=" * 70 puts "📊 RESUMEN DE PRUEBAS" puts "=" * 70 @resultados_pruebas.each do |prueba| puts " #{prueba[:estado]} #{prueba[:nombre]} (#{prueba[:duracion]}s)" if prueba[:error] puts " Error: #{prueba[:error][0..100]}..." end end puts "\n📈 ESTADÍSTICAS:" puts " • Total pruebas: #{@resultados_pruebas.size}" puts " • Pruebas exitosas: #{@resultados_pruebas.count { |p| p[:estado] == '✅' }}" puts " • Pruebas fallidas: #{@resultados_pruebas.count { |p| p[:estado] == '❌' }}" puts " • Errores: #{@resultados_pruebas.count { |p| p[:estado] == '💥' }}" puts " • Tiempo total: #{tiempo_total.round(2)}s" exit_code = @resultados_pruebas.any? { |p| p[:estado] != '✅' } ? 1 : 0 puts "\n🚀 Resultado: #{exit_code == 0 ? '✅ TODAS LAS PRUEBAS PASARON' : '❌ ALGUNAS PRUEBAS FALLARON'}" puts "=" * 70 exit exit_code end end # Parsear opciones de línea de comandos opciones = { test_all: false, test_entradas: false, test_nodos: false, test_temas: false, test_bitacoras: false, test_avanzado: false, test_indices: false, test_metricas: false, verbose: false } OptionParser.new do |opts| opts.banner = "Uso: ruby tools/probar_buscador.rb [OPCIONES]" opts.on("--test-all", "Ejecutar todas las pruebas") do opciones[:test_all] = true end opts.on("--test-entradas", "Probar búsqueda en entradas") do opciones[:test_entradas] = true end opts.on("--test-nodos", "Probar búsqueda en nodos") do opciones[:test_nodos] = true end opts.on("--test-temas", "Probar búsqueda en temas") do opciones[:test_temas] = true end opts.on("--test-bitacoras", "Probar búsqueda en bitácoras") do opciones[:test_bitacoras] = true end opts.on("--test-avanzado", "Probar búsqueda avanzada") do opciones[:test_avanzado] = true end opts.on("--test-indices", "Probar creación de índices") do opciones[:test_indices] = true end opts.on("--test-metricas", "Probar métricas de rendimiento") do opciones[:test_metricas] = true end opts.on("--verbose", "Mostrar detalles de ejecución") do opciones[:verbose] = true end opts.on("-h", "--help", "Mostrar ayuda") do puts opts exit end end.parse! # Si no se especificó ninguna prueba, ejecutar todas if opciones.values.none? { |v| v == true } opciones[:test_all] = true end # Ejecutar probador begin probador = ProbadorBuscador.new(opciones) probador.ejecutar rescue => e puts "❌ Error fatal: #{e.message}" puts e.backtrace if opciones[:verbose] exit 1 end