virtio: Add RX queue full statisitics
[vpp.git] / test / test_vlib.py
1 #!/usr/bin/env python3
2
3 import unittest
4 import pexpect
5 import time
6 import signal
7 from config import config
8 from framework import VppTestCase
9 from asfframework import VppTestRunner
10 from scapy.layers.inet import IP, ICMP
11 from scapy.layers.l2 import Ether
12 from scapy.packet import Raw
13
14
15 @unittest.skipUnless(config.gcov, "part of code coverage tests")
16 class TestVlib(VppTestCase):
17     """Vlib Unit Test Cases"""
18
19     vpp_worker_count = 1
20
21     @classmethod
22     def setUpClass(cls):
23         super(TestVlib, cls).setUpClass()
24
25     @classmethod
26     def tearDownClass(cls):
27         super(TestVlib, cls).tearDownClass()
28
29     def setUp(self):
30         super(TestVlib, self).setUp()
31
32     def tearDown(self):
33         super(TestVlib, self).tearDown()
34
35     def test_vlib_main_unittest(self):
36         """Vlib main.c Code Coverage Test"""
37
38         cmds = [
39             "loopback create",
40             "packet-generator new {\n"
41             " name vlib\n"
42             " limit 15\n"
43             " size 128-128\n"
44             " interface loop0\n"
45             " node ethernet-input\n"
46             " data {\n"
47             "   IP6: 00:d0:2d:5e:86:85 -> 00:0d:ea:d0:00:00\n"
48             "   ICMP: db00::1 -> db00::2\n"
49             "   incrementing 30\n"
50             "   }\n"
51             "}\n",
52             "event-logger trace dispatch",
53             "event-logger stop",
54             "event-logger clear",
55             "event-logger resize 102400",
56             "event-logger restart",
57             "pcap dispatch trace on max 100 buffer-trace pg-input 15",
58             "pa en",
59             "show event-log 100 all",
60             "event-log save",
61             "event-log save foo",
62             "pcap dispatch trace",
63             "pcap dispatch trace status",
64             "pcap dispatch trace off",
65             "show vlib frame-allocation",
66         ]
67
68         for cmd in cmds:
69             r = self.vapi.cli_return_response(cmd)
70             if r.retval != 0:
71                 if hasattr(r, "reply"):
72                     self.logger.info(cmd + " FAIL reply " + r.reply)
73                 else:
74                     self.logger.info(cmd + " FAIL retval " + str(r.retval))
75
76     def test_vlib_node_cli_unittest(self):
77         """Vlib node_cli.c Code Coverage Test"""
78
79         cmds = [
80             "loopback create",
81             "packet-generator new {\n"
82             " name vlib\n"
83             " limit 15\n"
84             " size 128-128\n"
85             " interface loop0\n"
86             " node ethernet-input\n"
87             " data {\n"
88             "   IP6: 00:d0:2d:5e:86:85 -> 00:0d:ea:d0:00:00\n"
89             "   ICMP: db00::1 -> db00::2\n"
90             "   incrementing 30\n"
91             "   }\n"
92             "}\n",
93             "show vlib graph",
94             "show vlib graph ethernet-input",
95             "show vlib graphviz",
96             "show vlib graphviz graphviz.dot",
97             "pa en",
98             "show runtime ethernet-input",
99             "show runtime brief verbose max summary",
100             "clear runtime",
101             "show node index 1",
102             "show node ethernet-input",
103             "show node pg-input",
104             "set node function",
105             "set node function no-such-node",
106             "set node function cdp-input default",
107             "set node function ethernet-input default",
108             "set node function ethernet-input bozo",
109             "set node function ethernet-input",
110             "show \t",
111         ]
112
113         for cmd in cmds:
114             r = self.vapi.cli_return_response(cmd)
115             if r.retval != 0:
116                 if hasattr(r, "reply"):
117                     self.logger.info(cmd + " FAIL reply " + r.reply)
118                 else:
119                     self.logger.info(cmd + " FAIL retval " + str(r.retval))
120
121     def test_vlib_buffer_c_unittest(self):
122         """Vlib buffer.c Code Coverage Test"""
123
124         cmds = [
125             "loopback create",
126             "packet-generator new {\n"
127             " name vlib\n"
128             " limit 15\n"
129             " size 128-128\n"
130             " interface loop0\n"
131             " node ethernet-input\n"
132             " data {\n"
133             "   IP6: 00:d0:2d:5e:86:85 -> 00:0d:ea:d0:00:00\n"
134             "   ICMP: db00::1 -> db00::2\n"
135             "   incrementing 30\n"
136             "   }\n"
137             "}\n",
138             "event-logger trace",
139             "event-logger trace enable",
140             "event-logger trace api cli barrier",
141             "pa en",
142             "show interface bogus",
143             "event-logger trace disable api cli barrier",
144             "event-logger trace circuit-node ethernet-input",
145             "event-logger trace circuit-node ethernet-input disable",
146             "clear interfaces",
147             "test vlib",
148             "test vlib2",
149             "show memory api-segment stats-segment main-heap verbose",
150             "leak-check { show memory }",
151             "show cpu",
152             "memory-trace main-heap",
153             "memory-trace main-heap api-segment stats-segment",
154             "leak-check { show version }",
155             "show version ?",
156             "comment { show version }",
157             "uncomment { show version }",
158             "show memory main-heap",
159             "show memory bogus",
160             "choices",
161             "test heap-validate",
162             "memory-trace main-heap disable",
163             "show buffers",
164             "show eve",
165             "show help",
166             "show ip ",
167         ]
168
169         for cmd in cmds:
170             r = self.vapi.cli_return_response(cmd)
171             if r.retval != 0:
172                 if hasattr(r, "reply"):
173                     self.logger.info(cmd + " FAIL reply " + r.reply)
174                 else:
175                     self.logger.info(cmd + " FAIL retval " + str(r.retval))
176
177     def test_vlib_format_unittest(self):
178         """Vlib format.c Code Coverage Test"""
179
180         cmds = [
181             "loopback create",
182             "classify filter pcap mask l2 proto match l2 proto 0x86dd",
183             "classify filter pcap del",
184             "test format-vlib",
185         ]
186
187         for cmd in cmds:
188             r = self.vapi.cli_return_response(cmd)
189             if r.retval != 0:
190                 if hasattr(r, "reply"):
191                     self.logger.info(cmd + " FAIL reply " + r.reply)
192                 else:
193                     self.logger.info(cmd + " FAIL retval " + str(r.retval))
194
195     def test_vlib_main_unittest(self):
196         """Private Binary API Segment Test (takes 70 seconds)"""
197
198         vat_path = config.vpp + "_api_test"
199         vat = pexpect.spawn(vat_path, ["socket-name", self.get_api_sock_path()])
200         vat.expect("vat# ", timeout=10)
201         vat.sendline("sock_init_shm")
202         vat.expect("vat# ", timeout=10)
203         vat.sendline("sh api cli")
204         vat.kill(signal.SIGKILL)
205         vat.wait()
206         self.logger.info("vat terminated, 70 second wait for the Reaper")
207         time.sleep(70)
208         self.logger.info("Reaper should be complete...")
209
210     def test_pool(self):
211         """Fixed-size Pool Test"""
212
213         cmds = [
214             "test pool",
215         ]
216
217         for cmd in cmds:
218             r = self.vapi.cli_return_response(cmd)
219             if r.retval != 0:
220                 if hasattr(r, "reply"):
221                     self.logger.info(cmd + " FAIL reply " + r.reply)
222                 else:
223                     self.logger.info(cmd + " FAIL retval " + str(r.retval))
224
225
226 class TestVlibFrameLeak(VppTestCase):
227     """Vlib Frame Leak Test Cases"""
228
229     vpp_worker_count = 1
230
231     @classmethod
232     def setUpClass(cls):
233         super(TestVlibFrameLeak, cls).setUpClass()
234
235     @classmethod
236     def tearDownClass(cls):
237         super(TestVlibFrameLeak, cls).tearDownClass()
238
239     def setUp(self):
240         super(TestVlibFrameLeak, self).setUp()
241         # create 1 pg interface
242         self.create_pg_interfaces(range(1))
243
244         for i in self.pg_interfaces:
245             i.admin_up()
246             i.config_ip4()
247             i.resolve_arp()
248
249     def tearDown(self):
250         super(TestVlibFrameLeak, self).tearDown()
251         for i in self.pg_interfaces:
252             i.unconfig_ip4()
253             i.admin_down()
254
255     def test_vlib_mw_refork_frame_leak(self):
256         """Vlib worker thread refork leak test case"""
257         icmp_id = 0xB
258         icmp_seq = 5
259         icmp_load = b"\x0a" * 18
260         pkt = (
261             Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac)
262             / IP(src=self.pg0.remote_ip4, dst=self.pg0.local_ip4)
263             / ICMP(id=icmp_id, seq=icmp_seq)
264             / Raw(load=icmp_load)
265         )
266
267         # Send a packet
268         self.pg0.add_stream(pkt)
269         self.pg_enable_capture(self.pg_interfaces)
270         self.pg_start()
271
272         rx = self.pg0.get_capture(1)
273
274         self.assertEquals(len(rx), 1)
275         rx = rx[0]
276         ether = rx[Ether]
277         ipv4 = rx[IP]
278
279         self.assertEqual(ether.src, self.pg0.local_mac)
280         self.assertEqual(ether.dst, self.pg0.remote_mac)
281
282         self.assertEqual(ipv4.src, self.pg0.local_ip4)
283         self.assertEqual(ipv4.dst, self.pg0.remote_ip4)
284
285         # Save allocated frame count
286         frame_allocated = {}
287         for fs in self.vapi.cli("show vlib frame-allocation").splitlines()[1:]:
288             spl = fs.split()
289             thread = int(spl[0])
290             size = int(spl[1])
291             alloc = int(spl[2])
292             key = (thread, size)
293             frame_allocated[key] = alloc
294
295         # cause reforks
296         _ = self.create_loopback_interfaces(1)
297
298         # send the same packet
299         self.pg0.add_stream(pkt)
300         self.pg_enable_capture(self.pg_interfaces)
301         self.pg_start()
302
303         rx = self.pg0.get_capture(1)
304
305         self.assertEquals(len(rx), 1)
306         rx = rx[0]
307         ether = rx[Ether]
308         ipv4 = rx[IP]
309
310         self.assertEqual(ether.src, self.pg0.local_mac)
311         self.assertEqual(ether.dst, self.pg0.remote_mac)
312
313         self.assertEqual(ipv4.src, self.pg0.local_ip4)
314         self.assertEqual(ipv4.dst, self.pg0.remote_ip4)
315
316         # Check that no frame were leaked during refork
317         for fs in self.vapi.cli("show vlib frame-allocation").splitlines()[1:]:
318             spl = fs.split()
319             thread = int(spl[0])
320             size = int(spl[1])
321             alloc = int(spl[2])
322             key = (thread, size)
323             self.assertEqual(frame_allocated[key], alloc)
324
325
326 if __name__ == "__main__":
327     unittest.main(testRunner=VppTestRunner)