udp: fix csum computation when offload disabled
[vpp.git] / test / test_stats_client.py
1 #!/usr/bin/env python3
2
3 import unittest
4 import psutil
5 from vpp_papi.vpp_stats import VPPStats
6
7 from framework import VppTestCase
8 from asfframework import VppTestRunner
9 from scapy.layers.l2 import Ether
10 from scapy.layers.inet import IP
11
12
13 class 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
24     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
34     @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
40     def test_set_errors(self):
41         """Test set errors"""
42         self.assertEqual(self.statistics.set_errors(), {})
43         self.assertEqual(
44             self.statistics.get_counter("/err/ethernet-input/no error"),
45             [0] * (1 + self.vpp_worker_count),
46         )
47
48     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):
56             stats = VPPStats(socketname=cls.get_stats_sock_path())
57             stats.disconnect()
58
59         ending_fds = p.num_fds()
60         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         )
67
68     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):
79             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             )
82             p.append(packet)
83
84         self.send_and_expect(self.pg0, p, self.pg1)
85         pg1_tx = self.statistics.get_counter("/interfaces/pg1/tx")
86         if_tx = self.statistics.get_counter("/if/tx")
87
88         self.assertEqual(pg1_tx[0]["bytes"], if_tx[0][self.pg1.sw_if_index]["bytes"])
89
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):
106             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             )
109             bytes_to_send += len(packet)
110             p.append(packet)
111
112         tx_before_sending = self.statistics.get_counter("/interfaces/pg1/tx")
113         rx_before_sending = self.statistics.get_counter("/interfaces/pg0/rx")
114         self.send_and_expect(self.pg0, p, self.pg1)
115         tx = self.statistics.get_counter("/interfaces/pg1/tx")
116         rx = self.statistics.get_counter("/interfaces/pg0/rx")
117
118         # We wait for nodes symlinks to update (interfaces created/deleted).
119         self.virtual_sleep(1)
120         vectors = self.statistics.get_counter("/nodes/pg1-tx/vectors")
121
122         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)
135         self.assertEqual(vectors[0], rx[0]["packets"])
136
137     def test_index_consistency(self):
138         """Test index consistency despite changes in the stats"""
139         d = self.statistics.ls(["/if/names"])
140         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
153     @unittest.skip("Manual only")
154     def test_mem_leak(self):
155         def loop():
156             print("Running loop")
157             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
163         before = self.statistics.get_counter("/mem/statseg/used")
164         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"))
169         print("AFTER", before, self.statistics.get_counter("/mem/statseg/used"))
170
171
172 if __name__ == "__main__":
173     unittest.main(testRunner=VppTestRunner)