dograh/api/services/telephony/transfer_test.py
2026-02-14 07:28:36 +05:30

133 lines
No EOL
4.4 KiB
Python

"""Test utilities for transfer coordination.
This module provides utilities to test Redis-based transfer coordination
across multiple instances.
"""
import asyncio
import time
import uuid
from typing import Optional
from loguru import logger
from api.services.telephony.call_transfer_manager import get_call_transfer_manager
from api.services.telephony.transfer_event_protocol import (
TransferContext,
TransferEvent,
TransferEventType
)
async def test_redis_coordination():
"""Test basic Redis pub/sub coordination for transfers."""
logger.info("Testing Redis-based transfer coordination...")
call_transfer_manager = await get_call_transfer_manager()
# Test 1: Store and retrieve transfer context
tool_call_id = str(uuid.uuid4())
test_context = TransferContext(
tool_call_id=tool_call_id,
call_sid="test_call_123",
target_number="+1234567890",
tool_uuid="test_tool_uuid",
original_call_sid="original_call_123",
caller_number="+0987654321",
initiated_at=time.time()
)
logger.info("Test 1: Storing transfer context...")
await call_transfer_manager.store_transfer_context(test_context)
logger.info("Test 1: Retrieving transfer context...")
retrieved_context = await call_transfer_manager.get_transfer_context(tool_call_id)
if retrieved_context and retrieved_context.tool_call_id == tool_call_id:
logger.info("✅ Test 1 PASSED: Context storage/retrieval works")
else:
logger.error("❌ Test 1 FAILED: Context storage/retrieval failed")
return False
# Test 2: Event publishing and waiting
logger.info("Test 2: Testing event publishing...")
# Start waiting for completion in background
async def wait_for_completion():
return await call_transfer_manager.wait_for_transfer_completion(tool_call_id, 5.0)
wait_task = asyncio.create_task(wait_for_completion())
# Give it a moment to start waiting
await asyncio.sleep(0.5)
# Publish completion event
test_event = TransferEvent(
type=TransferEventType.TRANSFER_COMPLETED,
tool_call_id=tool_call_id,
original_call_sid="original_call_123",
transfer_call_sid="transfer_call_456",
conference_name="test-conference",
message="Test transfer completed successfully",
status="success",
action="transfer_success"
)
logger.info("Test 2: Publishing completion event...")
await call_transfer_manager.publish_transfer_event(test_event)
# Wait for the completion
received_event = await wait_task
if received_event and received_event.tool_call_id == tool_call_id:
logger.info("✅ Test 2 PASSED: Event pub/sub works")
else:
logger.error("❌ Test 2 FAILED: Event pub/sub failed")
return False
# Test 3: Cleanup
logger.info("Test 3: Testing cleanup...")
await call_transfer_manager.remove_transfer_context(tool_call_id)
cleanup_context = await call_transfer_manager.get_transfer_context(tool_call_id)
if cleanup_context is None:
logger.info("✅ Test 3 PASSED: Cleanup works")
else:
logger.error("❌ Test 3 FAILED: Cleanup failed")
return False
logger.info("✅ All tests PASSED! Redis coordination is working correctly.")
return True
async def test_timeout_handling():
"""Test timeout handling in transfer coordination."""
logger.info("Testing timeout handling...")
call_transfer_manager = await get_call_transfer_manager()
tool_call_id = str(uuid.uuid4())
# Wait for completion with short timeout (should timeout)
start_time = time.time()
result = await call_transfer_manager.wait_for_transfer_completion(tool_call_id, 2.0)
elapsed = time.time() - start_time
if result is None and elapsed >= 2.0:
logger.info("✅ Timeout test PASSED: Properly timed out after 2 seconds")
return True
else:
logger.error(f"❌ Timeout test FAILED: Expected timeout, got {result} in {elapsed}s")
return False
if __name__ == "__main__":
async def main():
success1 = await test_redis_coordination()
success2 = await test_timeout_handling()
if success1 and success2:
logger.info("🎉 All transfer coordination tests PASSED!")
else:
logger.error("💥 Some tests FAILED!")
asyncio.run(main())