1# Example showing how to define stream for latency measurement, and how to parse the latency information
2
3import stl_path
4from trex_stl_lib.api import *
5
6import time
7import pprint
8
9def rx_example (tx_port, rx_port, burst_size, pps):
10
11    print("\nGoing to inject {0} packets on port {1} - checking RX stats on port {2}\n".format(burst_size, tx_port, rx_port))
12
13    # create client
14    c = STLClient()
15    passed = True
16
17    try:
18        pkt = STLPktBuilder(pkt = Ether()/IP(src="16.0.0.1",dst="48.0.0.1")/UDP(dport=12,sport=1025)/'at_least_16_bytes_payload_needed')
19        total_pkts = burst_size
20        s1 = STLStream(name = 'rx',
21                       packet = pkt,
22                       flow_stats = STLFlowLatencyStats(pg_id = 5),
23                       mode = STLTXSingleBurst(total_pkts = total_pkts,
24                                               pps = pps))
25
26        # connect to server
27        c.connect()
28
29        # prepare our ports
30        c.reset(ports = [tx_port, rx_port])
31
32        # add both streams to ports
33        c.add_streams([s1], ports = [tx_port])
34
35        print("\nInjecting {0} packets on port {1}\n".format(total_pkts, tx_port))
36
37        rc = rx_iteration(c, tx_port, rx_port, total_pkts, pkt.get_pkt_len())
38        if not rc:
39            passed = False
40
41    except STLError as e:
42        passed = False
43        print(e)
44
45    finally:
46        c.disconnect()
47
48    if passed:
49        print("\nTest passed :-)\n")
50    else:
51        print("\nTest failed :-(\n")
52
53# RX one iteration
54def rx_iteration (c, tx_port, rx_port, total_pkts, pkt_len):
55
56    c.clear_stats()
57
58    c.start(ports = [tx_port])
59    c.wait_on_traffic(ports = [tx_port])
60
61    stats = c.get_stats()
62    flow_stats = stats['flow_stats'].get(5)
63    global_lat_stats = stats['latency']
64    lat_stats = global_lat_stats.get(5)
65    if not flow_stats:
66        print("no flow stats available")
67        return False
68    if not lat_stats:
69        print("no latency stats available")
70        return False
71
72    tx_pkts  = flow_stats['tx_pkts'].get(tx_port, 0)
73    tx_bytes = flow_stats['tx_bytes'].get(tx_port, 0)
74    rx_pkts  = flow_stats['rx_pkts'].get(rx_port, 0)
75    drops = lat_stats['err_cntrs']['dropped']
76    ooo = lat_stats['err_cntrs']['out_of_order']
77    dup = lat_stats['err_cntrs']['dup']
78    sth = lat_stats['err_cntrs']['seq_too_high']
79    stl = lat_stats['err_cntrs']['seq_too_low']
80    old_flow = global_lat_stats['global']['old_flow']
81    bad_hdr = global_lat_stats['global']['bad_hdr']
82    lat = lat_stats['latency']
83    jitter = lat['jitter']
84    avg = lat['average']
85    tot_max = lat['total_max']
86    tot_min = lat['total_min']
87    last_max = lat['last_max']
88    hist = lat ['histogram']
89
90    if c.get_warnings():
91            print("\n\n*** test had warnings ****\n\n")
92            for w in c.get_warnings():
93                print(w)
94            return False
95
96    print('Error counters: dropped:{0}, ooo:{1} dup:{2} seq too high:{3} seq too low:{4}'.format(drops, ooo, dup, sth, stl))
97    if old_flow:
98        print ('Packets arriving too late after flow stopped: {0}'.format(old_flow))
99    if bad_hdr:
100        print ('Latency packets with corrupted info: {0}'.format(bad_hdr))
101    print('Latency info:')
102    print("  Maximum latency(usec): {0}".format(tot_max))
103    print("  Minimum latency(usec): {0}".format(tot_min))
104    print("  Maximum latency in last sampling period (usec): {0}".format(last_max))
105    print("  Average latency(usec): {0}".format(avg))
106    print("  Jitter(usec): {0}".format(jitter))
107    print("  Latency distribution histogram:")
108    l = hist.keys()
109    l.sort()
110    for sample in l:
111        range_start = sample
112        if range_start == 0:
113            range_end = 10
114        else:
115            range_end  = range_start + pow(10, (len(str(range_start))-1))
116        val = hist[sample]
117        print ("    Packets with latency between {0} and {1}:{2} ".format(range_start, range_end, val))
118
119    if tx_pkts != total_pkts:
120        print("TX pkts mismatch - got: {0}, expected: {1}".format(tx_pkts, total_pkts))
121        pprint.pprint(flow_stats)
122        return False
123    else:
124        print("TX pkts match   - {0}".format(tx_pkts))
125
126    if tx_bytes != (total_pkts * (pkt_len + 4)): # +4 for ethernet CRC
127        print("TX bytes mismatch - got: {0}, expected: {1}".format(tx_bytes, (total_pkts * pkt_len)))
128        pprint.pprint(flow_stats)
129        return False
130    else:
131        print("TX bytes match  - {0}".format(tx_bytes))
132
133    if rx_pkts != total_pkts:
134        print("RX pkts mismatch - got: {0}, expected: {1}".format(rx_pkts, total_pkts))
135        pprint.pprint(flow_stats)
136        return False
137    else:
138        print("RX pkts match   - {0}".format(rx_pkts))
139
140    return True
141
142# run the tests
143rx_example(tx_port = 0, rx_port = 1, burst_size = 1000, pps = 1000)
144
145