tests: make tests less make dependent
[vpp.git] / test / test_memif.py
1 import socket
2 import unittest
3
4 from scapy.layers.l2 import Ether
5 from scapy.layers.inet import IP, ICMP
6
7 from framework import VppTestCase, VppTestRunner
8 from framework import tag_run_solo
9 from remote_test import RemoteClass, RemoteVppTestCase
10 from vpp_memif import remove_all_memif_vpp_config, \
11     VppSocketFilename, VppMemif
12 from vpp_ip_route import VppIpRoute, VppRoutePath
13 from vpp_papi import VppEnum
14
15
16 @tag_run_solo
17 class TestMemif(VppTestCase):
18     """ Memif Test Case """
19     remote_class = RemoteVppTestCase
20
21     @classmethod
22     def get_cpus_required(cls):
23         return (super().get_cpus_required() +
24                 cls.remote_class.get_cpus_required())
25
26     @classmethod
27     def assign_cpus(cls, cpus):
28         remote_cpus = cpus[:cls.remote_class.get_cpus_required()]
29         my_cpus = cpus[cls.remote_class.get_cpus_required():]
30         cls.remote_class.assign_cpus(remote_cpus)
31         super().assign_cpus(my_cpus)
32
33     @classmethod
34     def setUpClass(cls):
35         # fork new process before client connects to VPP
36         cls.remote_test = RemoteClass(cls.remote_class)
37         cls.remote_test.start_remote()
38         cls.remote_test.set_request_timeout(10)
39         super(TestMemif, cls).setUpClass()
40         cls.remote_test.setUpClass(cls.tempdir)
41         cls.create_pg_interfaces(range(1))
42         for pg in cls.pg_interfaces:
43             pg.config_ip4()
44             pg.admin_up()
45             pg.resolve_arp()
46
47     @classmethod
48     def tearDownClass(cls):
49         cls.remote_test.tearDownClass()
50         cls.remote_test.quit_remote()
51         for pg in cls.pg_interfaces:
52             pg.unconfig_ip4()
53             pg.set_table_ip4(0)
54             pg.admin_down()
55         super(TestMemif, cls).tearDownClass()
56
57     def tearDown(self):
58         remove_all_memif_vpp_config(self)
59         remove_all_memif_vpp_config(self.remote_test)
60         super(TestMemif, self).tearDown()
61
62     def _check_socket_filename(self, dump, socket_id, filename):
63         for d in dump:
64             if (d.socket_id == socket_id) and (
65                     d.socket_filename == filename):
66                 return True
67         return False
68
69     def test_memif_socket_filename_add_del(self):
70         """ Memif socket filename add/del """
71
72         # dump default socket filename
73         dump = self.vapi.memif_socket_filename_dump()
74         self.assertTrue(
75             self._check_socket_filename(
76                 dump, 0, "%s/memif.sock" % self.tempdir))
77
78         memif_sockets = []
79         # existing path
80         memif_sockets.append(
81             VppSocketFilename(
82                 self, 1, "%s/memif1.sock" % self.tempdir))
83         # default path (test tempdir)
84         memif_sockets.append(
85             VppSocketFilename(
86                 self,
87                 2,
88                 "memif2.sock",
89                 add_default_folder=True))
90         # create new folder in default folder
91         memif_sockets.append(
92             VppSocketFilename(
93                 self,
94                 3,
95                 "sock/memif3.sock",
96                 add_default_folder=True))
97
98         for sock in memif_sockets:
99             sock.add_vpp_config()
100             dump = sock.query_vpp_config()
101             self.assertTrue(
102                 self._check_socket_filename(
103                     dump,
104                     sock.socket_id,
105                     sock.socket_filename))
106
107         for sock in memif_sockets:
108             sock.remove_vpp_config()
109
110         dump = self.vapi.memif_socket_filename_dump()
111         self.assertTrue(
112             self._check_socket_filename(
113                 dump, 0, "%s/memif.sock" % self.tempdir))
114
115     def _create_delete_test_one_interface(self, memif):
116         memif.add_vpp_config()
117
118         dump = memif.query_vpp_config()
119
120         self.assertTrue(dump)
121         self.assertEqual(dump.sw_if_index, memif.sw_if_index)
122         self.assertEqual(dump.role, memif.role)
123         self.assertEqual(dump.mode, memif.mode)
124         if (memif.socket_id is not None):
125             self.assertEqual(dump.socket_id, memif.socket_id)
126
127         memif.remove_vpp_config()
128
129         dump = memif.query_vpp_config()
130
131         self.assertFalse(dump)
132
133     def _connect_test_one_interface(self, memif):
134         self.assertTrue(memif.wait_for_link_up(5))
135         dump = memif.query_vpp_config()
136
137         if memif.role == VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE:
138             self.assertEqual(dump.ring_size, memif.ring_size)
139             self.assertEqual(dump.buffer_size, memif.buffer_size)
140         else:
141             self.assertEqual(dump.ring_size, 1)
142             self.assertEqual(dump.buffer_size, 0)
143
144     def _connect_test_interface_pair(self, memif0, memif1):
145         memif0.add_vpp_config()
146         memif1.add_vpp_config()
147
148         memif0.admin_up()
149         memif1.admin_up()
150
151         self._connect_test_one_interface(memif0)
152         self._connect_test_one_interface(memif1)
153
154         memif0.remove_vpp_config()
155         memif1.remove_vpp_config()
156
157     def test_memif_create_delete(self):
158         """ Memif create/delete interface """
159
160         memif = VppMemif(
161             self,
162             VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE,
163             VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET)
164         self._create_delete_test_one_interface(memif)
165         memif.role = VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_MASTER
166         self._create_delete_test_one_interface(memif)
167
168     def test_memif_create_custom_socket(self):
169         """ Memif create with non-default socket filename """
170
171         memif_sockets = []
172         # existing path
173         memif_sockets.append(
174             VppSocketFilename(
175                 self, 1, "%s/memif1.sock" % self.tempdir))
176         # default path (test tempdir)
177         memif_sockets.append(
178             VppSocketFilename(
179                 self,
180                 2,
181                 "memif2.sock",
182                 add_default_folder=True))
183         # create new folder in default folder
184         memif_sockets.append(
185             VppSocketFilename(
186                 self,
187                 3,
188                 "sock/memif3.sock",
189                 add_default_folder=True))
190
191         memif = VppMemif(
192             self,
193             VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE,
194             VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET)
195
196         for sock in memif_sockets:
197             sock.add_vpp_config()
198             memif.socket_id = sock.socket_id
199             memif.role = VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE
200             self._create_delete_test_one_interface(memif)
201             memif.role = VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_MASTER
202             self._create_delete_test_one_interface(memif)
203
204     def test_memif_connect(self):
205         """ Memif connect """
206         memif = VppMemif(
207             self,
208             VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE,
209             VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET,
210             ring_size=1024,
211             buffer_size=2048,
212             secret="abc")
213
214         remote_socket = VppSocketFilename(self.remote_test, 1,
215                                           "%s/memif.sock" % self.tempdir)
216         remote_socket.add_vpp_config()
217
218         remote_memif = VppMemif(
219             self.remote_test,
220             VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_MASTER,
221             VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET,
222             socket_id=1,
223             ring_size=1024,
224             buffer_size=2048,
225             secret="abc")
226
227         self._connect_test_interface_pair(memif, remote_memif)
228
229         memif.role = VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_MASTER
230         remote_memif.role = VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE
231
232         self._connect_test_interface_pair(memif, remote_memif)
233
234     def _create_icmp(self, pg, memif, num):
235         pkts = []
236         for i in range(num):
237             pkt = (Ether(dst=pg.local_mac, src=pg.remote_mac) /
238                    IP(src=pg.remote_ip4,
239                       dst=str(memif.ip_prefix.network_address)) /
240                    ICMP(id=memif.if_id, type='echo-request', seq=i))
241             pkts.append(pkt)
242         return pkts
243
244     def _verify_icmp(self, pg, memif, rx, seq):
245         ip = rx[IP]
246         self.assertEqual(ip.src, str(memif.ip_prefix.network_address))
247         self.assertEqual(ip.dst, pg.remote_ip4)
248         self.assertEqual(ip.proto, 1)
249         icmp = rx[ICMP]
250         self.assertEqual(icmp.type, 0)  # echo-reply
251         self.assertEqual(icmp.id, memif.if_id)
252         self.assertEqual(icmp.seq, seq)
253
254     def test_memif_ping(self):
255         """ Memif ping """
256
257         memif = VppMemif(
258             self,
259             VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE,
260             VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET)
261
262         remote_socket = VppSocketFilename(self.remote_test, 1,
263                                           "%s/memif.sock" % self.tempdir)
264         remote_socket.add_vpp_config()
265
266         remote_memif = VppMemif(
267             self.remote_test,
268             VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_MASTER,
269             VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET,
270             socket_id=1)
271
272         memif.add_vpp_config()
273         memif.config_ip4()
274         memif.admin_up()
275
276         remote_memif.add_vpp_config()
277         remote_memif.config_ip4()
278         remote_memif.admin_up()
279
280         self.assertTrue(memif.wait_for_link_up(5))
281         self.assertTrue(remote_memif.wait_for_link_up(5))
282
283         # add routing to remote vpp
284         route = VppIpRoute(self.remote_test, self.pg0._local_ip4_subnet, 24,
285                            [VppRoutePath(memif.ip_prefix.network_address,
286                                          0xffffffff)],
287                            register=False)
288
289         route.add_vpp_config()
290
291         # create ICMP echo-request from local pg to remote memif
292         packet_num = 10
293         pkts = self._create_icmp(self.pg0, remote_memif, packet_num)
294
295         self.pg0.add_stream(pkts)
296         self.pg_enable_capture(self.pg_interfaces)
297         self.pg_start()
298         capture = self.pg0.get_capture(packet_num, timeout=2)
299         seq = 0
300         for c in capture:
301             self._verify_icmp(self.pg0, remote_memif, c, seq)
302             seq += 1
303
304         route.remove_vpp_config()
305
306     def test_memif_admin_up_down_up(self):
307         """ Memif admin up/down/up """
308         memif = VppMemif(
309             self,
310             VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_SLAVE,
311             VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET,
312             ring_size=1024,
313             buffer_size=2048,
314             secret="abc")
315
316         remote_socket = VppSocketFilename(self.remote_test, 1,
317                                           "%s/memif.sock" % self.tempdir)
318         remote_socket.add_vpp_config()
319
320         remote_memif = VppMemif(
321             self.remote_test,
322             VppEnum.vl_api_memif_role_t.MEMIF_ROLE_API_MASTER,
323             VppEnum.vl_api_memif_mode_t.MEMIF_MODE_API_ETHERNET,
324             socket_id=1,
325             ring_size=1024,
326             buffer_size=2048,
327             secret="abc")
328
329         memif.add_vpp_config()
330         remote_memif.add_vpp_config()
331
332         memif.admin_up()
333         remote_memif.admin_up()
334         memif.admin_down()
335         remote_memif.admin_down()
336         memif.admin_up()
337         remote_memif.admin_up()
338
339         self._connect_test_one_interface(memif)
340         self._connect_test_one_interface(remote_memif)
341
342         memif.remove_vpp_config()
343         remote_memif.remove_vpp_config()
344         remote_socket.remove_vpp_config()
345
346
347 if __name__ == '__main__':
348     unittest.main(testRunner=VppTestRunner)