blob: 7e17e2a1fddbcfc3ef133f80433a1e7a30cfd13f [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
Andrew Yourtchenko8dc0d482021-01-29 13:17:19 +00007from framework import tag_fixme_vpp_workers
Paul Vinciguerra59954822019-03-11 05:04:12 -07008from framework import VppTestCase, 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
Andrew Yourtchenko8dc0d482021-01-29 13:17:19 +000013@tag_fixme_vpp_workers
Paul Vinciguerra59954822019-03-11 05:04:12 -070014class 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
Arthur de Kerhordb023802021-03-11 10:26:54 -080025 @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
Ole Troan233e4682019-05-16 15:01:34 +020031 def test_set_errors(self):
32 """Test set errors"""
33 self.assertEqual(self.statistics.set_errors(), {})
Ole Troane66443c2021-03-18 11:12:01 +010034 self.assertEqual(
35 self.statistics.get_counter('/err/ethernet-input/no error'), [0])
Ole Troan233e4682019-05-16 15:01:34 +020036
Paul Vinciguerra59954822019-03-11 05:04:12 -070037 def test_client_fd_leak(self):
38 """Test file descriptor count - VPP-1486"""
39
40 cls = self.__class__
41 p = psutil.Process()
42 initial_fds = p.num_fds()
43
44 for _ in range(100):
Klement Sekerae2636852021-03-16 12:52:12 +010045 stats = VPPStats(socketname=cls.get_stats_sock_path())
Paul Vinciguerra59954822019-03-11 05:04:12 -070046 stats.disconnect()
47
48 ending_fds = p.num_fds()
49 self.assertEqual(initial_fds, ending_fds,
50 "initial client side file descriptor count: %s "
51 "is not equal to "
52 "ending client side file descriptor count: %s" % (
53 initial_fds, ending_fds))
Steven Luongc79b32d2019-06-18 09:56:07 -070054
Arthur de Kerhordb023802021-03-11 10:26:54 -080055 def test_symlink_values(self):
56 """Test symlinks reported values"""
57 self.create_pg_interfaces(range(2))
58
59 for i in self.pg_interfaces:
60 i.admin_up()
61 i.config_ip4()
62 i.resolve_arp()
63
64 p = list()
65 for i in range(5):
66 packet = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
67 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4))
68 p.append(packet)
69
70 self.send_and_expect(self.pg0, p, self.pg1)
71
72 pg1_tx = self.statistics.get_counter('/interfaces/pg1/tx')
73 if_tx = self.statistics.get_counter('/if/tx')
74
75 self.assertEqual(pg1_tx[0]['bytes'],
76 if_tx[0][self.pg1.sw_if_index]['bytes'])
77 for i in self.pg_interfaces:
78 i.unconfig()
79 i.admin_down()
80
81 def test_symlink_add_del_interfaces(self):
82 """Test symlinks when adding and deleting interfaces"""
83 # We first create and delete interfaces
84 self.create_loopback_interfaces(1)
85 self.create_pg_interfaces(range(1))
86 self.loop0.remove_vpp_config()
87 self.create_pg_interfaces(range(2))
88
89 for i in self.pg_interfaces:
90 i.admin_up()
91 i.config_ip4()
92 i.resolve_arp()
93
94 p = list()
95 bytes_to_send = 0
96 for i in range(5):
97 packet = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
98 IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4))
99 bytes_to_send += len(packet)
100 p.append(packet)
101
102 tx_before_sending = self.statistics.get_counter('/interfaces/pg1/tx')
103 rx_before_sending = self.statistics.get_counter('/interfaces/pg0/rx')
104 self.send_and_expect(self.pg0, p, self.pg1)
105 tx = self.statistics.get_counter('/interfaces/pg1/tx')
106 rx = self.statistics.get_counter('/interfaces/pg0/rx')
107
108 # We wait for nodes symlinks to update (interfaces created/deleted).
109 # ... and packets to be sent
110 self.sleep(0.1)
111 vectors = self.statistics.get_counter('/nodes/pg1-tx/vectors')
112
113 self.assertEqual(tx[0]['bytes'] - tx_before_sending[0]['bytes'],
114 bytes_to_send)
115 self.assertEqual(tx[0]['packets'] - tx_before_sending[0]['packets'],
116 5)
117 self.assertEqual(rx[0]['bytes'] - rx_before_sending[0]['bytes'],
118 bytes_to_send)
119 self.assertEqual(rx[0]['packets'] - rx_before_sending[0]['packets'],
120 5)
121 self.assertEqual(vectors[0], rx[0]['packets'])
122
123 for i in self.pg_interfaces:
124 i.unconfig()
125 i.admin_down()
126
127 def test_index_consistency(self):
128 """Test index consistency despite changes in the stats"""
129 d = self.statistics.ls(['/if/names'])
130 self.create_loopback_interfaces(10)
131 for i in range(10):
132 try:
133 s = self.statistics.dump(d)
134 break
135 except:
136 pass
137 k, v = s.popitem()
138 self.assertEqual(len(v), 11)
139
140 for i in self.lo_interfaces:
141 i.remove_vpp_config()
142
Ole Troan92e30822019-06-16 12:33:51 +0200143 @unittest.skip("Manual only")
144 def test_mem_leak(self):
145 def loop():
146 print('Running loop')
147 for i in range(50):
148 rv = self.vapi.papi.tap_create_v2(id=i, use_random_mac=1)
149 self.assertEqual(rv.retval, 0)
150 rv = self.vapi.papi.tap_delete_v2(sw_if_index=rv.sw_if_index)
151 self.assertEqual(rv.retval, 0)
152
153 before = self.statistics.get_counter('/mem/statseg/used')
154 loop()
155 self.vapi.cli("memory-trace on stats-segment")
156 for j in range(100):
157 loop()
158 print(self.vapi.cli("show memory stats-segment verbose"))
Steven Luongc79b32d2019-06-18 09:56:07 -0700159 print('AFTER', before,
160 self.statistics.get_counter('/mem/statseg/used'))
161
Paul Vinciguerra59954822019-03-11 05:04:12 -0700162
163if __name__ == '__main__':
164 unittest.main(testRunner=VppTestRunner)