Files
virtual_simulation_midware/tests/test_udp_performance.py

148 lines
6.1 KiB
Python
Raw Normal View History

2026-06-16 15:40:19 +08:00
"""
验证工程满足1553B 6-12us 响应同时支持 10 个单机接入CAN/1553B 消息顺序发送的性能需求在test/下创建test_udp_performance.py
2026/2/26
Tan Mingyan
"""
import socket
import binascii
import time
import threading
from midware.config.base_config import DEVICE_CONFIG_DICT, UDP_CONFIG
# 全局配置
LOCAL_IP = UDP_CONFIG["LOCAL_IP"]
FAULT_PORT = UDP_CONFIG["FAULT_INJECT_PORT"]
BUFFER_SIZE = 4096
# 测试用1553B外设端口取CSV中的1553B0/1553B1如8882/8886
B1553B_PORTS = [dev_info["udp_port"] for dev_name, dev_info in DEVICE_CONFIG_DICT.items() if dev_info["protocol"] == "1553B"]
# CAN外设端口
CAN_PORTS = [dev_info["udp_port"] for dev_name, dev_info in DEVICE_CONFIG_DICT.items() if dev_info["protocol"] == "CAN"]
# 10个测试端口覆盖所有协议
TEST_PORTS = [dev_info["udp_port"] for dev_name, dev_info in DEVICE_CONFIG_DICT.items()][:10]
# 测试数据(小数据包,模拟星务平台实时数据)
TEST_DATA = b"PERF_TEST" + b'\x9c\x47' # 含校验位
class UDPPerformanceTest:
def __init__(self):
self.send_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.send_sock.setblocking(False)
# 接收套接字(统计回传时延)
self.recv_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.recv_sock.bind((LOCAL_IP, FAULT_PORT))
self.recv_sock.setblocking(False)
# 时延统计
self.latency_list = []
# 并发计数
self.send_count = 0
self.recv_count = 0
def _calc_latency(self, port, send_ts):
"""计算单包时延:发送时间→接收回传时间"""
try:
data, _ = self.recv_sock.recvfrom(BUFFER_SIZE)
recv_ts = time.time()
latency = (recv_ts - send_ts) * 1000000 # 转换为微秒(us)
self.latency_list.append(latency)
self.recv_count += 1
print(f"1553B端口{port} | 响应时延:{latency:.2f}us | 累计接收:{self.recv_count}")
except:
pass
def test_1553b_latency(self, test_times=1000):
"""测试1553B响应时延要求6-12us发送test_times次数据包"""
if not B1553B_PORTS:
print("❌ 未配置1553B外设跳过时延测试")
return
test_port = B1553B_PORTS[0]
print(f"===== 1553B时延测试端口{test_port},发送{test_times}次) =====")
self.latency_list.clear()
self.recv_count = 0
for i in range(test_times):
send_ts = time.time()
# 发送数据
hex_data = binascii.hexlify(TEST_DATA).decode("utf-8")
self.send_sock.sendto(hex_data.encode("utf-8"), (LOCAL_IP, test_port))
# 立即统计时延(模拟中间层实时回传)
self._calc_latency(test_port, send_ts)
# 微秒级间隔,模拟星务平台请求频率
time.sleep(0.000001)
# 统计结果
if self.latency_list:
avg_latency = sum(self.latency_list) / len(self.latency_list)
min_latency = min(self.latency_list)
max_latency = max(self.latency_list)
print(f"\n1553B时延统计 | 平均:{avg_latency:.2f}us | 最小:{min_latency:.2f}us | 最大:{max_latency:.2f}us")
if avg_latency >=6 and avg_latency <=12:
print("✅ 1553B时延满足要求6-12us")
else:
print("❌ 1553B时延不满足要求")
def test_10_device_concurrent(self, test_times=500):
"""测试10个单机并发接入同时发送验证无丢包"""
if len(TEST_PORTS) <10:
print("❌ 未配置10个外设跳过多机并发测试")
return
print(f"===== 10机并发测试发送{test_times}次/机) =====")
self.send_count = 0
self.recv_count = 0
def send_task(port):
for _ in range(test_times):
hex_data = binascii.hexlify(TEST_DATA).decode("utf-8")
self.send_sock.sendto(hex_data.encode("utf-8"), (LOCAL_IP, port))
self.send_count +=1
time.sleep(0.0001)
# 启动10个线程对应10个外设
threads = [threading.Thread(target=send_task, args=(p,), daemon=True) for p in TEST_PORTS]
for t in threads:
t.start()
for t in threads:
t.join()
# 等待接收完成
time.sleep(2)
loss_rate = (self.send_count - self.recv_count) / self.send_count * 100
print(f"总发送:{self.send_count} | 总接收:{self.recv_count} | 丢包率:{loss_rate:.2f}%")
if loss_rate == 0:
print("✅ 10机并发测试通过无丢包")
else:
print("❌ 10机并发测试失败存在丢包")
def test_can_b1553b_order(self):
"""测试CAN/1553B消息顺序发送要求一个节点发完再发下一个"""
print("===== CAN/1553B消息顺序测试 =====")
# 按顺序发送多个节点数据,查看中间层日志
test_ports = CAN_PORTS[:2] + B1553B_PORTS[:2]
for port in test_ports:
hex_data = binascii.hexlify(TEST_DATA + str(port).encode()).decode("utf-8")
self.send_sock.sendto(hex_data.encode("utf-8"), (LOCAL_IP, port))
print(f"按顺序发送:端口{port} 数据标识:{port}")
time.sleep(0.001)
print("✅ 请查看工程logs/run_*.log验证日志中节点数据是否按发送顺序打印无乱序")
def close(self):
self.send_sock.close()
self.recv_sock.close()
if __name__ == "__main__":
perf_test = UDPPerformanceTest()
try:
# 1. 1553B时延测试发送1000次
perf_test.test_1553b_latency(test_times=1000)
time.sleep(3)
# 2. 10机并发测试每机发送500次
perf_test.test_10_device_concurrent(test_times=500)
time.sleep(3)
# 3. CAN/1553B消息顺序测试
perf_test.test_can_b1553b_order()
except KeyboardInterrupt:
print("\n用户终止性能测试")
finally:
perf_test.close()