tests: replace pycodestyle with black
[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 tag_fixme_vpp_workers
8 from framework import VppTestCase, VppTestRunner
9 from scapy.layers.l2 import Ether
10 from scapy.layers.inet import IP
11
12
13 @tag_fixme_vpp_workers
14 class StatsClientTestCase(VppTestCase):
15     """Test Stats Client"""
16
17     @classmethod
18     def setUpClass(cls):
19         super(StatsClientTestCase, cls).setUpClass()
20
21     @classmethod
22     def tearDownClass(cls):
23         super(StatsClientTestCase, cls).tearDownClass()
24
25     @classmethod
26     def setUpConstants(cls):
27         cls.extra_vpp_statseg_config = "per-node-counters on"
28         cls.extra_vpp_statseg_config += "update-interval 0.05"
29         super(StatsClientTestCase, cls).setUpConstants()
30
31     def test_set_errors(self):
32         """Test set errors"""
33         self.assertEqual(self.statistics.set_errors(), {})
34         self.assertEqual(
35             self.statistics.get_counter("/err/ethernet-input/no error"), [0]
36         )
37
38     def test_client_fd_leak(self):
39         """Test file descriptor count - VPP-1486"""
40
41         cls = self.__class__
42         p = psutil.Process()
43         initial_fds = p.num_fds()
44
45         for _ in range(100):
46             stats = VPPStats(socketname=cls.get_stats_sock_path())
47             stats.disconnect()
48
49         ending_fds = p.num_fds()
50         self.assertEqual(
51             initial_fds,
52             ending_fds,
53             "initial client side file descriptor count: %s "
54             "is not equal to "
55             "ending client side file descriptor count: %s" % (initial_fds, ending_fds),
56         )
57
58     def test_symlink_values(self):
59         """Test symlinks reported values"""
60         self.create_pg_interfaces(range(2))
61
62         for i in self.pg_interfaces:
63             i.admin_up()
64             i.config_ip4()
65             i.resolve_arp()
66
67         p = list()
68         for i in range(5):
69             packet = Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) / IP(
70                 src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4
71             )
72             p.append(packet)
73
74         self.send_and_expect(self.pg0, p, self.pg1)
75         pg1_tx = self.statistics.get_counter("/interfaces/pg1/tx")
76         if_tx = self.statistics.get_counter("/if/tx")
77
78         self.assertEqual(pg1_tx[0]["bytes"], if_tx[0][self.pg1.sw_if_index]["bytes"])
79         for i in self.pg_interfaces:
80             i.unconfig()
81             i.admin_down()
82
83     def test_symlink_add_del_interfaces(self):
84         """Test symlinks when adding and deleting interfaces"""
85         # We first create and delete interfaces
86         self.create_loopback_interfaces(1)
87         self.create_pg_interfaces(range(1))
88         self.loop0.remove_vpp_config()
89         self.create_pg_interfaces(range(2))
90
91         for i in self.pg_interfaces:
92             i.admin_up()
93             i.config_ip4()
94             i.resolve_arp()
95
96         p = list()
97         bytes_to_send = 0
98         for i in range(5):
99             packet = Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) / IP(
100                 src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4
101             )
102             bytes_to_send += len(packet)
103             p.append(packet)
104
105         tx_before_sending = self.statistics.get_counter("/interfaces/pg1/tx")
106         rx_before_sending = self.statistics.get_counter("/interfaces/pg0/rx")
107         self.send_and_expect(self.pg0, p, self.pg1)
108         tx = self.statistics.get_counter("/interfaces/pg1/tx")
109         rx = self.statistics.get_counter("/interfaces/pg0/rx")
110
111         # We wait for nodes symlinks to update (interfaces created/deleted).
112         # ... and packets to be sent
113         self.sleep(0.1)
114         vectors = self.statistics.get_counter("/nodes/pg1-tx/vectors")
115
116         self.assertEqual(tx[0]["bytes"] - tx_before_sending[0]["bytes"], bytes_to_send)
117         self.assertEqual(tx[0]["packets"] - tx_before_sending[0]["packets"], 5)
118         self.assertEqual(rx[0]["bytes"] - rx_before_sending[0]["bytes"], bytes_to_send)
119         self.assertEqual(rx[0]["packets"] - rx_before_sending[0]["packets"], 5)
120         self.assertEqual(vectors[0], rx[0]["packets"])
121
122         for i in self.pg_interfaces:
123             i.unconfig()
124             i.admin_down()
125
126     def test_index_consistency(self):
127         """Test index consistency despite changes in the stats"""
128         d = self.statistics.ls(["/if/names"])
129         self.create_loopback_interfaces(10)
130         for i in range(10):
131             try:
132                 s = self.statistics.dump(d)
133                 break
134             except:
135                 pass
136         k, v = s.popitem()
137         self.assertEqual(len(v), 11)
138
139         for i in self.lo_interfaces:
140             i.remove_vpp_config()
141
142     @unittest.skip("Manual only")
143     def test_mem_leak(self):
144         def loop():
145             print("Running loop")
146             for i in range(50):
147                 rv = self.vapi.papi.tap_create_v2(id=i, use_random_mac=1)
148                 self.assertEqual(rv.retval, 0)
149                 rv = self.vapi.papi.tap_delete_v2(sw_if_index=rv.sw_if_index)
150                 self.assertEqual(rv.retval, 0)
151
152         before = self.statistics.get_counter("/mem/statseg/used")
153         loop()
154         self.vapi.cli("memory-trace on stats-segment")
155         for j in range(100):
156             loop()
157         print(self.vapi.cli("show memory stats-segment verbose"))
158         print("AFTER", before, self.statistics.get_counter("/mem/statseg/used"))
159
160
161 if __name__ == "__main__":
162     unittest.main(testRunner=VppTestRunner)