Files
bakery-ia/services/inventory/test_dedup.py

175 lines
6.3 KiB
Python
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
"""
Verification script to confirm the deduplication fix is working
This runs inside the inventory service container to test the actual implementation
"""
import asyncio
import redis.asyncio as aioredis
import json
from datetime import datetime
from uuid import UUID
# Mock the required components
class MockConfig:
SERVICE_NAME = "test-inventory-service"
REDIS_URL = "redis://redis_pass123@172.20.0.10:6379/0"
DATABASE_URL = "mock://test"
RABBITMQ_URL = "mock://test"
class MockDatabaseManager:
def get_session(self):
return self
async def __aenter__(self):
return self
async def __aexit__(self, *args):
pass
class MockRabbitMQClient:
def __init__(self, *args):
self.connected = True
async def connect(self):
pass
async def disconnect(self):
pass
async def publish_event(self, *args, **kwargs):
print(f"📤 Mock publish: Would send alert to RabbitMQ")
return True
async def test_deduplication_in_container():
"""Test the actual deduplication logic using the fixed implementation"""
print("🧪 Testing Alert Deduplication Fix")
print("=" * 50)
# Import the actual BaseAlertService with our fix
import sys
sys.path.append('/app')
from shared.alerts.base_service import BaseAlertService
class TestInventoryAlertService(BaseAlertService):
def __init__(self):
self.config = MockConfig()
self.db_manager = MockDatabaseManager()
self.rabbitmq_client = MockRabbitMQClient()
self.redis = None
self._items_published = 0
self._checks_performed = 0
self._errors_count = 0
def setup_scheduled_checks(self):
pass
async def start(self):
# Connect to Redis for deduplication testing
self.redis = await aioredis.from_url(self.config.REDIS_URL)
print(f"✅ Connected to Redis for testing")
async def stop(self):
if self.redis:
await self.redis.aclose()
# Create test service
service = TestInventoryAlertService()
await service.start()
try:
tenant_id = UUID('c464fb3e-7af2-46e6-9e43-85318f34199a')
print("\\n1⃣ Testing Overstock Alert Deduplication")
print("-" * 40)
# First overstock alert
overstock_alert = {
'type': 'overstock_warning',
'severity': 'medium',
'title': '📦 Exceso de Stock: Test Croissant',
'message': 'Stock actual 150.0kg excede máximo 100.0kg.',
'actions': ['Revisar caducidades'],
'metadata': {
'ingredient_id': 'test-croissant-123',
'current_stock': 150.0,
'maximum_stock': 100.0
}
}
# Send first alert - should succeed
result1 = await service.publish_item(tenant_id, overstock_alert.copy(), 'alert')
print(f"First overstock alert: {'✅ Published' if result1 else '❌ Blocked'}")
# Send duplicate alert - should be blocked
result2 = await service.publish_item(tenant_id, overstock_alert.copy(), 'alert')
print(f"Duplicate overstock alert: {'❌ Published (ERROR!)' if result2 else '✅ Blocked (SUCCESS!)'}")
print("\\n2⃣ Testing Different Ingredient - Should Pass")
print("-" * 40)
# Different ingredient - should succeed
overstock_alert2 = overstock_alert.copy()
overstock_alert2['title'] = '📦 Exceso de Stock: Test Harina'
overstock_alert2['metadata'] = {
'ingredient_id': 'test-harina-456', # Different ingredient
'current_stock': 200.0,
'maximum_stock': 150.0
}
result3 = await service.publish_item(tenant_id, overstock_alert2, 'alert')
print(f"Different ingredient alert: {'✅ Published' if result3 else '❌ Blocked (ERROR!)'}")
print("\\n3⃣ Testing Expired Products Deduplication")
print("-" * 40)
# Expired products alert
expired_alert = {
'type': 'expired_products',
'severity': 'urgent',
'title': '🗑️ Productos Caducados Test',
'message': '3 productos han caducado.',
'actions': ['Retirar inmediatamente'],
'metadata': {
'expired_items': [
{'id': 'expired-1', 'name': 'Leche', 'stock_id': 'stock-1'},
{'id': 'expired-2', 'name': 'Huevos', 'stock_id': 'stock-2'}
]
}
}
# Send first expired products alert - should succeed
result4 = await service.publish_item(tenant_id, expired_alert.copy(), 'alert')
print(f"First expired products alert: {'✅ Published' if result4 else '❌ Blocked'}")
# Send duplicate expired products alert - should be blocked
result5 = await service.publish_item(tenant_id, expired_alert.copy(), 'alert')
print(f"Duplicate expired products alert: {'❌ Published (ERROR!)' if result5 else '✅ Blocked (SUCCESS!)'}")
print("\\n📊 Test Results Summary")
print("=" * 50)
unique_published = sum([result1, result3, result4]) # Should be 3
duplicates_blocked = sum([not result2, not result5]) # Should be 2
print(f"✅ Unique alerts published: {unique_published}/3")
print(f"🚫 Duplicate alerts blocked: {duplicates_blocked}/2")
if unique_published == 3 and duplicates_blocked == 2:
print("\\n🎉 SUCCESS: Deduplication fix is working correctly!")
print(" • All unique alerts were published")
print(" • All duplicate alerts were blocked")
print(" • The duplicate alert issue should be resolved")
else:
print("\\n❌ ISSUE: Deduplication is not working as expected")
# Show Redis keys for verification
print("\\n🔍 Deduplication Keys in Redis:")
keys = await service.redis.keys("item_sent:*")
for key in keys:
ttl = await service.redis.ttl(key)
decoded_key = key.decode() if isinstance(key, bytes) else key
print(f"{decoded_key} (TTL: {ttl}s)")
finally:
await service.stop()
print("\\n✅ Test completed and cleaned up")
if __name__ == "__main__":
asyncio.run(test_deduplication_in_container())