Reestructuración modular integral de servicios, reorganización de gestión en docs/ y limpieza profunda del repositorio

This commit is contained in:
Ricardo Monla
2026-03-06 18:03:07 -03:00
parent 15725e0b3c
commit ac9bdf516b
286 changed files with 36187 additions and 112775 deletions
+489
View File
@@ -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