smartreceive_return_envelope #6
@@ -1,220 +1,207 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Micropython NATS Bridge - Basic Test Examples
|
||||
|
||||
This module demonstrates basic usage of the NATSBridge for Micropython.
|
||||
Basic functionality test for nats_bridge.py
|
||||
Tests the core classes and functions without NATS connection
|
||||
"""
|
||||
|
||||
import sys
|
||||
sys.path.insert(0, "../src")
|
||||
import os
|
||||
|
||||
from nats_bridge import MessageEnvelope, MessagePayload, smartsend, smartreceive, log_trace
|
||||
# Add src to path for import
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'src'))
|
||||
|
||||
from nats_bridge import (
|
||||
MessagePayload,
|
||||
MessageEnvelope,
|
||||
smartsend,
|
||||
smartreceive,
|
||||
log_trace,
|
||||
generate_uuid,
|
||||
get_timestamp,
|
||||
_serialize_data,
|
||||
_deserialize_data
|
||||
)
|
||||
import json
|
||||
|
||||
# ============================================= 100 ============================================== #
|
||||
|
||||
def test_message_payload():
|
||||
"""Test MessagePayload class"""
|
||||
print("\n=== Testing MessagePayload ===")
|
||||
|
||||
def test_text_message():
|
||||
"""Test sending and receiving text messages."""
|
||||
print("\n=== Test 1: Text Message ===")
|
||||
|
||||
# Send text message
|
||||
data = [
|
||||
("message", "Hello World", "text"),
|
||||
("greeting", "Good morning!", "text")
|
||||
]
|
||||
|
||||
env = smartsend(
|
||||
"/test/text",
|
||||
data,
|
||||
nats_url="nats://localhost:4222",
|
||||
size_threshold=1000000
|
||||
# Test direct transport with text
|
||||
payload1 = MessagePayload(
|
||||
data="Hello World",
|
||||
msg_type="text",
|
||||
id="test-id-1",
|
||||
dataname="message",
|
||||
transport="direct",
|
||||
encoding="base64",
|
||||
size=11
|
||||
)
|
||||
|
||||
print("Sent envelope:")
|
||||
print(" Subject: {}".format(env.send_to))
|
||||
print(" Correlation ID: {}".format(env.correlation_id))
|
||||
print(" Payloads: {}".format(len(env.payloads)))
|
||||
assert payload1.id == "test-id-1"
|
||||
assert payload1.dataname == "message"
|
||||
assert payload1.type == "text"
|
||||
assert payload1.transport == "direct"
|
||||
assert payload1.encoding == "base64"
|
||||
assert payload1.size == 11
|
||||
print(" [PASS] MessagePayload with text data")
|
||||
|
||||
# Expected output on receiver:
|
||||
# envelope = smartreceive(msg)
|
||||
# for dataname, data, type in envelope["payloads"]:
|
||||
# print("Received {}: {}".format(dataname, data))
|
||||
|
||||
|
||||
def test_dictionary_message():
|
||||
"""Test sending and receiving dictionary messages."""
|
||||
print("\n=== Test 2: Dictionary Message ===")
|
||||
|
||||
# Send dictionary message
|
||||
config = {
|
||||
"step_size": 0.01,
|
||||
"iterations": 1000,
|
||||
"threshold": 0.5
|
||||
}
|
||||
|
||||
data = [
|
||||
("config", config, "dictionary")
|
||||
]
|
||||
|
||||
env = smartsend(
|
||||
"/test/dictionary",
|
||||
data,
|
||||
nats_url="nats://localhost:4222",
|
||||
size_threshold=1000000
|
||||
# Test link transport with URL
|
||||
payload2 = MessagePayload(
|
||||
data="http://example.com/file.txt",
|
||||
msg_type="binary",
|
||||
id="test-id-2",
|
||||
dataname="file",
|
||||
transport="link",
|
||||
encoding="none",
|
||||
size=1000
|
||||
)
|
||||
|
||||
print("Sent envelope:")
|
||||
print(" Subject: {}".format(env.send_to))
|
||||
print(" Payloads: {}".format(len(env.payloads)))
|
||||
assert payload2.transport == "link"
|
||||
assert payload2.data == "http://example.com/file.txt"
|
||||
print(" [PASS] MessagePayload with link transport")
|
||||
|
||||
# Expected output on receiver:
|
||||
# envelope = smartreceive(msg)
|
||||
# for dataname, data, type in envelope["payloads"]:
|
||||
# if type == "dictionary":
|
||||
# print("Config: {}".format(data))
|
||||
# Test to_dict method
|
||||
payload_dict = payload1.to_dict()
|
||||
assert "id" in payload_dict
|
||||
assert "dataname" in payload_dict
|
||||
assert "type" in payload_dict
|
||||
assert "transport" in payload_dict
|
||||
assert "data" in payload_dict
|
||||
print(" [PASS] MessagePayload.to_dict() method")
|
||||
|
||||
|
||||
def test_mixed_payloads():
|
||||
"""Test sending mixed payload types in a single message."""
|
||||
print("\n=== Test 3: Mixed Payloads ===")
|
||||
def test_message_envelope():
|
||||
"""Test MessageEnvelope class"""
|
||||
print("\n=== Testing MessageEnvelope ===")
|
||||
|
||||
# Mixed content: text, dictionary, and binary
|
||||
image_data = b"\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR" # PNG header (example)
|
||||
# Create payloads
|
||||
payload1 = MessagePayload("Hello", "text", id="p1", dataname="msg1")
|
||||
payload2 = MessagePayload("http://example.com/file", "binary", id="p2", dataname="file", transport="link")
|
||||
|
||||
data = [
|
||||
("message_text", "Hello!", "text"),
|
||||
("user_config", {"theme": "dark", "volume": 80}, "dictionary"),
|
||||
("user_image", image_data, "binary")
|
||||
]
|
||||
|
||||
env = smartsend(
|
||||
"/test/mixed",
|
||||
data,
|
||||
nats_url="nats://localhost:4222",
|
||||
size_threshold=1000000
|
||||
# Create envelope
|
||||
env = MessageEnvelope(
|
||||
send_to="/test/subject",
|
||||
payloads=[payload1, payload2],
|
||||
correlation_id="test-correlation-id",
|
||||
msg_id="test-msg-id",
|
||||
msg_purpose="chat",
|
||||
sender_name="test_sender",
|
||||
receiver_name="test_receiver",
|
||||
reply_to="/test/reply"
|
||||
)
|
||||
|
||||
print("Sent envelope:")
|
||||
print(" Subject: {}".format(env.send_to))
|
||||
print(" Payloads: {}".format(len(env.payloads)))
|
||||
assert env.send_to == "/test/subject"
|
||||
assert env.correlation_id == "test-correlation-id"
|
||||
assert env.msg_id == "test-msg-id"
|
||||
assert env.msg_purpose == "chat"
|
||||
assert len(env.payloads) == 2
|
||||
print(" [PASS] MessageEnvelope creation")
|
||||
|
||||
# Expected output on receiver:
|
||||
# envelope = smartreceive(msg)
|
||||
# for dataname, data, type in envelope["payloads"]:
|
||||
# print("Received {}: {} (type: {})".format(dataname, data if type != "binary" else len(data), type))
|
||||
# Test to_json method
|
||||
json_str = env.to_json()
|
||||
json_data = json.loads(json_str)
|
||||
assert json_data["sendTo"] == "/test/subject"
|
||||
assert json_data["correlationId"] == "test-correlation-id"
|
||||
assert json_data["msgPurpose"] == "chat"
|
||||
assert len(json_data["payloads"]) == 2
|
||||
print(" [PASS] MessageEnvelope.to_json() method")
|
||||
|
||||
|
||||
def test_large_payload():
|
||||
"""Test sending large payloads that require fileserver upload."""
|
||||
print("\n=== Test 4: Large Payload (Link Transport) ===")
|
||||
def test_serialize_data():
|
||||
"""Test _serialize_data function"""
|
||||
print("\n=== Testing _serialize_data ===")
|
||||
|
||||
# Create large data (> 1MB would trigger link transport)
|
||||
# For testing, we'll use a smaller size but configure threshold lower
|
||||
large_data = b"A" * 100000 # 100KB
|
||||
# Test text serialization
|
||||
text_bytes = _serialize_data("Hello", "text")
|
||||
assert isinstance(text_bytes, bytes)
|
||||
assert text_bytes == b"Hello"
|
||||
print(" [PASS] Text serialization")
|
||||
|
||||
data = [
|
||||
("large_data", large_data, "binary")
|
||||
]
|
||||
# Test dictionary serialization
|
||||
dict_data = {"key": "value", "number": 42}
|
||||
dict_bytes = _serialize_data(dict_data, "dictionary")
|
||||
assert isinstance(dict_bytes, bytes)
|
||||
parsed = json.loads(dict_bytes.decode('utf-8'))
|
||||
assert parsed["key"] == "value"
|
||||
print(" [PASS] Dictionary serialization")
|
||||
|
||||
# Use a lower threshold for testing
|
||||
env = smartsend(
|
||||
"/test/large",
|
||||
data,
|
||||
nats_url="nats://localhost:4222",
|
||||
fileserver_url="http://localhost:8080",
|
||||
size_threshold=50000 # 50KB threshold for testing
|
||||
)
|
||||
# Test binary serialization
|
||||
binary_data = b"\x00\x01\x02"
|
||||
binary_bytes = _serialize_data(binary_data, "binary")
|
||||
assert binary_bytes == b"\x00\x01\x02"
|
||||
print(" [PASS] Binary serialization")
|
||||
|
||||
print("Sent envelope:")
|
||||
print(" Subject: {}".format(env.send_to))
|
||||
print(" Payloads: {}".format(len(env.payloads)))
|
||||
for p in env.payloads:
|
||||
print(" - Transport: {}, Type: {}".format(p.transport, p.type))
|
||||
# Test image serialization
|
||||
image_data = bytes([1, 2, 3, 4, 5])
|
||||
image_bytes = _serialize_data(image_data, "image")
|
||||
assert image_bytes == image_data
|
||||
print(" [PASS] Image serialization")
|
||||
|
||||
|
||||
def test_reply_to():
|
||||
"""Test sending messages with reply-to functionality."""
|
||||
print("\n=== Test 5: Reply To ===")
|
||||
def test_deserialize_data():
|
||||
"""Test _deserialize_data function"""
|
||||
print("\n=== Testing _deserialize_data ===")
|
||||
|
||||
data = [
|
||||
("command", {"action": "start"}, "dictionary")
|
||||
]
|
||||
# Test text deserialization
|
||||
text_bytes = b"Hello"
|
||||
text_data = _deserialize_data(text_bytes, "text", "test-correlation-id")
|
||||
assert text_data == "Hello"
|
||||
print(" [PASS] Text deserialization")
|
||||
|
||||
env = smartsend(
|
||||
"/test/command",
|
||||
data,
|
||||
nats_url="nats://localhost:4222",
|
||||
reply_to="/test/response",
|
||||
reply_to_msg_id="reply-123",
|
||||
msg_purpose="command"
|
||||
)
|
||||
# Test dictionary deserialization
|
||||
dict_bytes = b'{"key": "value"}'
|
||||
dict_data = _deserialize_data(dict_bytes, "dictionary", "test-correlation-id")
|
||||
assert dict_data == {"key": "value"}
|
||||
print(" [PASS] Dictionary deserialization")
|
||||
|
||||
print("Sent envelope:")
|
||||
print(" Subject: {}".format(env.send_to))
|
||||
print(" Reply To: {}".format(env.reply_to))
|
||||
print(" Reply To Msg ID: {}".format(env.reply_to_msg_id))
|
||||
# Test binary deserialization
|
||||
binary_data = b"\x00\x01\x02"
|
||||
binary_result = _deserialize_data(binary_data, "binary", "test-correlation-id")
|
||||
assert binary_result == b"\x00\x01\x02"
|
||||
print(" [PASS] Binary deserialization")
|
||||
|
||||
|
||||
def test_correlation_id():
|
||||
"""Test using custom correlation IDs for tracing."""
|
||||
print("\n=== Test 6: Custom Correlation ID ===")
|
||||
def test_utilities():
|
||||
"""Test utility functions"""
|
||||
print("\n=== Testing Utility Functions ===")
|
||||
|
||||
custom_cid = "trace-abc123"
|
||||
data = [
|
||||
("message", "Test with correlation ID", "text")
|
||||
]
|
||||
# Test generate_uuid
|
||||
uuid1 = generate_uuid()
|
||||
uuid2 = generate_uuid()
|
||||
assert uuid1 != uuid2
|
||||
print(f" [PASS] generate_uuid() - generated: {uuid1}")
|
||||
|
||||
env = smartsend(
|
||||
"/test/correlation",
|
||||
data,
|
||||
nats_url="nats://localhost:4222",
|
||||
correlation_id=custom_cid
|
||||
)
|
||||
|
||||
print("Sent envelope with correlation ID: {}".format(env.correlation_id))
|
||||
print("This ID can be used to trace the message flow.")
|
||||
# Test get_timestamp
|
||||
timestamp = get_timestamp()
|
||||
assert "T" in timestamp
|
||||
print(f" [PASS] get_timestamp() - generated: {timestamp}")
|
||||
|
||||
|
||||
def test_multiple_payloads():
|
||||
"""Test sending multiple payloads in one message."""
|
||||
print("\n=== Test 7: Multiple Payloads ===")
|
||||
def main():
|
||||
"""Run all tests"""
|
||||
print("=" * 60)
|
||||
print("NATSBridge Python/Micropython - Basic Functionality Tests")
|
||||
print("=" * 60)
|
||||
|
||||
data = [
|
||||
("text_message", "Hello", "text"),
|
||||
("json_data", {"key": "value", "number": 42}, "dictionary"),
|
||||
("table_data", b"\x01\x02\x03\x04", "binary"),
|
||||
("audio_data", b"\x00\x01\x02\x03", "binary")
|
||||
]
|
||||
try:
|
||||
test_message_payload()
|
||||
test_message_envelope()
|
||||
test_serialize_data()
|
||||
test_deserialize_data()
|
||||
test_utilities()
|
||||
|
||||
env = smartsend(
|
||||
"/test/multiple",
|
||||
data,
|
||||
nats_url="nats://localhost:4222",
|
||||
size_threshold=1000000
|
||||
)
|
||||
print("\n" + "=" * 60)
|
||||
print("ALL TESTS PASSED!")
|
||||
print("=" * 60)
|
||||
|
||||
print("Sent {} payloads in one message".format(len(env.payloads)))
|
||||
except Exception as e:
|
||||
print(f"\n[FAIL] Test failed with error: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("Micropython NATS Bridge Test Suite")
|
||||
print("==================================")
|
||||
print()
|
||||
|
||||
# Run tests
|
||||
test_text_message()
|
||||
test_dictionary_message()
|
||||
test_mixed_payloads()
|
||||
test_large_payload()
|
||||
test_reply_to()
|
||||
test_correlation_id()
|
||||
test_multiple_payloads()
|
||||
|
||||
print("\n=== All tests completed ===")
|
||||
print()
|
||||
print("Note: These tests require:")
|
||||
print(" 1. A running NATS server at nats://localhost:4222")
|
||||
print(" 2. An HTTP file server at http://localhost:8080 (for large payloads)")
|
||||
print()
|
||||
print("To run the tests:")
|
||||
print(" python test_micropython_basic.py")
|
||||
main()
|
||||
70
test/test_micropython_dict_receiver.py
Normal file
70
test/test_micropython_dict_receiver.py
Normal file
@@ -0,0 +1,70 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Test script for dictionary transport testing - Receiver
|
||||
Tests receiving dictionary messages via NATS using nats_bridge.py smartreceive
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
import json
|
||||
|
||||
# Add src to path for import
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'src'))
|
||||
|
||||
from nats_bridge import smartreceive, log_trace
|
||||
import nats
|
||||
import asyncio
|
||||
|
||||
# Configuration
|
||||
SUBJECT = "/NATSBridge_dict_test"
|
||||
NATS_URL = "nats://nats.yiem.cc:4222"
|
||||
|
||||
|
||||
async def main():
|
||||
log_trace("", f"Starting dictionary transport receiver test...")
|
||||
log_trace("", f"Note: This receiver will wait for messages from the sender.")
|
||||
log_trace("", f"Run test_micropython_dict_sender.py first to send test data.")
|
||||
|
||||
# Connect to NATS
|
||||
nc = await nats.connect(NATS_URL)
|
||||
log_trace("", f"Connected to NATS at {NATS_URL}")
|
||||
|
||||
# Subscribe to the subject
|
||||
async def message_handler(msg):
|
||||
log_trace("", f"Received message on {msg.subject}")
|
||||
|
||||
# Use smartreceive to handle the data
|
||||
result = smartreceive(msg.data)
|
||||
|
||||
# Result is an envelope dictionary with payloads field containing list of (dataname, data, data_type) tuples
|
||||
for dataname, data, data_type in result["payloads"]:
|
||||
if isinstance(data, dict):
|
||||
log_trace(result.get("correlationId", ""), f"Received dictionary '{dataname}' of type {data_type}")
|
||||
log_trace(result.get("correlationId", ""), f" Keys: {list(data.keys())}")
|
||||
|
||||
# Display first few items for small dicts
|
||||
if isinstance(data, dict) and len(data) <= 10:
|
||||
log_trace(result.get("correlationId", ""), f" Content: {json.dumps(data, indent=2)}")
|
||||
else:
|
||||
# For large dicts, show summary
|
||||
log_trace(result.get("correlationId", ""), f" Summary: {json.dumps(data, default=str)[:200]}...")
|
||||
|
||||
# Save to file
|
||||
output_path = f"./received_{dataname}.json"
|
||||
with open(output_path, 'w') as f:
|
||||
json.dump(data, f, indent=2)
|
||||
log_trace(result.get("correlationId", ""), f"Saved dictionary to {output_path}")
|
||||
else:
|
||||
log_trace(result.get("correlationId", ""), f"Received unexpected data type for '{dataname}': {type(data)}")
|
||||
|
||||
sid = await nc.subscribe(SUBJECT, cb=message_handler)
|
||||
log_trace("", f"Subscribed to {SUBJECT} with subscription ID: {sid}")
|
||||
|
||||
# Keep listening for 120 seconds
|
||||
await asyncio.sleep(120)
|
||||
await nc.close()
|
||||
log_trace("", "Test completed.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
99
test/test_micropython_dict_sender.py
Normal file
99
test/test_micropython_dict_sender.py
Normal file
@@ -0,0 +1,99 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Test script for dictionary transport testing - Micropython
|
||||
Tests sending dictionary messages via NATS using nats_bridge.py smartsend
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
# Add src to path for import
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'src'))
|
||||
|
||||
from nats_bridge import smartsend, log_trace
|
||||
import uuid
|
||||
|
||||
# Configuration
|
||||
SUBJECT = "/NATSBridge_dict_test"
|
||||
NATS_URL = "nats://nats.yiem.cc:4222"
|
||||
FILESERVER_URL = "http://192.168.88.104:8080"
|
||||
SIZE_THRESHOLD = 1_000_000 # 1MB
|
||||
|
||||
# Create correlation ID for tracing
|
||||
correlation_id = str(uuid.uuid4())
|
||||
|
||||
|
||||
def main():
|
||||
# Create a small dictionary (will use direct transport)
|
||||
small_dict = {
|
||||
"name": "test",
|
||||
"value": 42,
|
||||
"enabled": True,
|
||||
"metadata": {
|
||||
"version": "1.0.0",
|
||||
"timestamp": "2026-02-22T12:00:00Z"
|
||||
}
|
||||
}
|
||||
|
||||
# Create a large dictionary (will use link transport if > 1MB)
|
||||
# Generate a larger dictionary (~2MB to ensure link transport)
|
||||
large_dict = {
|
||||
"id": str(uuid.uuid4()),
|
||||
"items": [
|
||||
{
|
||||
"index": i,
|
||||
"name": f"item_{i}",
|
||||
"value": i * 1.5,
|
||||
"data": "x" * 10000 # Large string per item
|
||||
}
|
||||
for i in range(200)
|
||||
],
|
||||
"metadata": {
|
||||
"count": 200,
|
||||
"created": "2026-02-22T12:00:00Z"
|
||||
}
|
||||
}
|
||||
|
||||
# Test data 1: small dictionary
|
||||
data1 = ("small_dict", small_dict, "dictionary")
|
||||
|
||||
# Test data 2: large dictionary
|
||||
data2 = ("large_dict", large_dict, "dictionary")
|
||||
|
||||
log_trace(correlation_id, f"Starting smartsend for subject: {SUBJECT}")
|
||||
log_trace(correlation_id, f"Correlation ID: {correlation_id}")
|
||||
|
||||
# Use smartsend with dictionary type
|
||||
env = smartsend(
|
||||
SUBJECT,
|
||||
[data1, data2], # List of (dataname, data, type) tuples
|
||||
nats_url=NATS_URL,
|
||||
fileserver_url=FILESERVER_URL,
|
||||
size_threshold=SIZE_THRESHOLD,
|
||||
correlation_id=correlation_id,
|
||||
msg_purpose="chat",
|
||||
sender_name="dict_sender",
|
||||
receiver_name="",
|
||||
receiver_id="",
|
||||
reply_to="",
|
||||
reply_to_msg_id=""
|
||||
)
|
||||
|
||||
log_trace(correlation_id, f"Sent message with {len(env.payloads)} payloads")
|
||||
|
||||
# Log transport type for each payload
|
||||
for i, payload in enumerate(env.payloads):
|
||||
log_trace(correlation_id, f"Payload {i+1} ('{payload.dataname}'):")
|
||||
log_trace(correlation_id, f" Transport: {payload.transport}")
|
||||
log_trace(correlation_id, f" Type: {payload.type}")
|
||||
log_trace(correlation_id, f" Size: {payload.size} bytes")
|
||||
log_trace(correlation_id, f" Encoding: {payload.encoding}")
|
||||
|
||||
if payload.transport == "link":
|
||||
log_trace(correlation_id, f" URL: {payload.data}")
|
||||
|
||||
print(f"Test completed. Correlation ID: {correlation_id}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
65
test/test_micropython_file_receiver.py
Normal file
65
test/test_micropython_file_receiver.py
Normal file
@@ -0,0 +1,65 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Test script for file transport testing - Receiver
|
||||
Tests receiving binary files via NATS using nats_bridge.py smartreceive
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
# Add src to path for import
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'src'))
|
||||
|
||||
from nats_bridge import smartreceive, log_trace
|
||||
import nats
|
||||
import asyncio
|
||||
|
||||
# Configuration
|
||||
SUBJECT = "/NATSBridge_file_test"
|
||||
NATS_URL = "nats://nats.yiem.cc:4222"
|
||||
|
||||
|
||||
async def main():
|
||||
log_trace("", f"Starting file transport receiver test...")
|
||||
log_trace("", f"Note: This receiver will wait for messages from the sender.")
|
||||
log_trace("", f"Run test_micropython_file_sender.py first to send test data.")
|
||||
|
||||
# Connect to NATS
|
||||
nc = await nats.connect(NATS_URL)
|
||||
log_trace("", f"Connected to NATS at {NATS_URL}")
|
||||
|
||||
# Subscribe to the subject
|
||||
async def message_handler(msg):
|
||||
log_trace("", f"Received message on {msg.subject}")
|
||||
|
||||
# Use smartreceive to handle the data
|
||||
result = smartreceive(msg.data)
|
||||
|
||||
# Result is an envelope dictionary with payloads field containing list of (dataname, data, data_type) tuples
|
||||
for dataname, data, data_type in result["payloads"]:
|
||||
if isinstance(data, bytes):
|
||||
log_trace(result.get("correlationId", ""), f"Received binary '{dataname}' of type {data_type}")
|
||||
log_trace(result.get("correlationId", ""), f" Size: {len(data)} bytes")
|
||||
|
||||
# Display first 100 bytes as hex
|
||||
log_trace(result.get("correlationId", ""), f" First 100 bytes (hex): {data[:100].hex()}")
|
||||
|
||||
# Save to file
|
||||
output_path = f"./received_{dataname}.bin"
|
||||
with open(output_path, 'wb') as f:
|
||||
f.write(data)
|
||||
log_trace(result.get("correlationId", ""), f"Saved binary to {output_path}")
|
||||
else:
|
||||
log_trace(result.get("correlationId", ""), f"Received unexpected data type for '{dataname}': {type(data)}")
|
||||
|
||||
sid = await nc.subscribe(SUBJECT, cb=message_handler)
|
||||
log_trace("", f"Subscribed to {SUBJECT} with subscription ID: {sid}")
|
||||
|
||||
# Keep listening for 120 seconds
|
||||
await asyncio.sleep(120)
|
||||
await nc.close()
|
||||
log_trace("", "Test completed.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
79
test/test_micropython_file_sender.py
Normal file
79
test/test_micropython_file_sender.py
Normal file
@@ -0,0 +1,79 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Test script for file transport testing - Micropython
|
||||
Tests sending binary files via NATS using nats_bridge.py smartsend
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
# Add src to path for import
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'src'))
|
||||
|
||||
from nats_bridge import smartsend, log_trace
|
||||
import uuid
|
||||
|
||||
# Configuration
|
||||
SUBJECT = "/NATSBridge_file_test"
|
||||
NATS_URL = "nats://nats.yiem.cc:4222"
|
||||
FILESERVER_URL = "http://192.168.88.104:8080"
|
||||
SIZE_THRESHOLD = 1_000_000 # 1MB
|
||||
|
||||
# Create correlation ID for tracing
|
||||
correlation_id = str(uuid.uuid4())
|
||||
|
||||
|
||||
def main():
|
||||
# Create small binary data (will use direct transport)
|
||||
small_binary = b"This is small binary data for testing direct transport."
|
||||
small_binary += b"\x00" * 100 # Add some null bytes
|
||||
|
||||
# Create large binary data (will use link transport if > 1MB)
|
||||
# Generate a larger binary (~2MB to ensure link transport)
|
||||
large_binary = bytes([
|
||||
(i * 7) % 256 for i in range(2_000_000)
|
||||
])
|
||||
|
||||
# Test data 1: small binary (direct transport)
|
||||
data1 = ("small_binary", small_binary, "binary")
|
||||
|
||||
# Test data 2: large binary (link transport)
|
||||
data2 = ("large_binary", large_binary, "binary")
|
||||
|
||||
log_trace(correlation_id, f"Starting smartsend for subject: {SUBJECT}")
|
||||
log_trace(correlation_id, f"Correlation ID: {correlation_id}")
|
||||
|
||||
# Use smartsend with binary type
|
||||
env = smartsend(
|
||||
SUBJECT,
|
||||
[data1, data2], # List of (dataname, data, type) tuples
|
||||
nats_url=NATS_URL,
|
||||
fileserver_url=FILESERVER_URL,
|
||||
size_threshold=SIZE_THRESHOLD,
|
||||
correlation_id=correlation_id,
|
||||
msg_purpose="chat",
|
||||
sender_name="file_sender",
|
||||
receiver_name="",
|
||||
receiver_id="",
|
||||
reply_to="",
|
||||
reply_to_msg_id=""
|
||||
)
|
||||
|
||||
log_trace(correlation_id, f"Sent message with {len(env.payloads)} payloads")
|
||||
|
||||
# Log transport type for each payload
|
||||
for i, payload in enumerate(env.payloads):
|
||||
log_trace(correlation_id, f"Payload {i+1} ('{payload.dataname}'):")
|
||||
log_trace(correlation_id, f" Transport: {payload.transport}")
|
||||
log_trace(correlation_id, f" Type: {payload.type}")
|
||||
log_trace(correlation_id, f" Size: {payload.size} bytes")
|
||||
log_trace(correlation_id, f" Encoding: {payload.encoding}")
|
||||
|
||||
if payload.transport == "link":
|
||||
log_trace(correlation_id, f" URL: {payload.data}")
|
||||
|
||||
print(f"Test completed. Correlation ID: {correlation_id}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
97
test/test_micropython_mixed_receiver.py
Normal file
97
test/test_micropython_mixed_receiver.py
Normal file
@@ -0,0 +1,97 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Test script for mixed payload testing - Receiver
|
||||
Tests receiving mixed payload types via NATS using nats_bridge.py smartreceive
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
import json
|
||||
|
||||
# Add src to path for import
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'src'))
|
||||
|
||||
from nats_bridge import smartreceive, log_trace
|
||||
import nats
|
||||
import asyncio
|
||||
|
||||
# Configuration
|
||||
SUBJECT = "/NATSBridge_mixed_test"
|
||||
NATS_URL = "nats://nats.yiem.cc:4222"
|
||||
|
||||
|
||||
async def main():
|
||||
log_trace("", f"Starting mixed payload receiver test...")
|
||||
log_trace("", f"Note: This receiver will wait for messages from the sender.")
|
||||
log_trace("", f"Run test_micropython_mixed_sender.py first to send test data.")
|
||||
|
||||
# Connect to NATS
|
||||
nc = await nats.connect(NATS_URL)
|
||||
log_trace("", f"Connected to NATS at {NATS_URL}")
|
||||
|
||||
# Subscribe to the subject
|
||||
async def message_handler(msg):
|
||||
log_trace("", f"Received message on {msg.subject}")
|
||||
|
||||
# Use smartreceive to handle the data
|
||||
result = smartreceive(msg.data)
|
||||
|
||||
log_trace(result.get("correlationId", ""), f"Received envelope with {len(result['payloads'])} payloads")
|
||||
|
||||
# Result is an envelope dictionary with payloads field containing list of (dataname, data, data_type) tuples
|
||||
for dataname, data, data_type in result["payloads"]:
|
||||
log_trace(result.get("correlationId", ""), f"\n--- Payload: {dataname} (type: {data_type}) ---")
|
||||
|
||||
if isinstance(data, str):
|
||||
log_trace(result.get("correlationId", ""), f" Type: text/string")
|
||||
log_trace(result.get("correlationId", ""), f" Length: {len(data)} characters")
|
||||
if len(data) <= 100:
|
||||
log_trace(result.get("correlationId", ""), f" Content: {data}")
|
||||
else:
|
||||
log_trace(result.get("correlationId", ""), f" First 100 chars: {data[:100]}...")
|
||||
# Save to file
|
||||
output_path = f"./received_{dataname}.txt"
|
||||
with open(output_path, 'w') as f:
|
||||
f.write(data)
|
||||
log_trace(result.get("correlationId", ""), f" Saved to: {output_path}")
|
||||
|
||||
elif isinstance(data, dict):
|
||||
log_trace(result.get("correlationId", ""), f" Type: dictionary")
|
||||
log_trace(result.get("correlationId", ""), f" Keys: {list(data.keys())}")
|
||||
log_trace(result.get("correlationId", ""), f" Content: {json.dumps(data, indent=2)}")
|
||||
# Save to file
|
||||
output_path = f"./received_{dataname}.json"
|
||||
with open(output_path, 'w') as f:
|
||||
json.dump(data, f, indent=2)
|
||||
log_trace(result.get("correlationId", ""), f" Saved to: {output_path}")
|
||||
|
||||
elif isinstance(data, bytes):
|
||||
log_trace(result.get("correlationId", ""), f" Type: binary")
|
||||
log_trace(result.get("correlationId", ""), f" Size: {len(data)} bytes")
|
||||
log_trace(result.get("correlationId", ""), f" First 100 bytes (hex): {data[:100].hex()}")
|
||||
# Save to file
|
||||
output_path = f"./received_{dataname}.bin"
|
||||
with open(output_path, 'wb') as f:
|
||||
f.write(data)
|
||||
log_trace(result.get("correlationId", ""), f" Saved to: {output_path}")
|
||||
else:
|
||||
log_trace(result.get("correlationId", ""), f" Received unexpected data type: {type(data)}")
|
||||
|
||||
# Log envelope metadata
|
||||
log_trace(result.get("correlationId", ""), f"\n--- Envelope Metadata ---")
|
||||
log_trace(result.get("correlationId", ""), f" Correlation ID: {result.get('correlationId', 'N/A')}")
|
||||
log_trace(result.get("correlationId", ""), f" Message ID: {result.get('msgId', 'N/A')}")
|
||||
log_trace(result.get("correlationId", ""), f" Sender: {result.get('senderName', 'N/A')}")
|
||||
log_trace(result.get("correlationId", ""), f" Purpose: {result.get('msgPurpose', 'N/A')}")
|
||||
|
||||
sid = await nc.subscribe(SUBJECT, cb=message_handler)
|
||||
log_trace("", f"Subscribed to {SUBJECT} with subscription ID: {sid}")
|
||||
|
||||
# Keep listening for 120 seconds
|
||||
await asyncio.sleep(120)
|
||||
await nc.close()
|
||||
log_trace("", "Test completed.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
93
test/test_micropython_mixed_sender.py
Normal file
93
test/test_micropython_mixed_sender.py
Normal file
@@ -0,0 +1,93 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Test script for mixed payload testing - Micropython
|
||||
Tests sending mixed payload types via NATS using nats_bridge.py smartsend
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
# Add src to path for import
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'src'))
|
||||
|
||||
from nats_bridge import smartsend, log_trace
|
||||
import uuid
|
||||
|
||||
# Configuration
|
||||
SUBJECT = "/NATSBridge_mixed_test"
|
||||
NATS_URL = "nats://nats.yiem.cc:4222"
|
||||
FILESERVER_URL = "http://192.168.88.104:8080"
|
||||
SIZE_THRESHOLD = 1_000_000 # 1MB
|
||||
|
||||
# Create correlation ID for tracing
|
||||
correlation_id = str(uuid.uuid4())
|
||||
|
||||
|
||||
def main():
|
||||
# Create payloads for mixed content test
|
||||
|
||||
# 1. Small text (direct transport)
|
||||
text_data = "Hello, this is a text message for testing mixed payloads!"
|
||||
|
||||
# 2. Small dictionary (direct transport)
|
||||
dict_data = {
|
||||
"status": "ok",
|
||||
"code": 200,
|
||||
"message": "Test successful",
|
||||
"items": [1, 2, 3]
|
||||
}
|
||||
|
||||
# 3. Small binary (direct transport)
|
||||
binary_data = b"\x00\x01\x02\x03\x04\x05" + b"\xff" * 100
|
||||
|
||||
# 4. Large text (link transport - will use fileserver)
|
||||
large_text = "\n".join([
|
||||
f"Line {i}: This is a large text payload for link transport testing. " * 50
|
||||
for i in range(100)
|
||||
])
|
||||
|
||||
# Test data list - mixed payload types
|
||||
data = [
|
||||
("message_text", text_data, "text"),
|
||||
("config_dict", dict_data, "dictionary"),
|
||||
("small_binary", binary_data, "binary"),
|
||||
("large_text", large_text, "text"),
|
||||
]
|
||||
|
||||
log_trace(correlation_id, f"Starting smartsend for subject: {SUBJECT}")
|
||||
log_trace(correlation_id, f"Correlation ID: {correlation_id}")
|
||||
|
||||
# Use smartsend with mixed types
|
||||
env = smartsend(
|
||||
SUBJECT,
|
||||
data, # List of (dataname, data, type) tuples
|
||||
nats_url=NATS_URL,
|
||||
fileserver_url=FILESERVER_URL,
|
||||
size_threshold=SIZE_THRESHOLD,
|
||||
correlation_id=correlation_id,
|
||||
msg_purpose="chat",
|
||||
sender_name="mixed_sender",
|
||||
receiver_name="",
|
||||
receiver_id="",
|
||||
reply_to="",
|
||||
reply_to_msg_id=""
|
||||
)
|
||||
|
||||
log_trace(correlation_id, f"Sent message with {len(env.payloads)} payloads")
|
||||
|
||||
# Log transport type for each payload
|
||||
for i, payload in enumerate(env.payloads):
|
||||
log_trace(correlation_id, f"Payload {i+1} ('{payload.dataname}'):")
|
||||
log_trace(correlation_id, f" Transport: {payload.transport}")
|
||||
log_trace(correlation_id, f" Type: {payload.type}")
|
||||
log_trace(correlation_id, f" Size: {payload.size} bytes")
|
||||
log_trace(correlation_id, f" Encoding: {payload.encoding}")
|
||||
|
||||
if payload.transport == "link":
|
||||
log_trace(correlation_id, f" URL: {payload.data}")
|
||||
|
||||
print(f"Test completed. Correlation ID: {correlation_id}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
69
test/test_micropython_text_receiver.py
Normal file
69
test/test_micropython_text_receiver.py
Normal file
@@ -0,0 +1,69 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Test script for text transport testing - Receiver
|
||||
Tests receiving text messages via NATS using nats_bridge.py smartreceive
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
import json
|
||||
|
||||
# Add src to path for import
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'src'))
|
||||
|
||||
from nats_bridge import smartreceive, log_trace
|
||||
import nats
|
||||
import asyncio
|
||||
|
||||
# Configuration
|
||||
SUBJECT = "/NATSBridge_text_test"
|
||||
NATS_URL = "nats://nats.yiem.cc:4222"
|
||||
|
||||
|
||||
async def main():
|
||||
log_trace("", f"Starting text transport receiver test...")
|
||||
log_trace("", f"Note: This receiver will wait for messages from the sender.")
|
||||
log_trace("", f"Run test_micropython_text_sender.py first to send test data.")
|
||||
|
||||
# Connect to NATS
|
||||
nc = await nats.connect(NATS_URL)
|
||||
log_trace("", f"Connected to NATS at {NATS_URL}")
|
||||
|
||||
# Subscribe to the subject
|
||||
async def message_handler(msg):
|
||||
log_trace("", f"Received message on {msg.subject}")
|
||||
|
||||
# Use smartreceive to handle the data
|
||||
result = smartreceive(msg.data)
|
||||
|
||||
# Result is an envelope dictionary with payloads field containing list of (dataname, data, data_type) tuples
|
||||
for dataname, data, data_type in result["payloads"]:
|
||||
if isinstance(data, str):
|
||||
log_trace(result.get("correlationId", ""), f"Received text '{dataname}' of type {data_type}")
|
||||
log_trace(result.get("correlationId", ""), f" Length: {len(data)} characters")
|
||||
|
||||
# Display first 100 characters
|
||||
if len(data) > 100:
|
||||
log_trace(result.get("correlationId", ""), f" First 100 characters: {data[:100]}...")
|
||||
else:
|
||||
log_trace(result.get("correlationId", ""), f" Content: {data}")
|
||||
|
||||
# Save to file
|
||||
output_path = f"./received_{dataname}.txt"
|
||||
with open(output_path, 'w') as f:
|
||||
f.write(data)
|
||||
log_trace(result.get("correlationId", ""), f"Saved text to {output_path}")
|
||||
else:
|
||||
log_trace(result.get("correlationId", ""), f"Received unexpected data type for '{dataname}': {type(data)}")
|
||||
|
||||
sid = await nc.subscribe(SUBJECT, cb=message_handler)
|
||||
log_trace("", f"Subscribed to {SUBJECT} with subscription ID: {sid}")
|
||||
|
||||
# Keep listening for 120 seconds
|
||||
await asyncio.sleep(120)
|
||||
await nc.close()
|
||||
log_trace("", "Test completed.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
81
test/test_micropython_text_sender.py
Normal file
81
test/test_micropython_text_sender.py
Normal file
@@ -0,0 +1,81 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Test script for text transport testing - Micropython
|
||||
Tests sending text messages via NATS using nats_bridge.py smartsend
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
# Add src to path for import
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'src'))
|
||||
|
||||
from nats_bridge import smartsend, log_trace
|
||||
import uuid
|
||||
|
||||
# Configuration
|
||||
SUBJECT = "/NATSBridge_text_test"
|
||||
NATS_URL = "nats://nats.yiem.cc:4222"
|
||||
FILESERVER_URL = "http://192.168.88.104:8080"
|
||||
SIZE_THRESHOLD = 1_000_000 # 1MB
|
||||
|
||||
# Create correlation ID for tracing
|
||||
correlation_id = str(uuid.uuid4())
|
||||
|
||||
|
||||
def main():
|
||||
# Create a small text (will use direct transport)
|
||||
small_text = "Hello, this is a small text message. Testing direct transport via NATS."
|
||||
|
||||
# Create a large text (will use link transport if > 1MB)
|
||||
# Generate a larger text (~2MB to ensure link transport)
|
||||
large_text = "\n".join([
|
||||
f"Line {i}: This is a sample text line with some content to pad the size. " * 100
|
||||
for i in range(500)
|
||||
])
|
||||
|
||||
# Test data 1: small text
|
||||
data1 = ("small_text", small_text, "text")
|
||||
|
||||
# Test data 2: large text
|
||||
data2 = ("large_text", large_text, "text")
|
||||
|
||||
log_trace(correlation_id, f"Starting smartsend for subject: {SUBJECT}")
|
||||
log_trace(correlation_id, f"Correlation ID: {correlation_id}")
|
||||
|
||||
# Use smartsend with text type
|
||||
# For small text: will use direct transport (Base64 encoded UTF-8)
|
||||
# For large text: will use link transport (uploaded to fileserver)
|
||||
env = smartsend(
|
||||
SUBJECT,
|
||||
[data1, data2], # List of (dataname, data, type) tuples
|
||||
nats_url=NATS_URL,
|
||||
fileserver_url=FILESERVER_URL,
|
||||
size_threshold=SIZE_THRESHOLD,
|
||||
correlation_id=correlation_id,
|
||||
msg_purpose="chat",
|
||||
sender_name="text_sender",
|
||||
receiver_name="",
|
||||
receiver_id="",
|
||||
reply_to="",
|
||||
reply_to_msg_id=""
|
||||
)
|
||||
|
||||
log_trace(correlation_id, f"Sent message with {len(env.payloads)} payloads")
|
||||
|
||||
# Log transport type for each payload
|
||||
for i, payload in enumerate(env.payloads):
|
||||
log_trace(correlation_id, f"Payload {i+1} ('{payload.dataname}'):")
|
||||
log_trace(correlation_id, f" Transport: {payload.transport}")
|
||||
log_trace(correlation_id, f" Type: {payload.type}")
|
||||
log_trace(correlation_id, f" Size: {payload.size} bytes")
|
||||
log_trace(correlation_id, f" Encoding: {payload.encoding}")
|
||||
|
||||
if payload.transport == "link":
|
||||
log_trace(correlation_id, f" URL: {payload.data}")
|
||||
|
||||
print(f"Test completed. Correlation ID: {correlation_id}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user