blob: 2615c32ce8663b89f9d5a4330a31a715de8cfaee [file] [log] [blame]
Renato Botelho do Coutoead1e532019-10-31 13:31:07 -05001#!/usr/bin/env python3
Paul Vinciguerra59954822019-03-11 05:04:12 -07002
3import unittest
Paul Vinciguerra59954822019-03-11 05:04:12 -07004import psutil
5from vpp_papi.vpp_stats import VPPStats
6
Dave Wallace8800f732023-08-31 00:47:44 -04007from framework import VppTestCase
8from asfframework import VppTestRunner
Arthur de Kerhordb023802021-03-11 10:26:54 -08009from scapy.layers.l2 import Ether
10from scapy.layers.inet import IP
Paul Vinciguerra59954822019-03-11 05:04:12 -070011
12
13class StatsClientTestCase(VppTestCase):
14 """Test Stats Client"""
15
16 @classmethod
17 def setUpClass(cls):
18 super(StatsClientTestCase, cls).setUpClass()
19
20 @classmethod
21 def tearDownClass(cls):
22 super(StatsClientTestCase, cls).tearDownClass()
23
Benoît Ganne79cb1d52023-02-24 16:13:29 +010024 def setUp(self):
25 super(StatsClientTestCase, self).setUp()
26 self.create_pg_interfaces([])
27
28 def tearDown(self):
29 super(StatsClientTestCase, self).tearDown()
30 for i in self.pg_interfaces:
31 i.unconfig()
32 i.admin_down()
33
Arthur de Kerhordb023802021-03-11 10:26:54 -080034 @classmethod
35 def setUpConstants(cls):
36 cls.extra_vpp_statseg_config = "per-node-counters on"
37 cls.extra_vpp_statseg_config += "update-interval 0.05"
38 super(StatsClientTestCase, cls).setUpConstants()
39
Ole Troan233e4682019-05-16 15:01:34 +020040 def test_set_errors(self):
41 """Test set errors"""
42 self.assertEqual(self.statistics.set_errors(), {})
Ole Troane66443c2021-03-18 11:12:01 +010043 self.assertEqual(
Benoît Ganne79cb1d52023-02-24 16:13:29 +010044 self.statistics.get_counter("/err/ethernet-input/no error"),
45 [0] * (1 + self.vpp_worker_count),
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020046 )
Ole Troan233e4682019-05-16 15:01:34 +020047
Paul Vinciguerra59954822019-03-11 05:04:12 -070048 def test_client_fd_leak(self):
49 """Test file descriptor count - VPP-1486"""
50
51 cls = self.__class__
52 p = psutil.Process()
53 initial_fds = p.num_fds()
54
55 for _ in range(100):
Klement Sekerae2636852021-03-16 12:52:12 +010056 stats = VPPStats(socketname=cls.get_stats_sock_path())
Paul Vinciguerra59954822019-03-11 05:04:12 -070057 stats.disconnect()
58
59 ending_fds = p.num_fds()
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020060 self.assertEqual(
61 initial_fds,
62 ending_fds,
63 "initial client side file descriptor count: %s "
64 "is not equal to "
65 "ending client side file descriptor count: %s" % (initial_fds, ending_fds),
66 )
Steven Luongc79b32d2019-06-18 09:56:07 -070067
Arthur de Kerhordb023802021-03-11 10:26:54 -080068 def test_symlink_values(self):
69 """Test symlinks reported values"""
70 self.create_pg_interfaces(range(2))
71
72 for i in self.pg_interfaces:
73 i.admin_up()
74 i.config_ip4()
75 i.resolve_arp()
76
77 p = list()
78 for i in range(5):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020079 packet = Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) / IP(
80 src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4
81 )
Arthur de Kerhordb023802021-03-11 10:26:54 -080082 p.append(packet)
83
84 self.send_and_expect(self.pg0, p, self.pg1)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020085 pg1_tx = self.statistics.get_counter("/interfaces/pg1/tx")
86 if_tx = self.statistics.get_counter("/if/tx")
Arthur de Kerhordb023802021-03-11 10:26:54 -080087
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020088 self.assertEqual(pg1_tx[0]["bytes"], if_tx[0][self.pg1.sw_if_index]["bytes"])
Arthur de Kerhordb023802021-03-11 10:26:54 -080089
90 def test_symlink_add_del_interfaces(self):
91 """Test symlinks when adding and deleting interfaces"""
92 # We first create and delete interfaces
93 self.create_loopback_interfaces(1)
94 self.create_pg_interfaces(range(1))
95 self.loop0.remove_vpp_config()
96 self.create_pg_interfaces(range(2))
97
98 for i in self.pg_interfaces:
99 i.admin_up()
100 i.config_ip4()
101 i.resolve_arp()
102
103 p = list()
104 bytes_to_send = 0
105 for i in range(5):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200106 packet = Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) / IP(
107 src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4
108 )
Arthur de Kerhordb023802021-03-11 10:26:54 -0800109 bytes_to_send += len(packet)
110 p.append(packet)
111
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200112 tx_before_sending = self.statistics.get_counter("/interfaces/pg1/tx")
113 rx_before_sending = self.statistics.get_counter("/interfaces/pg0/rx")
Arthur de Kerhordb023802021-03-11 10:26:54 -0800114 self.send_and_expect(self.pg0, p, self.pg1)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200115 tx = self.statistics.get_counter("/interfaces/pg1/tx")
116 rx = self.statistics.get_counter("/interfaces/pg0/rx")
Arthur de Kerhordb023802021-03-11 10:26:54 -0800117
118 # We wait for nodes symlinks to update (interfaces created/deleted).
Benoît Ganne79cb1d52023-02-24 16:13:29 +0100119 self.virtual_sleep(1)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200120 vectors = self.statistics.get_counter("/nodes/pg1-tx/vectors")
Arthur de Kerhordb023802021-03-11 10:26:54 -0800121
Benoît Ganne79cb1d52023-02-24 16:13:29 +0100122 rx_bytes = 0
123 rx_packets = 0
124 tx_bytes = 0
125 tx_packets = 0
126 for i in range(1 + self.vpp_worker_count):
127 rx_bytes += rx[i]["bytes"] - rx_before_sending[i]["bytes"]
128 rx_packets += rx[i]["packets"] - rx_before_sending[i]["packets"]
129 tx_bytes += tx[i]["bytes"] - tx_before_sending[i]["bytes"]
130 tx_packets += tx[i]["packets"] - tx_before_sending[i]["packets"]
131 self.assertEqual(tx_bytes, bytes_to_send)
132 self.assertEqual(tx_packets, 5)
133 self.assertEqual(rx_bytes, bytes_to_send)
134 self.assertEqual(rx_packets, 5)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200135 self.assertEqual(vectors[0], rx[0]["packets"])
Arthur de Kerhordb023802021-03-11 10:26:54 -0800136
Arthur de Kerhordb023802021-03-11 10:26:54 -0800137 def test_index_consistency(self):
138 """Test index consistency despite changes in the stats"""
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200139 d = self.statistics.ls(["/if/names"])
Arthur de Kerhordb023802021-03-11 10:26:54 -0800140 self.create_loopback_interfaces(10)
141 for i in range(10):
142 try:
143 s = self.statistics.dump(d)
144 break
145 except:
146 pass
147 k, v = s.popitem()
148 self.assertEqual(len(v), 11)
149
150 for i in self.lo_interfaces:
151 i.remove_vpp_config()
152
Ole Troan92e30822019-06-16 12:33:51 +0200153 @unittest.skip("Manual only")
154 def test_mem_leak(self):
155 def loop():
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200156 print("Running loop")
Ole Troan92e30822019-06-16 12:33:51 +0200157 for i in range(50):
158 rv = self.vapi.papi.tap_create_v2(id=i, use_random_mac=1)
159 self.assertEqual(rv.retval, 0)
160 rv = self.vapi.papi.tap_delete_v2(sw_if_index=rv.sw_if_index)
161 self.assertEqual(rv.retval, 0)
162
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200163 before = self.statistics.get_counter("/mem/statseg/used")
Ole Troan92e30822019-06-16 12:33:51 +0200164 loop()
165 self.vapi.cli("memory-trace on stats-segment")
166 for j in range(100):
167 loop()
168 print(self.vapi.cli("show memory stats-segment verbose"))
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200169 print("AFTER", before, self.statistics.get_counter("/mem/statseg/used"))
Steven Luongc79b32d2019-06-18 09:56:07 -0700170
Paul Vinciguerra59954822019-03-11 05:04:12 -0700171
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200172if __name__ == "__main__":
Paul Vinciguerra59954822019-03-11 05:04:12 -0700173 unittest.main(testRunner=VppTestRunner)