184 lines
6.5 KiB
Python
184 lines
6.5 KiB
Python
"""
|
|
Python Binary Receiver Test
|
|
Tests the smartreceive function with binary/image/audio/video/table payloads
|
|
"""
|
|
|
|
import asyncio
|
|
import sys
|
|
import os
|
|
import json
|
|
import base64
|
|
|
|
# Add parent directory to path
|
|
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
|
|
|
from natbridge import smartreceive, DEFAULT_BROKER_URL, DEFAULT_FILESERVER_URL
|
|
|
|
TEST_BROKER_URL = os.environ.get('NATS_URL', 'nats://localhost:4222')
|
|
TEST_FILESERVER_URL = os.environ.get('FILESERVER_URL', 'http://localhost:8080')
|
|
|
|
|
|
async def run_test():
|
|
print('=== Python Binary Receiver Test ===\n')
|
|
|
|
# Create mock NATS message with binary payloads
|
|
image_data = bytes([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]) # PNG header
|
|
audio_data = bytes([0x46, 0x4C, 0x41, 0x43, 0x00, 0x00, 0x00, 0x00]) # FLAC header
|
|
video_data = bytes([0x00, 0x00, 0x00, 0x18, 0x66, 0x74, 0x79, 0x70]) # MP4 header
|
|
generic_binary = bytes([0xDE, 0xAD, 0xBE, 0xEF, 0xCA, 0xFE, 0xBA, 0xBE])
|
|
|
|
test_data = {
|
|
'correlation_id': 'py-binary-receiver-' + str(asyncio.get_event_loop().time() * 1000000),
|
|
'msg_id': 'msg-' + str(asyncio.get_event_loop().time() * 1000000),
|
|
'timestamp': asyncio.get_event_loop().time().isoformat(),
|
|
'send_to': '/test/binary',
|
|
'msg_purpose': 'test',
|
|
'sender_name': 'py-binary-test',
|
|
'sender_id': 'sender-' + str(asyncio.get_event_loop().time() * 1000000),
|
|
'receiver_name': 'py-receiver',
|
|
'receiver_id': 'receiver-' + str(asyncio.get_event_loop().time() * 1000000),
|
|
'reply_to': '',
|
|
'reply_to_msg_id': '',
|
|
'broker_url': TEST_BROKER_URL,
|
|
'metadata': {},
|
|
'payloads': [
|
|
{
|
|
'id': 'payload-1',
|
|
'dataname': 'image',
|
|
'payload_type': 'image',
|
|
'transport': 'direct',
|
|
'encoding': 'base64',
|
|
'size': len(image_data),
|
|
'data': base64.b64encode(image_data).decode('ascii'),
|
|
'metadata': {'payload_bytes': len(image_data)}
|
|
},
|
|
{
|
|
'id': 'payload-2',
|
|
'dataname': 'audio',
|
|
'payload_type': 'audio',
|
|
'transport': 'direct',
|
|
'encoding': 'base64',
|
|
'size': len(audio_data),
|
|
'data': base64.b64encode(audio_data).decode('ascii'),
|
|
'metadata': {'payload_bytes': len(audio_data)}
|
|
},
|
|
{
|
|
'id': 'payload-3',
|
|
'dataname': 'video',
|
|
'payload_type': 'video',
|
|
'transport': 'direct',
|
|
'encoding': 'base64',
|
|
'size': len(video_data),
|
|
'data': base64.b64encode(video_data).decode('ascii'),
|
|
'metadata': {'payload_bytes': len(video_data)}
|
|
},
|
|
{
|
|
'id': 'payload-4',
|
|
'dataname': 'binary',
|
|
'payload_type': 'binary',
|
|
'transport': 'direct',
|
|
'encoding': 'base64',
|
|
'size': len(generic_binary),
|
|
'data': base64.b64encode(generic_binary).decode('ascii'),
|
|
'metadata': {'payload_bytes': len(generic_binary)}
|
|
}
|
|
]
|
|
}
|
|
|
|
mock_msg = {
|
|
'payload': json.dumps(test_data)
|
|
}
|
|
|
|
print('Mock Message Created:')
|
|
print(f' Correlation ID: {test_data["correlation_id"]}')
|
|
print(f' Payloads: {len(test_data["payloads"])}')
|
|
print(f' Payload types: {", ".join(p["payload_type"] for p in test_data["payloads"])}\n')
|
|
|
|
try:
|
|
# Receive and process the message
|
|
print('Receiving and processing message...')
|
|
env = await smartreceive(
|
|
mock_msg,
|
|
max_retries=3,
|
|
base_delay=100,
|
|
max_delay=1000
|
|
)
|
|
|
|
print('\n=== Received Envelope ===')
|
|
print(f'Correlation ID: {env["correlation_id"]}')
|
|
print(f'Message ID: {env["msg_id"]}')
|
|
print(f'Timestamp: {env["timestamp"]}')
|
|
print(f'Subject: {env["send_to"]}')
|
|
print(f'Payloads: {len(env["payloads"])}\n')
|
|
|
|
# Validate received data
|
|
print('=== Validation ===')
|
|
passed = True
|
|
|
|
if not env.get('correlation_id'):
|
|
print('❌ correlation_id is missing')
|
|
passed = False
|
|
else:
|
|
print('✅ correlation_id present')
|
|
|
|
if len(env['payloads']) != 4:
|
|
print(f'❌ Expected 4 payloads, got {len(env["payloads"])}')
|
|
passed = False
|
|
else:
|
|
print('✅ Correct number of payloads')
|
|
|
|
# Expected data
|
|
expected_data = [
|
|
('image', image_data, 'image'),
|
|
('audio', audio_data, 'audio'),
|
|
('video', video_data, 'video'),
|
|
('binary', generic_binary, 'binary')
|
|
]
|
|
|
|
for i in range(len(env['payloads'])):
|
|
payload = env['payloads'][i]
|
|
expected = expected_data[i]
|
|
|
|
if payload[0] != expected[0]:
|
|
print(f"❌ Payload {i + 1}: Expected dataname '{expected[0]}', got '{payload[0]}'")
|
|
passed = False
|
|
else:
|
|
print(f'✅ Payload {i + 1}: Correct dataname')
|
|
|
|
if payload[2] != expected[2]:
|
|
print(f"❌ Payload {i + 1}: Expected type '{expected[2]}', got '{payload[2]}'")
|
|
passed = False
|
|
else:
|
|
print(f'✅ Payload {i + 1}: Correct type')
|
|
|
|
# Verify binary data integrity
|
|
received_data = payload[1]
|
|
if not isinstance(received_data, (bytes, bytearray)):
|
|
print(f'❌ Payload {i + 1}: Expected bytes/bytearray, got {type(received_data)}')
|
|
passed = False
|
|
elif received_data != expected[1]:
|
|
print(f'❌ Payload {i + 1}: Data mismatch')
|
|
print(f' Expected: {expected[1]}')
|
|
print(f' Got: {received_data}')
|
|
passed = False
|
|
else:
|
|
print(f'✅ Payload {i + 1}: Data correctly deserialized')
|
|
|
|
# Final result
|
|
print('\n=== Test Result ===')
|
|
if passed:
|
|
print('✅ ALL TESTS PASSED')
|
|
sys.exit(0)
|
|
else:
|
|
print('❌ SOME TESTS FAILED')
|
|
sys.exit(1)
|
|
|
|
except Exception as e:
|
|
print(f'❌ Test failed with error: {e}')
|
|
import traceback
|
|
traceback.print_exc()
|
|
sys.exit(1)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
asyncio.run(run_test()) |