Skip to content

Commit e2d4f89

Browse files
committed
add cli scripts support.
1 parent 6fd56a8 commit e2d4f89

30 files changed

+248
-180
lines changed

net_test_tools/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from .plot import *

net_test_tools/common/frame.py

-46
This file was deleted.

net_test_tools/common/dataset.py net_test_tools/dataset.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import random
22
from typing import List
33

4-
from net_test_tools.common.utils import Multiset, hex_str
4+
from net_test_tools.utils import Multiset, hex_str
55

66

77
def generate_file(path: str,

net_test_tools/frame.py

+46-84
Original file line numberDiff line numberDiff line change
@@ -1,84 +1,46 @@
1-
from enum import IntEnum
2-
from typing import Dict
3-
4-
5-
class FragFlag(IntEnum):
6-
NOT = 0
7-
START = 1
8-
CONTINUE = 2
9-
END = 3
10-
11-
@staticmethod
12-
def check(value: int):
13-
type_dict = {
14-
0: FragFlag.NOT,
15-
1: FragFlag.START,
16-
2: FragFlag.CONTINUE,
17-
3: FragFlag.END
18-
}
19-
if value in type_dict:
20-
return type_dict[value]
21-
else:
22-
raise ValueError("Invalid fragment flag value.")
23-
24-
25-
class Frame:
26-
BYTE_ORDER = 'big'
27-
HEADER_COST = 1 + 2 + 2 + 1
28-
MAX_PAYLOAD_LEN = 2048 - HEADER_COST
29-
30-
def __init__(self, frame_type: int, payload_len: int, seq: int, frag_flag: FragFlag, data: bytes):
31-
assert frame_type == 0xff
32-
assert 2 <= payload_len <= Frame.MAX_PAYLOAD_LEN
33-
assert 0 <= seq < 2 ** 16
34-
assert frag_flag in FragFlag
35-
assert 0 <= len(data) <= Frame.MAX_PAYLOAD_LEN
36-
37-
self.frame_type = frame_type # 0xff
38-
self.payload_len = payload_len
39-
self.seq = seq
40-
self.frag_flag = frag_flag
41-
self.data = data
42-
43-
@staticmethod
44-
def from_dict(data: Dict):
45-
return Frame(**data)
46-
47-
@staticmethod
48-
def from_bytes(data: bytes):
49-
frame_type = int(data[0])
50-
payload_len = int(data[1:1+2].hex(), base=16)
51-
if len(data) < Frame.HEADER_COST + payload_len:
52-
raise ValueError("Invalid length of payload")
53-
seq = int(data[3:3+2].hex(), base=16)
54-
frag_flag = FragFlag.check(data[5])
55-
data = data[6:6+payload_len]
56-
return Frame(frame_type, payload_len, seq, frag_flag, data)
57-
58-
def to_bytes(self):
59-
result = self.frame_type.to_bytes(1, self.BYTE_ORDER) \
60-
+ self.payload_len.to_bytes(2, self.BYTE_ORDER) \
61-
+ self.seq.to_bytes(2, self.BYTE_ORDER) \
62-
+ self.frag_flag.value.to_bytes(1, self.BYTE_ORDER) \
63-
+ self.data
64-
65-
return result
66-
67-
def to_dict(self):
68-
return {
69-
"frame_type": self.frame_type,
70-
"payload_len": self.payload_len,
71-
"seq": self.seq,
72-
"frag_flag": self.frag_flag,
73-
"data": self.data
74-
}
75-
76-
77-
if __name__ == "__main__":
78-
f1 = Frame.from_bytes(b"\xff\x00\x03\x00\x00\x00\x01\x02\x03")
79-
print(f1.to_dict())
80-
print(f1.to_bytes())
81-
82-
f2 = Frame.from_dict(f1.to_dict())
83-
print(f2.to_dict())
84-
print(f2.to_bytes())
1+
"""
2+
简易的帧解析和生成,仅支持线性帧结构
3+
"""
4+
5+
import struct
6+
from typing import Any
7+
8+
9+
class LinearFrame:
10+
"""
11+
basic use format string in struct, expect bare 's' means greedy bytes.
12+
"""
13+
def __init__(self, spec: dict[str, str]):
14+
self.spec = spec
15+
16+
def serialize(self, *args) -> bytes:
17+
if len(args) != len(self.spec):
18+
raise Exception
19+
20+
frame = b""
21+
# for each section
22+
for i, fc in enumerate(self.spec.values()):
23+
arg = args[i]
24+
if fc == "s":
25+
fmt = str(len(arg)) + "s"
26+
else:
27+
fmt = fc
28+
section = struct.pack(fmt, arg)
29+
frame += section
30+
return frame
31+
32+
def deserialize(self, frame: bytes) -> dict[Any]:
33+
ret = {}
34+
ptr = 0
35+
# for each section
36+
for i, item in enumerate(self.spec.items()):
37+
label, fc = item[0], item[1]
38+
if fc == "s":
39+
fmt = str(len(frame) - ptr) + "s"
40+
else:
41+
fmt = fc
42+
size = struct.calcsize(fmt)
43+
value = struct.unpack(fmt, frame[ptr:ptr+size])[0]
44+
ptr += size
45+
ret[label] = value
46+
return ret

net_test_tools/common/plot.py net_test_tools/plot.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from matplotlib import pyplot as plt
22

3-
from net_test_tools.common.utils import Multiset
3+
from net_test_tools.utils import Multiset
44

55

66
def plot_t_ul(data: list[tuple[int, float]]):

net_test_tools/scripts/udping_master.py

+12-8
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import click
2-
# from typing import Optional
32

4-
from net_test_tools.topic import test_ul_dl_delay
3+
from net_test_tools.topic import udping
54

65

76
@click.command()
@@ -33,26 +32,31 @@
3332
"--random_size", "-r",
3433
type=bool,
3534
help="Whether size of each packet is random.",
36-
default=True
35+
default=True,
36+
show_default=True
3737
)
3838
@click.option(
3939
"--interval", "-i",
4040
type=float,
4141
help="Interval of transmit.",
42-
default=1
42+
default=1,
43+
show_default=True
4344
)
4445
@click.option(
45-
"--tx_only",
46+
"--no_echo", "-ne",
4647
type=bool,
4748
help="Whether only to transmit, meaning lower interval is acceptable.",
48-
default=False
49+
default=False,
50+
show_default=True,
51+
is_flag=True
4952
)
5053
def udping_master(
5154
local: tuple[str, int], remote: tuple[str, int],
5255
packet_size: int, n_packet: int, random_size: bool,
53-
interval: float, tx_only: bool
56+
interval: float, no_echo: bool
5457
):
55-
test_ul_dl_delay.run_master(
58+
tx_only = no_echo
59+
udping.run_master(
5660
local, remote, packet_size, n_packet, random_size=random_size, interval=interval, tx_only=tx_only
5761
)
5862

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import click
2+
from typing import Optional
3+
4+
from net_test_tools.topic import udping
5+
from net_test_tools.plot import plot_t_ul, plot_t_ul_hist
6+
7+
8+
@click.command()
9+
@click.option(
10+
"--local",
11+
type=(str, int),
12+
help="Address of local.",
13+
required=True
14+
)
15+
@click.option(
16+
"--remote",
17+
type=(str, int),
18+
help="Address of remote.",
19+
default=None,
20+
show_default=True
21+
)
22+
@click.option(
23+
"--plot_line_chart", "-pl",
24+
type=bool,
25+
help="Plot line chart of UL delay.",
26+
is_flag=True,
27+
default=False,
28+
show_default=True
29+
)
30+
@click.option(
31+
"--plot_histogram", "-ph",
32+
type=bool,
33+
help="Plot histogram of UL delay.",
34+
is_flag=True,
35+
default=False,
36+
show_default=True
37+
)
38+
@click.option(
39+
"--no_echo", "-ne",
40+
type=bool,
41+
help="Whether to echo.",
42+
is_flag=True,
43+
default=False,
44+
show_default=True,
45+
)
46+
def udping_slave(
47+
local: tuple[str, int], remote: Optional[tuple[str, int]],
48+
plot_line_chart: bool, plot_histogram: bool,
49+
no_echo: bool
50+
):
51+
echo = not no_echo
52+
data = udping.run_slave(
53+
local, remote, echo=echo
54+
)
55+
if plot_line_chart:
56+
plot_t_ul(data)
57+
if plot_histogram:
58+
plot_t_ul_hist(data)
59+
60+
61+
if __name__ == "__main__":
62+
udping_slave()

net_test_tools/self_tests/__init__.py

Whitespace-only changes.
File renamed without changes.

net_test_tools/self_tests/test_linear_frame.py net_test_tools/tests/test_linear_frame.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from net_test_tools.common.frame import LinearFrame
1+
from net_test_tools.frame import LinearFrame
22

33

44
def test_reverse():

net_test_tools/topic/test_echo/master_async.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import time
33

44
from .master_sync import prepare_dataset
5-
from net_test_tools.common.utils import hex_str
5+
from net_test_tools.utils import hex_str
66

77

88
async def main(

net_test_tools/topic/test_echo/master_sync.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
import time
33
from typing import Optional
44

5-
from net_test_tools.common.dataset import generate
6-
from net_test_tools.common.transceiver import Transceiver
7-
from net_test_tools.common.utils import hex_str
5+
from net_test_tools.dataset import generate
6+
from net_test_tools.transceiver import Transceiver
7+
from net_test_tools.utils import hex_str
88

99

1010
def prepare_dataset(max_packet_size: int, n_packet: int, *, random_size: bool):

net_test_tools/topic/test_echo/slave.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
from net_test_tools.common.transceiver import Transceiver
2-
from net_test_tools.common.utils import hex_str
1+
from net_test_tools.transceiver import Transceiver
2+
from net_test_tools.utils import hex_str
33

44

55
class TestEchoLossSlave:

net_test_tools/topic/test_image/__init__.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
transmit image in fragments.
33
"""
44

5-
from .transmit import *
6-
from .receive import *
5+
from .transmit import transmit_image
6+
from .receive import listen_until_timeout
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from net_test_tools.transceiver import Frame
2+
3+
4+
if __name__ == "__main__":
5+
f1 = Frame.from_bytes(b"\xff\x00\x03\x00\x00\x00\x01\x02\x03")
6+
print(f1.to_dict())
7+
print(f1.to_bytes())
8+
9+
f2 = Frame.from_dict(f1.to_dict())
10+
print(f2.to_dict())
11+
print(f2.to_bytes())

net_test_tools/topic/test_image/receive.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import cv2
22
import numpy as np
3-
from net_test_tools.common.transceiver import Transceiver, FragFailure
3+
from net_test_tools.transceiver import Transceiver, FragFailure
44
from typing import Tuple
55

66

net_test_tools/topic/test_image/transmit.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import cv2
22
from typing import Tuple
3-
from net_test_tools.common.transceiver import Transceiver
3+
from net_test_tools.transceiver import Transceiver
44

55

66
def transmit_image(local: Tuple[str, int], remote: Tuple[str, int], path: str, *, interval=0):

net_test_tools/topic/test_loss/receive.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
from typing import Tuple, Optional
33
from collections import deque
44

5-
from net_test_tools.common.dataset import preprocess
6-
from net_test_tools.common.transceiver import Transceiver
7-
from net_test_tools.common.utils import Multiset, hex_str
5+
from net_test_tools.dataset import preprocess
6+
from net_test_tools.transceiver import Transceiver
7+
from net_test_tools.utils import Multiset, hex_str
88

99

1010
def receive_for_dataset(

0 commit comments

Comments
 (0)