172 lines
6.1 KiB
Python
172 lines
6.1 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Test script para verificar la detección de cambios basada en hash.
|
|
|
|
Este script demuestra cómo el sistema detecta cambios en archivos XML
|
|
utilizando hash SHA256 en lugar de solo tiempo/tamaño de archivo.
|
|
"""
|
|
|
|
import os
|
|
import json
|
|
import hashlib
|
|
import tempfile
|
|
import shutil
|
|
from datetime import datetime
|
|
|
|
|
|
def calculate_file_hash(filepath):
|
|
"""Calcula el hash SHA256 de un archivo."""
|
|
try:
|
|
sha256_hash = hashlib.sha256()
|
|
with open(filepath, "rb") as f:
|
|
for chunk in iter(lambda: f.read(4096), b""):
|
|
sha256_hash.update(chunk)
|
|
return sha256_hash.hexdigest()
|
|
except Exception as e:
|
|
print(f"Error calculando hash de {filepath}: {e}")
|
|
return None
|
|
|
|
|
|
def create_test_xml(content, filepath):
|
|
"""Crea un archivo XML de prueba con el contenido especificado."""
|
|
with open(filepath, "w", encoding="utf-8") as f:
|
|
f.write(content)
|
|
|
|
|
|
def create_test_json(xml_filepath, json_filepath):
|
|
"""Crea un archivo JSON de prueba con metadatos del XML."""
|
|
xml_hash = calculate_file_hash(xml_filepath)
|
|
xml_mtime = os.path.getmtime(xml_filepath)
|
|
xml_size = os.path.getsize(xml_filepath)
|
|
|
|
json_data = {
|
|
"block_name": "Test_Block",
|
|
"block_type": "FC",
|
|
"language": "LAD",
|
|
"source_xml_mod_time": xml_mtime,
|
|
"source_xml_size": xml_size,
|
|
"source_xml_hash": xml_hash,
|
|
"interface": {},
|
|
"networks": [],
|
|
}
|
|
|
|
with open(json_filepath, "w", encoding="utf-8") as f:
|
|
json.dump(json_data, f, indent=4)
|
|
|
|
return json_data
|
|
|
|
|
|
def test_hash_detection():
|
|
"""Prueba la detección de cambios basada en hash."""
|
|
print("=== Test de Detección de Cambios por Hash ===\n")
|
|
|
|
# Crear directorio temporal
|
|
with tempfile.TemporaryDirectory() as temp_dir:
|
|
xml_file = os.path.join(temp_dir, "test_block.xml")
|
|
json_file = os.path.join(temp_dir, "test_block_processed.json")
|
|
|
|
# Paso 1: Crear XML original
|
|
original_content = """<?xml version="1.0" encoding="UTF-8"?>
|
|
<Document>
|
|
<SW.Blocks.FC ID="A">
|
|
<AttributeList>
|
|
<Name>Test_Block</Name>
|
|
<Number>100</Number>
|
|
<ProgrammingLanguage>LAD</ProgrammingLanguage>
|
|
</AttributeList>
|
|
<ObjectList>
|
|
<NetworkSource />
|
|
</ObjectList>
|
|
</SW.Blocks.FC>
|
|
</Document>"""
|
|
|
|
create_test_xml(original_content, xml_file)
|
|
original_hash = calculate_file_hash(xml_file)
|
|
print(f"1. XML original creado")
|
|
print(f" Hash: {original_hash[:16]}...")
|
|
print(f" Tamaño: {os.path.getsize(xml_file)} bytes")
|
|
|
|
# Paso 2: Crear JSON con metadatos
|
|
json_data = create_test_json(xml_file, json_file)
|
|
print(f"\n2. JSON con metadatos creado")
|
|
print(f" Hash almacenado: {json_data['source_xml_hash'][:16]}...")
|
|
|
|
# Paso 3: Simular verificación - archivo sin cambios
|
|
current_hash = calculate_file_hash(xml_file)
|
|
hash_match = json_data["source_xml_hash"] == current_hash
|
|
print(f"\n3. Verificación sin cambios:")
|
|
print(f" Hash actual: {current_hash[:16]}...")
|
|
print(f" ¿Hash coincide?: {hash_match}")
|
|
print(f" → {'SALTAR procesamiento' if hash_match else 'PROCESAR archivo'}")
|
|
|
|
# Paso 4: Modificar archivo manteniendo mismo tamaño y tiempo
|
|
print(f"\n4. Modificando XML (cambio sutil)...")
|
|
modified_content = original_content.replace(
|
|
"Test_Block", "Test_Blck"
|
|
) # Cambio sutil
|
|
|
|
# Guardar tiempo original
|
|
original_mtime = os.path.getmtime(xml_file)
|
|
|
|
create_test_xml(modified_content, xml_file)
|
|
|
|
# Restaurar tiempo original (simular que el timestamp no cambió)
|
|
os.utime(xml_file, (original_mtime, original_mtime))
|
|
|
|
new_size = os.path.getsize(xml_file)
|
|
new_mtime = os.path.getmtime(xml_file)
|
|
new_hash = calculate_file_hash(xml_file)
|
|
|
|
print(f" Nuevo hash: {new_hash[:16]}...")
|
|
print(f" Nuevo tamaño: {new_size} bytes")
|
|
print(
|
|
f" Tiempo modificación: {abs(new_mtime - json_data['source_xml_mod_time']) < 0.001}"
|
|
)
|
|
|
|
# Paso 5: Verificar detección por diferentes métodos
|
|
print(f"\n5. Comparación de métodos de detección:")
|
|
|
|
# Método tradicional (tiempo + tamaño)
|
|
time_match = abs(new_mtime - json_data["source_xml_mod_time"]) < 0.001
|
|
size_match = new_size == json_data["source_xml_size"]
|
|
traditional_would_skip = time_match and size_match
|
|
|
|
# Método por hash
|
|
hash_would_skip = new_hash == json_data["source_xml_hash"]
|
|
|
|
print(f" Método tradicional (tiempo+tamaño):")
|
|
print(f" ¿Tiempo coincide?: {time_match}")
|
|
print(f" ¿Tamaño coincide?: {size_match}")
|
|
print(f" → {'SALTAR' if traditional_would_skip else 'PROCESAR'}")
|
|
|
|
print(f" Método por hash:")
|
|
print(f" ¿Hash coincide?: {hash_would_skip}")
|
|
print(f" → {'SALTAR' if hash_would_skip else 'PROCESAR'}")
|
|
|
|
print(f"\n6. Resultado:")
|
|
if traditional_would_skip and not hash_would_skip:
|
|
print(f" ✅ HASH DETECTÓ CAMBIO que el método tradicional PERDIÓ")
|
|
print(f" 🔄 El archivo será regenerado correctamente")
|
|
elif not traditional_would_skip and not hash_would_skip:
|
|
print(f" ✅ Ambos métodos detectaron el cambio")
|
|
elif traditional_would_skip and hash_would_skip:
|
|
print(f" ✅ Ambos métodos indican que no hay cambios")
|
|
else:
|
|
print(f" ⚠️ Situación inesperada")
|
|
|
|
# Paso 6: Mostrar contenidos para verificación
|
|
print(f"\n7. Verificación de contenido:")
|
|
print(f" Contenido original tenía: 'Test_Block'")
|
|
print(f" Contenido nuevo tiene: 'Test_Blck'")
|
|
|
|
with open(xml_file, "r", encoding="utf-8") as f:
|
|
content = f.read()
|
|
has_original = "Test_Block" in content
|
|
has_modified = "Test_Blck" in content
|
|
print(f" ¿Contiene 'Test_Block'?: {has_original}")
|
|
print(f" ¿Contiene 'Test_Blck'?: {has_modified}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
test_hash_detection()
|