tests: fix worker thread initialization
[vpp.git] / src / plugins / quic / test / test_quic.py
1 #!/usr/bin/env python3
2 """ Vpp QUIC tests """
3
4 import unittest
5 import os
6 import subprocess
7 import signal
8 from framework import VppTestCase, VppTestRunner, running_extended_tests, \
9     Worker
10 from vpp_ip_route import VppIpTable, VppIpRoute, VppRoutePath
11
12
13 class QUICAppWorker(Worker):
14     """ QUIC Test Application Worker """
15     process = None
16
17     def __init__(self, build_dir, appname, executable_args, logger, role,
18                  testcase, env=None, *args, **kwargs):
19         if env is None:
20             env = {}
21         app = "%s/vpp/bin/%s" % (build_dir, appname)
22         self.args = [app] + executable_args
23         self.role = role
24         self.wait_for_gdb = 'wait-for-gdb'
25         self.testcase = testcase
26         super(QUICAppWorker, self).__init__(self.args, logger, env,
27                                             *args, **kwargs)
28
29     def run(self):
30         super(QUICAppWorker, self).run()
31
32     def teardown(self, logger, timeout):
33         if self.process is None:
34             return False
35         try:
36             logger.debug("Killing worker process (pid %d)" % self.process.pid)
37             os.killpg(os.getpgid(self.process.pid), signal.SIGKILL)
38             self.join(timeout)
39         except OSError as e:
40             logger.debug("Couldn't kill worker process")
41             return True
42         return False
43
44
45 class QUICTestCase(VppTestCase):
46     """ QUIC Test Case """
47
48     timeout = 20
49     pre_test_sleep = 0.3
50     post_test_sleep = 0.2
51
52     @classmethod
53     def setUpClass(cls):
54         cls.extra_vpp_plugin_config.append("plugin quic_plugin.so { enable }")
55         super(QUICTestCase, cls).setUpClass()
56
57     def setUp(self):
58         super(QUICTestCase, self).setUp()
59         var = "VPP_BUILD_DIR"
60         self.build_dir = os.getenv(var, None)
61         if self.build_dir is None:
62             raise Exception("Environment variable `%s' not set" % var)
63         self.vppDebug = 'vpp_debug' in self.build_dir
64         self.vapi.session_enable_disable(is_enabled=1)
65
66         self.create_loopback_interfaces(2)
67         self.uri = "quic://%s/1234" % self.loop0.local_ip4
68         table_id = 1
69         for i in self.lo_interfaces:
70             i.admin_up()
71
72             if table_id != 0:
73                 tbl = VppIpTable(self, table_id)
74                 tbl.add_vpp_config()
75
76             i.set_table_ip4(table_id)
77             i.config_ip4()
78             table_id += 1
79
80         # Configure namespaces
81         self.vapi.app_namespace_add_del(namespace_id=b"server",
82                                         sw_if_index=self.loop0.sw_if_index)
83         self.vapi.app_namespace_add_del(namespace_id=b"client",
84                                         sw_if_index=self.loop1.sw_if_index)
85
86         # Add inter-table routes
87         self.ip_t01 = VppIpRoute(self, self.loop1.local_ip4, 32,
88                                  [VppRoutePath("0.0.0.0",
89                                                0xffffffff,
90                                                nh_table_id=2)], table_id=1)
91         self.ip_t10 = VppIpRoute(self, self.loop0.local_ip4, 32,
92                                  [VppRoutePath("0.0.0.0",
93                                                0xffffffff,
94                                                nh_table_id=1)], table_id=2)
95         self.ip_t01.add_vpp_config()
96         self.ip_t10.add_vpp_config()
97         self.logger.debug(self.vapi.cli("show ip fib"))
98
99     def tearDown(self):
100         self.vapi.session_enable_disable(is_enabled=0)
101         # Delete inter-table routes
102         self.ip_t01.remove_vpp_config()
103         self.ip_t10.remove_vpp_config()
104
105         for i in self.lo_interfaces:
106             i.unconfig_ip4()
107             i.set_table_ip4(0)
108             i.admin_down()
109         super(QUICTestCase, self).tearDown()
110
111
112 class QUICEchoIntTestCase(QUICTestCase):
113     """QUIC Echo Internal Test Case"""
114     test_bytes = ' test-bytes'
115
116     def setUp(self):
117         super(QUICEchoIntTestCase, self).setUp()
118         self.client_args = 'uri {uri} fifo-size 64{testbytes} appns client' \
119             .format(uri=self.uri, testbytes=self.test_bytes)
120         self.server_args = "uri %s fifo-size 64 appns server" % self.uri
121
122     def server(self, *args):
123         error = self.vapi.cli(
124             "test echo server %s %s" %
125             (self.server_args, ' '.join(args)))
126         if error:
127             self.logger.critical(error)
128             self.assertNotIn("failed", error)
129
130     def client(self, *args):
131         error = self.vapi.cli(
132             "test echo client %s %s" %
133             (self.client_args, ' '.join(args)))
134         if error:
135             self.logger.critical(error)
136             self.assertNotIn("failed", error)
137
138
139 class QUICEchoIntTransferTestCase(QUICEchoIntTestCase):
140     """QUIC Echo Internal Transfer Test Case"""
141     def test_quic_int_transfer(self):
142         self.server()
143         self.client("no-output", "mbytes", "2")
144
145
146 class QUICEchoIntTransferBigTestCase(QUICEchoIntTestCase):
147     """QUIC Echo Internal Transfer Big Test Case"""
148     test_bytes = ''
149
150     @unittest.skipUnless(running_extended_tests, "part of extended tests")
151     def test_quic_int_transfer_big(self):
152         self.server()
153         self.client("no-output", "gbytes", "10")
154
155
156 class QUICEchoIntSerialTestCase(QUICEchoIntTestCase):
157     """QUIC Echo Internal Serial Transfer Test Case"""
158     def test_quic_serial_int_transfer(self):
159         self.server()
160         self.client("no-output", "mbytes", "2")
161         self.client("no-output", "mbytes", "2")
162         self.client("no-output", "mbytes", "2")
163         self.client("no-output", "mbytes", "2")
164         self.client("no-output", "mbytes", "2")
165
166
167 class QUICEchoIntSerialBigTestCase(QUICEchoIntTestCase):
168     """QUIC Echo Internal Serial Transfer Big Test Case"""
169
170     @unittest.skipUnless(running_extended_tests, "part of extended tests")
171     def test_quic_serial_int_transfer_big(self):
172         self.server()
173         self.client("no-output", "gbytes", "5")
174         self.client("no-output", "gbytes", "5")
175         self.client("no-output", "gbytes", "5")
176         self.client("no-output", "gbytes", "5")
177         self.client("no-output", "gbytes", "5")
178
179
180 class QUICEchoIntMStreamTestCase(QUICEchoIntTestCase):
181     """QUIC Echo Internal MultiStream Test Case"""
182     def test_quic_int_multistream_transfer(self):
183         self.server()
184         self.client("nclients", "10", "mbytes", "1", "no-output")
185
186
187 class QUICEchoIntMStreamBigTestCase(QUICEchoIntTestCase):
188     """QUIC Echo Internal MultiStream Big Test Case"""
189
190     @unittest.skipUnless(running_extended_tests, "part of extended tests")
191     def test_quic_int_multistream_transfer(self):
192         self.server()
193         self.client("nclients", "10", "gbytes", "5", "no-output")
194
195
196 class QUICEchoExtTestCase(QUICTestCase):
197     extra_vpp_punt_config = ["session", "{", "evt_qs_memfd_seg", "}"]
198     quic_setup = "default"
199     test_bytes = "test-bytes:assert"
200     app = "vpp_echo"
201
202     def setUp(self):
203         super(QUICEchoExtTestCase, self).setUp()
204         common_args = [
205             "uri",
206             self.uri,
207             "json",
208             self.test_bytes,
209             "socket-name", self.api_sock,
210             "quic-setup", self.quic_setup]
211         self.server_echo_test_args = common_args + \
212             ["server", "appns", "server"]  # use default fifo-size
213         self.client_echo_test_args = common_args + \
214             ["client", "appns", "client", "fifo-size", "4M"]
215         error = self.vapi.cli("quic set fifo-size 2M")
216         if error:
217             self.logger.critical(error)
218             self.assertNotIn("failed", error)
219
220     def server(self, *args):
221         _args = self.server_echo_test_args + list(args)
222         self.worker_server = QUICAppWorker(
223             self.build_dir,
224             self.app,
225             _args,
226             self.logger,
227             'server',
228             self)
229         self.worker_server.start()
230         self.sleep(self.pre_test_sleep)
231
232     def client(self, *args):
233         _args = self.client_echo_test_args + list(args)
234         self.worker_client = QUICAppWorker(
235             self.build_dir,
236             self.app,
237             _args,
238             self.logger,
239             'client',
240             self)
241         self.worker_client.start()
242         timeout = None if self.debug_all else self.timeout
243         self.worker_client.join(timeout)
244         self.worker_server.join(timeout)
245         self.sleep(self.post_test_sleep)
246
247     def validate_ext_test_results(self):
248         server_result = self.worker_server.result
249         client_result = self.worker_client.result
250         self.logger.info("Server worker result is `%s'" %
251                          server_result)
252         self.logger.info("Client worker result is `%s'" %
253                          client_result)
254         server_kill_error = False
255         if self.worker_server.result is None:
256             server_kill_error = self.worker_server.teardown(
257                 self.logger, self.timeout)
258         if self.worker_client.result is None:
259             self.worker_client.teardown(self.logger, self.timeout)
260         err_msg = "Wrong server worker return code (%s)" % server_result
261         self.assertEqual(server_result, 0, err_msg)
262         self.assertIsNotNone(
263             client_result,
264             "Timeout! Client worker did not finish in %ss" %
265             self.timeout)
266         err_msg = "Wrong client worker return code (%s)" % client_result
267         self.assertEqual(client_result, 0, err_msg)
268         self.assertFalse(server_kill_error, "Server kill errored")
269
270
271 class QUICEchoExtTransferTestCase(QUICEchoExtTestCase):
272     """QUIC Echo External Transfer Test Case"""
273     timeout = 60
274
275     def test_quic_ext_transfer(self):
276         self.server()
277         self.client()
278         self.validate_ext_test_results()
279
280
281 class QUICEchoExtTransferBigTestCase(QUICEchoExtTestCase):
282     """QUIC Echo External Transfer Big Test Case"""
283     test_bytes = ''
284     timeout = 60
285
286     @unittest.skipUnless(running_extended_tests, "part of extended tests")
287     def test_quic_ext_transfer_big(self):
288         self.server("TX=0", "RX=10Gb")
289         self.client("TX=10Gb", "RX=0")
290         self.validate_ext_test_results()
291
292
293 class QUICEchoExtQcloseRxTestCase(QUICEchoExtTestCase):
294     """QUIC Echo External Transfer Qclose Rx Test Case"""
295
296     @unittest.skipUnless(running_extended_tests, "part of extended tests")
297     def test_quic_ext_qclose_rx(self):
298         self.server("TX=0", "RX=10Mb", "qclose=Y", "sclose=N")
299         self.client("TX=10Mb", "RX=0", "qclose=W", "sclose=W")
300         self.validate_ext_test_results()
301
302
303 class QUICEchoExtQcloseTxTestCase(QUICEchoExtTestCase):
304     """QUIC Echo External Transfer Qclose Tx Test Case"""
305
306     @unittest.skipUnless(running_extended_tests, "part of extended tests")
307     def test_quic_ext_qclose_tx(self):
308         self.server("TX=0", "RX=10Mb", "qclose=W", "sclose=W",
309                     "rx-results-diff")
310         self.client("TX=10Mb", "RX=0", "qclose=Y", "sclose=N")
311         self.validate_ext_test_results()
312
313
314 class QUICEchoExtEarlyQcloseRxTestCase(QUICEchoExtTestCase):
315     """QUIC Echo External Transfer Early Qclose Rx Test Case"""
316
317     @unittest.skipUnless(running_extended_tests, "part of extended tests")
318     def test_quic_ext_early_qclose_rx(self):
319         self.server("TX=0", "RX=10Mb", "qclose=Y", "sclose=N")
320         self.client("TX=20Mb", "RX=0", "qclose=W", "sclose=W",
321                     "tx-results-diff")
322         self.validate_ext_test_results()
323
324
325 class QUICEchoExtEarlyQcloseTxTestCase(QUICEchoExtTestCase):
326     """QUIC Echo External Transfer Early Qclose Tx Test Case"""
327
328     @unittest.skipUnless(running_extended_tests, "part of extended tests")
329     def test_quic_ext_early_qclose_tx(self):
330         self.server("TX=0", "RX=20Mb", "qclose=W", "sclose=W",
331                     "rx-results-diff")
332         self.client("TX=10Mb", "RX=0", "qclose=Y", "sclose=N")
333         self.validate_ext_test_results()
334
335
336 class QUICEchoExtScloseRxTestCase(QUICEchoExtTestCase):
337     """QUIC Echo External Transfer Sclose Rx Test Case"""
338
339     @unittest.skipUnless(running_extended_tests, "part of extended tests")
340     def test_quic_ext_sclose_rx(self):
341         self.server("TX=0", "RX=10Mb", "qclose=N", "sclose=Y")
342         self.client("TX=10Mb", "RX=0", "qclose=W", "sclose=W")
343         self.validate_ext_test_results()
344
345
346 class QUICEchoExtScloseTxTestCase(QUICEchoExtTestCase):
347     """QUIC Echo External Transfer Sclose Tx Test Case"""
348
349     @unittest.skipUnless(running_extended_tests, "part of extended tests")
350     def test_quic_ext_sclose_tx(self):
351         self.server("TX=0", "RX=10Mb", "qclose=W", "sclose=W")
352         self.client("TX=10Mb", "RX=0", "qclose=Y", "sclose=Y")
353         self.validate_ext_test_results()
354
355
356 class QUICEchoExtEarlyScloseRxTestCase(QUICEchoExtTestCase):
357     """QUIC Echo External Transfer Early Sclose Rx Test Case"""
358
359     @unittest.skipUnless(running_extended_tests, "part of extended tests")
360     def test_quic_ext_early_sclose_rx(self):
361         self.server("TX=0", "RX=10Mb", "qclose=N", "sclose=Y")
362         self.client("TX=20Mb", "RX=0", "qclose=W", "sclose=W",
363                     "tx-results-diff")
364         self.validate_ext_test_results()
365
366
367 class QUICEchoExtEarlyScloseTxTestCase(QUICEchoExtTestCase):
368     """QUIC Echo External Transfer Early Sclose Tx Test Case"""
369
370     @unittest.skipUnless(running_extended_tests, "part of extended tests")
371     def test_quic_ext_early_sclose_tx(self):
372         self.server("TX=0", "RX=20Mb", "qclose=W", "sclose=W",
373                     "rx-results-diff")
374         self.client("TX=10Mb", "RX=0", "qclose=Y", "sclose=Y")
375         self.validate_ext_test_results()
376
377
378 class QUICEchoExtServerStreamTestCase(QUICEchoExtTestCase):
379     """QUIC Echo External Transfer Server Stream Test Case"""
380     quic_setup = "serverstream"
381
382     def test_quic_ext_transfer_server_stream(self):
383         self.server("TX=10Mb", "RX=0")
384         self.client("TX=0", "RX=10Mb")
385         self.validate_ext_test_results()
386
387
388 class QUICEchoExtBigServerStreamTestCase(QUICEchoExtTestCase):
389     """QUIC Echo External Transfer Big Server Stream Test Case"""
390     quic_setup = "serverstream"
391     test_bytes = ''
392
393     @unittest.skipUnless(running_extended_tests, "part of extended tests")
394     def test_quic_ext_transfer_big_server_stream(self):
395         self.server("TX=10Gb", "RX=0")
396         self.client("TX=0", "RX=10Gb")
397         self.validate_ext_test_results()
398
399
400 class QUICEchoExtServerStreamQcloseRxTestCase(QUICEchoExtTestCase):
401     """QUIC Echo External Transfer Server Stream Qclose Rx Test Case"""
402     quic_setup = "serverstream"
403
404     @unittest.skipUnless(running_extended_tests, "part of extended tests")
405     def test_quic_ext_server_stream_qclose_rx(self):
406         self.server("TX=10Mb", "RX=0", "qclose=W", "sclose=W")
407         self.client("TX=0", "RX=10Mb", "qclose=Y", "sclose=N")
408         self.validate_ext_test_results()
409
410
411 class QUICEchoExtServerStreamQcloseTxTestCase(QUICEchoExtTestCase):
412     """QUIC Echo External Transfer Server Stream Qclose Tx Test Case"""
413     quic_setup = "serverstream"
414
415     @unittest.skipUnless(running_extended_tests, "part of extended tests")
416     def test_quic_ext_server_stream_qclose_tx(self):
417         self.server("TX=10Mb", "RX=0", "qclose=Y", "sclose=N")
418         self.client("TX=0", "RX=10Mb", "qclose=W", "sclose=W",
419                     "rx-results-diff")
420         self.validate_ext_test_results()
421
422
423 class QUICEchoExtServerStreamEarlyQcloseRxTestCase(QUICEchoExtTestCase):
424     """QUIC Echo External Transfer Server Stream Early Qclose Rx Test Case"""
425     quic_setup = "serverstream"
426
427     @unittest.skipUnless(running_extended_tests, "part of extended tests")
428     def test_quic_ext_server_stream_early_qclose_rx(self):
429         self.server("TX=20Mb", "RX=0", "qclose=W", "sclose=W",
430                     "tx-results-diff")
431         self.client("TX=0", "RX=10Mb", "qclose=Y", "sclose=N")
432         self.validate_ext_test_results()
433
434
435 class QUICEchoExtServerStreamEarlyQcloseTxTestCase(QUICEchoExtTestCase):
436     """QUIC Echo External Transfer Server Stream Early Qclose Tx Test Case"""
437     quic_setup = "serverstream"
438
439     @unittest.skipUnless(running_extended_tests, "part of extended tests")
440     def test_quic_ext_server_stream_early_qclose_tx(self):
441         self.server("TX=10Mb", "RX=0", "qclose=Y", "sclose=N")
442         self.client("TX=0", "RX=20Mb", "qclose=W", "sclose=W",
443                     "rx-results-diff")
444         self.validate_ext_test_results()
445
446
447 class QUICEchoExtServerStreamScloseRxTestCase(QUICEchoExtTestCase):
448     """QUIC Echo External Transfer Server Stream Sclose Rx Test Case"""
449     quic_setup = "serverstream"
450
451     @unittest.skipUnless(running_extended_tests, "part of extended tests")
452     def test_quic_ext_server_stream_sclose_rx(self):
453         self.server("TX=10Mb", "RX=0", "qclose=W", "sclose=W")
454         self.client("TX=0", "RX=10Mb", "qclose=N", "sclose=Y")
455         self.validate_ext_test_results()
456
457
458 class QUICEchoExtServerStreamScloseTxTestCase(QUICEchoExtTestCase):
459     """QUIC Echo External Transfer Server Stream Sclose Tx Test Case"""
460     quic_setup = "serverstream"
461
462     @unittest.skipUnless(running_extended_tests, "part of extended tests")
463     def test_quic_ext_server_stream_sclose_tx(self):
464         self.server("TX=10Mb", "RX=0", "qclose=Y", "sclose=Y")
465         self.client("TX=0", "RX=10Mb", "qclose=W", "sclose=W")
466         self.validate_ext_test_results()
467
468
469 class QUICEchoExtServerStreamEarlyScloseRxTestCase(QUICEchoExtTestCase):
470     """QUIC Echo External Transfer Server Stream Early Sclose Rx Test Case"""
471     quic_setup = "serverstream"
472
473     @unittest.skipUnless(running_extended_tests, "part of extended tests")
474     def test_quic_ext_server_stream_early_sclose_rx(self):
475         self.server("TX=20Mb", "RX=0", "qclose=W", "sclose=W",
476                     "tx-results-diff")
477         self.client("TX=0", "RX=10Mb", "qclose=N", "sclose=Y")
478         self.validate_ext_test_results()
479
480
481 class QUICEchoExtServerStreamEarlyScloseTxTestCase(QUICEchoExtTestCase):
482     """QUIC Echo Ext Transfer Server Stream Early Sclose Tx Test Case"""
483     quic_setup = "serverstream"
484
485     @unittest.skipUnless(running_extended_tests, "part of extended tests")
486     def test_quic_ext_server_stream_early_sclose_tx(self):
487         self.server("TX=10Mb", "RX=0", "qclose=Y", "sclose=Y")
488         self.client("TX=0", "RX=20Mb", "qclose=W", "sclose=W",
489                     "rx-results-diff")
490         self.validate_ext_test_results()
491
492
493 class QUICEchoExtServerStreamWorkersTestCase(QUICEchoExtTestCase):
494     """QUIC Echo External Transfer Server Stream MultiWorker Test Case"""
495     quic_setup = "serverstream"
496
497     @unittest.skipUnless(running_extended_tests, "part of extended tests")
498     def test_quic_ext_transfer_server_stream_multi_workers(self):
499         self.server("nclients", "4", "quic-streams", "4", "TX=10Mb", "RX=0")
500         self.client("nclients", "4", "quic-streams", "4", "TX=0", "RX=10Mb")
501         self.validate_ext_test_results()
502
503
504 if __name__ == '__main__':
505     unittest.main(testRunner=VppTestRunner)