Reestructuración modular integral de servicios, reorganización de gestión en docs/ y limpieza profunda del repositorio
This commit is contained in:
@@ -0,0 +1,489 @@
|
||||
#!/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
|
||||
Reference in New Issue
Block a user