490 lines
14 KiB
Ruby
490 lines
14 KiB
Ruby
#!/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/adn/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__, 'adn', '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
|