Skip to content

Commit 1c88274

Browse files
author
Kamil Vojanec
committed
common: introduce common conversion functions
1 parent b400cc7 commit 1c88274

File tree

2 files changed

+124
-0
lines changed

2 files changed

+124
-0
lines changed

lbr_testsuite/common/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,14 @@
55
local_tests,
66
wait_until_condition,
77
)
8+
from .conv import mbps_to_mpps, mpps_to_mbps, parse_size
89
from .sysctl import sysctl_get, sysctl_set, sysctl_set_with_restore
910

1011

1112
__all__ = [
13+
"mbps_to_mpps",
14+
"mpps_to_mbps",
15+
"parse_size",
1216
"sysctl_set",
1317
"sysctl_get",
1418
"sysctl_set_with_restore",

lbr_testsuite/common/conv.py

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
"""
2+
Author(s): Kamil Vojanec <[email protected]>
3+
4+
Copyright: (C) 2024 CESNET, z.s.p.o.
5+
6+
Common conversion functions.
7+
"""
8+
9+
import re
10+
from enum import StrEnum
11+
12+
13+
"""
14+
Extra bytes added to L2 packet size when converting:
15+
7B preamble + 1B SoF + 4B CRC + 12B minimal IFG.
16+
"""
17+
PACKET_EXTRA_BYTES = 24
18+
19+
20+
def mbps_to_mpps(thrpt_mbps: float, pkt_len: int):
21+
"""Convert megabits per second throughput into megapackets per second.
22+
23+
Parameters
24+
----------
25+
thrpt_mbps : float
26+
Throughput value in megabits per second (on L1).
27+
pkt_len : int
28+
Individual packet length in bytes (on L2 without FCS).
29+
30+
Returns
31+
-------
32+
float
33+
Throughput value in megapackets per second.
34+
"""
35+
36+
return thrpt_mbps / ((pkt_len + PACKET_EXTRA_BYTES) * 8)
37+
38+
39+
def mpps_to_mbps(thrpt_mpps: float, pkt_len: int):
40+
"""Convert megapackets per second throughput into megabits per second.
41+
42+
Parameters
43+
----------
44+
thrpt_mpps : float
45+
Throughput value in megapackets per second.
46+
pkt_len : int
47+
Individual packet length in bytes (on L2 without FCS).
48+
49+
Returns
50+
-------
51+
float
52+
Throughput value in megabits per second (on L1).
53+
"""
54+
55+
return thrpt_mpps * ((pkt_len + PACKET_EXTRA_BYTES) * 8)
56+
57+
58+
class UnitsPolicy(StrEnum):
59+
"""Units policy to be used in size conversion.
60+
Used to avoid confusion when comparing decimal and binary
61+
size values.
62+
"""
63+
64+
"""SI defines base 10 prefixes for conversion.
65+
See: https://en.wikipedia.org/wiki/Metric_prefix#List_of_SI_prefixes
66+
"""
67+
SI = "si"
68+
69+
"""IEC Defines binary prefixes for conversion.
70+
See: https://en.wikipedia.org/wiki/Binary_prefix#Prefixes
71+
"""
72+
IEC = "iec"
73+
74+
75+
def parse_size(
76+
size_str: str,
77+
units: UnitsPolicy = UnitsPolicy.SI,
78+
) -> int:
79+
"""Parse size - value with k, M, G suffix into
80+
an integer representing the size in bytes.
81+
82+
Parameters
83+
----------
84+
size_str : str
85+
Size string to be parsed. Contains a value
86+
with a unit (k, M, G, T).
87+
units : UnitsPolicy
88+
Specify the unit used for conversion.
89+
90+
Returns
91+
-------
92+
int
93+
Integer size in bytes.
94+
"""
95+
96+
# First match group matches the value.
97+
# Second match group matches the unit.
98+
reg = r"(\d+)\s*([kMGT])"
99+
match = re.match(reg, size_str).groups()
100+
101+
assert len(match) == 2, "Must match only the value and unit"
102+
103+
mult_table = {
104+
UnitsPolicy.SI: {
105+
"k": 1e3,
106+
"M": 1e6,
107+
"G": 1e9,
108+
"T": 1e12,
109+
},
110+
UnitsPolicy.IEC: {
111+
"k": 2**10,
112+
"M": 2**20,
113+
"G": 2**30,
114+
"T": 2**40,
115+
},
116+
}
117+
118+
val = int(match[0])
119+
mult = mult_table[units][match[1]]
120+
return val * mult

0 commit comments

Comments
 (0)