blob: 0bd89292beb58da61a79dbcc5e86d2ef0f852864 [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
7from framework import VppTestCase, VppTestRunner
Arthur de Kerhordb023802021-03-11 10:26:54 -08008from scapy.layers.l2 import Ether
9from scapy.layers.inet import IP
Paul Vinciguerra59954822019-03-11 05:04:12 -070010
11
12class StatsClientTestCase(VppTestCase):
13 """Test Stats Client"""
14
15 @classmethod
16 def setUpClass(cls):
17 super(StatsClientTestCase, cls).setUpClass()
18
19 @classmethod
20 def tearDownClass(cls):
21 super(StatsClientTestCase, cls).tearDownClass()
22
Benoît Ganne79cb1d52023-02-24 16:13:29 +010023 def setUp(self):
24 super(StatsClientTestCase, self).setUp()
25 self.create_pg_interfaces([])
26
27 def tearDown(self):
28 super(StatsClientTestCase, self).tearDown()
29 for i in self.pg_interfaces:
30 i.unconfig()
31 i.admin_down()
32
Arthur de Kerhordb023802021-03-11 10:26:54 -080033 @classmethod
34 def setUpConstants(cls):
35 cls.extra_vpp_statseg_config = "per-node-counters on"
36 cls.extra_vpp_statseg_config += "update-interval 0.05"
37 super(StatsClientTestCase, cls).setUpConstants()
38
Ole Troan233e4682019-05-16 15:01:34 +020039 def test_set_errors(self):
40 """Test set errors"""
41 self.assertEqual(self.statistics.set_errors(), {})
Ole Troane66443c2021-03-18 11:12:01 +010042 self.assertEqual(
Benoît Ganne79cb1d52023-02-24 16:13:29 +010043 self.statistics.get_counter("/err/ethernet-input/no error"),
44 [0] * (1 + self.vpp_worker_count),
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020045 )
Ole Troan233e4682019-05-16 15:01:34 +020046
Paul Vinciguerra59954822019-03-11 05:04:12 -070047 def test_client_fd_leak(self):
48 """Test file descriptor count - VPP-1486"""
49
50 cls = self.__class__
51 p = psutil.Process()
52 initial_fds = p.num_fds()
53
54 for _ in range(100):
Klement Sekerae2636852021-03-16 12:52:12 +010055 stats = VPPStats(socketname=cls.get_stats_sock_path())
Paul Vinciguerra59954822019-03-11 05:04:12 -070056 stats.disconnect()
57
58 ending_fds = p.num_fds()
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020059 self.assertEqual(
60 initial_fds,
61 ending_fds,
62 "initial client side file descriptor count: %s "
63 "is not equal to "
64 "ending client side file descriptor count: %s" % (initial_fds, ending_fds),
65 )
Steven Luongc79b32d2019-06-18 09:56:07 -070066
Arthur de Kerhordb023802021-03-11 10:26:54 -080067 def test_symlink_values(self):
68 """Test symlinks reported values"""
69 self.create_pg_interfaces(range(2))
70
71 for i in self.pg_interfaces:
72 i.admin_up()
73 i.config_ip4()
74 i.resolve_arp()
75
76 p = list()
77 for i in range(5):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020078 packet = Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) / IP(
79 src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4
80 )
Arthur de Kerhordb023802021-03-11 10:26:54 -080081 p.append(packet)
82
83 self.send_and_expect(self.pg0, p, self.pg1)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020084 pg1_tx = self.statistics.get_counter("/interfaces/pg1/tx")
85 if_tx = self.statistics.get_counter("/if/tx")
Arthur de Kerhordb023802021-03-11 10:26:54 -080086
Klement Sekerad9b0c6f2022-04-26 19:02:15 +020087 self.assertEqual(pg1_tx[0]["bytes"], if_tx[0][self.pg1.sw_if_index]["bytes"])
Arthur de Kerhordb023802021-03-11 10:26:54 -080088
89 def test_symlink_add_del_interfaces(self):
90 """Test symlinks when adding and deleting interfaces"""
91 # We first create and delete interfaces
92 self.create_loopback_interfaces(1)
93 self.create_pg_interfaces(range(1))
94 self.loop0.remove_vpp_config()
95 self.create_pg_interfaces(range(2))
96
97 for i in self.pg_interfaces:
98 i.admin_up()
99 i.config_ip4()
100 i.resolve_arp()
101
102 p = list()
103 bytes_to_send = 0
104 for i in range(5):
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200105 packet = Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) / IP(
106 src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4
107 )
Arthur de Kerhordb023802021-03-11 10:26:54 -0800108 bytes_to_send += len(packet)
109 p.append(packet)
110
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200111 tx_before_sending = self.statistics.get_counter("/interfaces/pg1/tx")
112 rx_before_sending = self.statistics.get_counter("/interfaces/pg0/rx")
Arthur de Kerhordb023802021-03-11 10:26:54 -0800113 self.send_and_expect(self.pg0, p, self.pg1)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200114 tx = self.statistics.get_counter("/interfaces/pg1/tx")
115 rx = self.statistics.get_counter("/interfaces/pg0/rx")
Arthur de Kerhordb023802021-03-11 10:26:54 -0800116
117 # We wait for nodes symlinks to update (interfaces created/deleted).
Benoît Ganne79cb1d52023-02-24 16:13:29 +0100118 self.virtual_sleep(1)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200119 vectors = self.statistics.get_counter("/nodes/pg1-tx/vectors")
Arthur de Kerhordb023802021-03-11 10:26:54 -0800120
Benoît Ganne79cb1d52023-02-24 16:13:29 +0100121 rx_bytes = 0
122 rx_packets = 0
123 tx_bytes = 0
124 tx_packets = 0
125 for i in range(1 + self.vpp_worker_count):
126 rx_bytes += rx[i]["bytes"] - rx_before_sending[i]["bytes"]
127 rx_packets += rx[i]["packets"] - rx_before_sending[i]["packets"]
128 tx_bytes += tx[i]["bytes"] - tx_before_sending[i]["bytes"]
129 tx_packets += tx[i]["packets"] - tx_before_sending[i]["packets"]
130 self.assertEqual(tx_bytes, bytes_to_send)
131 self.assertEqual(tx_packets, 5)
132 self.assertEqual(rx_bytes, bytes_to_send)
133 self.assertEqual(rx_packets, 5)
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200134 self.assertEqual(vectors[0], rx[0]["packets"])
Arthur de Kerhordb023802021-03-11 10:26:54 -0800135
Arthur de Kerhordb023802021-03-11 10:26:54 -0800136 def test_index_consistency(self):
137 """Test index consistency despite changes in the stats"""
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200138 d = self.statistics.ls(["/if/names"])
Arthur de Kerhordb023802021-03-11 10:26:54 -0800139 self.create_loopback_interfaces(10)
140 for i in range(10):
141 try:
142 s = self.statistics.dump(d)
143 break
144 except:
145 pass
146 k, v = s.popitem()
147 self.assertEqual(len(v), 11)
148
149 for i in self.lo_interfaces:
150 i.remove_vpp_config()
151
Ole Troan92e30822019-06-16 12:33:51 +0200152 @unittest.skip("Manual only")
153 def test_mem_leak(self):
154 def loop():
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200155 print("Running loop")
Ole Troan92e30822019-06-16 12:33:51 +0200156 for i in range(50):
157 rv = self.vapi.papi.tap_create_v2(id=i, use_random_mac=1)
158 self.assertEqual(rv.retval, 0)
159 rv = self.vapi.papi.tap_delete_v2(sw_if_index=rv.sw_if_index)
160 self.assertEqual(rv.retval, 0)
161
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200162 before = self.statistics.get_counter("/mem/statseg/used")
Ole Troan92e30822019-06-16 12:33:51 +0200163 loop()
164 self.vapi.cli("memory-trace on stats-segment")
165 for j in range(100):
166 loop()
167 print(self.vapi.cli("show memory stats-segment verbose"))
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200168 print("AFTER", before, self.statistics.get_counter("/mem/statseg/used"))
Steven Luongc79b32d2019-06-18 09:56:07 -0700169
Paul Vinciguerra59954822019-03-11 05:04:12 -0700170
Klement Sekerad9b0c6f2022-04-26 19:02:15 +0200171if __name__ == "__main__":
Paul Vinciguerra59954822019-03-11 05:04:12 -0700172 unittest.main(testRunner=VppTestRunner)