8 from config import config
9 from framework import tag_fixme_vpp_workers
10 from framework import VppTestCase, VppTestRunner, Worker
11 from vpp_ip_route import VppIpTable, VppIpRoute, VppRoutePath
14 class QUICAppWorker(Worker):
15 """ QUIC Test Application Worker """
18 def __init__(self, appname, executable_args, logger, role,
19 testcase, env=None, *args, **kwargs):
22 app = f"{config.vpp_build_dir}/vpp/bin/{appname}"
23 self.args = [app] + executable_args
25 self.wait_for_gdb = 'wait-for-gdb'
26 self.testcase = testcase
27 super(QUICAppWorker, self).__init__(self.args, logger, env,
31 super(QUICAppWorker, self).run()
33 def teardown(self, logger, timeout):
34 if self.process is None:
37 logger.debug("Killing worker process (pid %d)" % self.process.pid)
38 os.killpg(os.getpgid(self.process.pid), signal.SIGKILL)
41 logger.debug("Couldn't kill worker process")
46 class QUICTestCase(VppTestCase):
47 """ QUIC Test Case """
55 cls.extra_vpp_plugin_config.append("plugin quic_plugin.so { enable }")
56 super(QUICTestCase, cls).setUpClass()
59 super(QUICTestCase, self).setUp()
60 self.vppDebug = 'vpp_debug' in config.vpp_build_dir
62 self.create_loopback_interfaces(2)
63 self.uri = "quic://%s/1234" % self.loop0.local_ip4
65 for i in self.lo_interfaces:
69 tbl = VppIpTable(self, table_id)
72 i.set_table_ip4(table_id)
76 # Configure namespaces
77 self.vapi.app_namespace_add_del(namespace_id="server",
78 sw_if_index=self.loop0.sw_if_index)
79 self.vapi.app_namespace_add_del(namespace_id="client",
80 sw_if_index=self.loop1.sw_if_index)
82 # Add inter-table routes
83 self.ip_t01 = VppIpRoute(self, self.loop1.local_ip4, 32,
84 [VppRoutePath("0.0.0.0",
86 nh_table_id=2)], table_id=1)
87 self.ip_t10 = VppIpRoute(self, self.loop0.local_ip4, 32,
88 [VppRoutePath("0.0.0.0",
90 nh_table_id=1)], table_id=2)
91 self.ip_t01.add_vpp_config()
92 self.ip_t10.add_vpp_config()
93 self.logger.debug(self.vapi.cli("show ip fib"))
96 # Delete inter-table routes
97 self.ip_t01.remove_vpp_config()
98 self.ip_t10.remove_vpp_config()
100 for i in self.lo_interfaces:
104 super(QUICTestCase, self).tearDown()
107 class QUICEchoIntTestCase(QUICTestCase):
108 """QUIC Echo Internal Test Case"""
109 test_bytes = ' test-bytes'
110 extra_vpp_punt_config = ["session", "{", "enable", "poll-main", "}"]
113 super(QUICEchoIntTestCase, self).setUp()
114 self.client_args = 'uri {uri} fifo-size 64{testbytes} appns client' \
115 .format(uri=self.uri, testbytes=self.test_bytes)
116 self.server_args = "uri %s fifo-size 64 appns server" % self.uri
119 super(QUICEchoIntTestCase, self).tearDown()
121 def server(self, *args):
122 error = self.vapi.cli(
123 "test echo server %s %s" %
124 (self.server_args, ' '.join(args)))
126 self.logger.critical(error)
127 self.assertNotIn("failed", error)
129 def client(self, *args):
130 error = self.vapi.cli(
131 "test echo client %s %s" %
132 (self.client_args, ' '.join(args)))
134 self.logger.critical(error)
135 self.assertNotIn("failed", error)
138 @tag_fixme_vpp_workers
139 class QUICEchoIntTransferTestCase(QUICEchoIntTestCase):
140 """QUIC Echo Internal Transfer Test Case"""
141 def test_quic_int_transfer(self):
142 """QUIC internal transfer"""
144 self.client("no-output", "mbytes", "2")
147 @tag_fixme_vpp_workers
148 class QUICEchoIntSerialTestCase(QUICEchoIntTestCase):
149 """QUIC Echo Internal Serial Transfer Test Case"""
150 def test_quic_serial_int_transfer(self):
151 """QUIC serial internal transfer"""
153 self.client("no-output", "mbytes", "2")
154 self.client("no-output", "mbytes", "2")
155 self.client("no-output", "mbytes", "2")
156 self.client("no-output", "mbytes", "2")
157 self.client("no-output", "mbytes", "2")
160 @tag_fixme_vpp_workers
161 class QUICEchoIntMStreamTestCase(QUICEchoIntTestCase):
162 """QUIC Echo Internal MultiStream Test Case"""
163 def test_quic_int_multistream_transfer(self):
164 """QUIC internal multi-stream transfer"""
166 self.client("nclients", "10", "mbytes", "1", "no-output")
169 class QUICEchoExtTestCase(QUICTestCase):
170 quic_setup = "default"
171 test_bytes = "test-bytes:assert"
177 server_fifo_size = "1M"
178 client_fifo_size = "4M"
179 extra_vpp_punt_config = ["session", "{",
180 "enable", "poll-main", "evt_qs_memfd_seg",
181 "evt_qs_seg_size", "64M",
182 "event-queue-length", f"{evt_q_len}",
183 "preallocated-sessions", "1024",
184 "v4-session-table-buckets", "20000",
185 "v4-session-table-memory", "64M",
186 "v4-halfopen-table-buckets", "20000",
187 "v4-halfopen-table-memory", "64M",
188 "local-endpoints-table-buckets", "250000",
189 "local-endpoints-table-memory", "512M",
193 super(QUICEchoExtTestCase, self).setUp()
198 "socket-name", self.get_api_sock_path(),
199 "quic-setup", self.quic_setup,
201 "mq-size", f"{self.evt_q_len}"
203 self.server_echo_test_args = common_args + \
204 ["server", "appns", "server", "fifo-size",
205 f"{self.server_fifo_size}"]
206 self.client_echo_test_args = common_args + \
207 ["client", "appns", "client", "fifo-size",
208 f"{self.client_fifo_size}"]
209 error = self.vapi.cli("quic set fifo-size 2M")
211 self.logger.critical(error)
212 self.assertNotIn("failed", error)
214 def server(self, *args):
215 _args = self.server_echo_test_args + list(args)
216 self.worker_server = QUICAppWorker(
222 self.worker_server.start()
223 self.sleep(self.pre_test_sleep)
225 def client(self, *args):
226 _args = self.client_echo_test_args + list(args)
227 self.worker_client = QUICAppWorker(
233 self.worker_client.start()
234 timeout = None if self.debug_all else self.timeout
235 self.worker_client.join(timeout)
236 if self.worker_client.is_alive():
237 error = f"Client failed to complete in {timeout} seconds!"
238 self.logger.critical(error)
240 self.worker_server.join(timeout)
241 if self.worker_server.is_alive():
242 error = f"Server failed to complete in {timeout} seconds!"
243 self.logger.critical(error)
244 self.sleep(self.post_test_sleep)
246 def validate_ext_test_results(self):
247 server_result = self.worker_server.result
248 client_result = self.worker_client.result
249 self.logger.info("Server worker result is `%s'" %
251 self.logger.info("Client worker result is `%s'" %
253 server_kill_error = False
254 if self.worker_server.result is None:
255 server_kill_error = self.worker_server.teardown(
256 self.logger, self.timeout)
257 if self.worker_client.result is None:
258 self.worker_client.teardown(self.logger, self.timeout)
259 err_msg = "Wrong server worker return code (%s)" % server_result
260 self.assertEqual(server_result, 0, err_msg)
261 self.assertIsNotNone(
263 "Timeout! Client worker did not finish in %ss" %
265 err_msg = "Wrong client worker return code (%s)" % client_result
266 self.assertEqual(client_result, 0, err_msg)
267 self.assertFalse(server_kill_error, "Server kill errored")
270 class QUICEchoExtTransferTestCase(QUICEchoExtTestCase):
271 """QUIC Echo External Transfer Test Case"""
274 def test_quic_ext_transfer(self):
275 """QUIC external transfer"""
278 self.validate_ext_test_results()
281 class QUICEchoExtTransferBigTestCase(QUICEchoExtTestCase):
282 """QUIC Echo External Transfer Big Test Case"""
283 server_fifo_size = '4M'
284 client_fifo_size = '4M'
288 @unittest.skipUnless(config.extended, "part of extended tests")
289 def test_quic_ext_transfer_big(self):
290 """QUIC external transfer, big stream"""
291 self.server("TX=0", "RX=2G")
292 self.client("TX=2G", "RX=0")
293 self.validate_ext_test_results()
296 class QUICEchoExtQcloseRxTestCase(QUICEchoExtTestCase):
297 """QUIC Echo External Transfer Qclose Rx Test Case"""
299 @unittest.skipUnless(config.extended, "part of extended tests")
300 @unittest.skip("testcase under development")
301 def test_quic_ext_qclose_rx(self):
302 """QUIC external transfer, rx close"""
303 self.server("TX=0", "RX=10M", "qclose=Y", "sclose=N")
304 self.client("TX=10M", "RX=0", "qclose=W", "sclose=W")
305 self.validate_ext_test_results()
308 class QUICEchoExtQcloseTxTestCase(QUICEchoExtTestCase):
309 """QUIC Echo External Transfer Qclose Tx Test Case"""
311 @unittest.skipUnless(config.extended, "part of extended tests")
312 @unittest.skip("testcase under development")
313 def test_quic_ext_qclose_tx(self):
314 """QUIC external transfer, tx close"""
315 self.server("TX=0", "RX=10M", "qclose=W", "sclose=W",
317 self.client("TX=10M", "RX=0", "qclose=Y", "sclose=N")
318 self.validate_ext_test_results()
321 class QUICEchoExtEarlyQcloseRxTestCase(QUICEchoExtTestCase):
322 """QUIC Echo External Transfer Early Qclose Rx Test Case"""
324 @unittest.skipUnless(config.extended, "part of extended tests")
325 @unittest.skip("testcase under development")
326 def test_quic_ext_early_qclose_rx(self):
327 """QUIC external transfer, early rx close"""
328 self.server("TX=0", "RX=10M", "qclose=Y", "sclose=N")
329 self.client("TX=20M", "RX=0", "qclose=W", "sclose=W",
331 self.validate_ext_test_results()
334 class QUICEchoExtEarlyQcloseTxTestCase(QUICEchoExtTestCase):
335 """QUIC Echo External Transfer Early Qclose Tx Test Case"""
337 @unittest.skipUnless(config.extended, "part of extended tests")
338 @unittest.skip("testcase under development")
339 def test_quic_ext_early_qclose_tx(self):
340 """QUIC external transfer, early tx close"""
341 self.server("TX=0", "RX=20M", "qclose=W", "sclose=W",
343 self.client("TX=10M", "RX=0", "qclose=Y", "sclose=N")
344 self.validate_ext_test_results()
347 class QUICEchoExtScloseRxTestCase(QUICEchoExtTestCase):
348 """QUIC Echo External Transfer Sclose Rx Test Case"""
350 @unittest.skipUnless(config.extended, "part of extended tests")
351 @unittest.skip("testcase under development")
352 def test_quic_ext_sclose_rx(self):
353 """QUIC external transfer, rx stream close"""
354 self.server("TX=0", "RX=10M", "qclose=N", "sclose=Y")
355 self.client("TX=10M", "RX=0", "qclose=W", "sclose=W")
356 self.validate_ext_test_results()
359 class QUICEchoExtScloseTxTestCase(QUICEchoExtTestCase):
360 """QUIC Echo External Transfer Sclose Tx Test Case"""
362 @unittest.skipUnless(config.extended, "part of extended tests")
363 @unittest.skip("testcase under development")
364 def test_quic_ext_sclose_tx(self):
365 """QUIC external transfer, tx stream close"""
366 self.server("TX=0", "RX=10M", "qclose=W", "sclose=W")
367 self.client("TX=10M", "RX=0", "qclose=Y", "sclose=Y")
368 self.validate_ext_test_results()
371 class QUICEchoExtEarlyScloseRxTestCase(QUICEchoExtTestCase):
372 """QUIC Echo External Transfer Early Sclose Rx Test Case"""
374 @unittest.skipUnless(config.extended, "part of extended tests")
375 @unittest.skip("testcase under development")
376 def test_quic_ext_early_sclose_rx(self):
377 """QUIC external transfer, early rx stream close"""
378 self.server("TX=0", "RX=10M", "qclose=N", "sclose=Y")
379 self.client("TX=20M", "RX=0", "qclose=W", "sclose=W",
381 self.validate_ext_test_results()
384 class QUICEchoExtEarlyScloseTxTestCase(QUICEchoExtTestCase):
385 """QUIC Echo External Transfer Early Sclose Tx Test Case"""
387 @unittest.skipUnless(config.extended, "part of extended tests")
388 @unittest.skip("testcase under development")
389 def test_quic_ext_early_sclose_tx(self):
390 """QUIC external transfer, early tx stream close"""
391 self.server("TX=0", "RX=20M", "qclose=W", "sclose=W",
393 self.client("TX=10M", "RX=0", "qclose=Y", "sclose=Y")
394 self.validate_ext_test_results()
397 class QUICEchoExtServerStreamTestCase(QUICEchoExtTestCase):
398 """QUIC Echo External Transfer Server Stream Test Case"""
399 quic_setup = "serverstream"
402 def test_quic_ext_transfer_server_stream(self):
403 """QUIC external server transfer"""
404 self.server("TX=10M", "RX=0")
405 self.client("TX=0", "RX=10M")
406 self.validate_ext_test_results()
409 class QUICEchoExtServerStreamBigTestCase(QUICEchoExtTestCase):
410 """QUIC Echo External Transfer Server Stream Big Test Case"""
411 quic_setup = "serverstream"
412 server_fifo_size = '4M'
413 client_fifo_size = '4M'
417 @unittest.skipUnless(config.extended, "part of extended tests")
418 def test_quic_ext_transfer_server_stream_big(self):
419 """QUIC external server transfer, big stream"""
420 self.server("TX=2G", "RX=0")
421 self.client("TX=0", "RX=2G")
422 self.validate_ext_test_results()
425 class QUICEchoExtServerStreamQcloseRxTestCase(QUICEchoExtTestCase):
426 """QUIC Echo External Transfer Server Stream Qclose Rx Test Case"""
427 quic_setup = "serverstream"
429 @unittest.skipUnless(config.extended, "part of extended tests")
430 @unittest.skip("testcase under development")
431 def test_quic_ext_server_stream_qclose_rx(self):
432 """QUIC external server transfer, rx close"""
433 self.server("TX=10M", "RX=0", "qclose=W", "sclose=W")
434 self.client("TX=0", "RX=10M", "qclose=Y", "sclose=N")
435 self.validate_ext_test_results()
438 class QUICEchoExtServerStreamQcloseTxTestCase(QUICEchoExtTestCase):
439 """QUIC Echo External Transfer Server Stream Qclose Tx Test Case"""
440 quic_setup = "serverstream"
442 @unittest.skipUnless(config.extended, "part of extended tests")
443 @unittest.skip("testcase under development")
444 def test_quic_ext_server_stream_qclose_tx(self):
445 """QUIC external server transfer, tx close"""
446 self.server("TX=10M", "RX=0", "qclose=Y", "sclose=N")
447 self.client("TX=0", "RX=10M", "qclose=W", "sclose=W",
449 self.validate_ext_test_results()
452 class QUICEchoExtServerStreamEarlyQcloseRxTestCase(QUICEchoExtTestCase):
453 """QUIC Echo External Transfer Server Stream Early Qclose Rx Test Case"""
454 quic_setup = "serverstream"
456 @unittest.skipUnless(config.extended, "part of extended tests")
457 @unittest.skip("testcase under development")
458 def test_quic_ext_server_stream_early_qclose_rx(self):
459 """QUIC external server transfer, early rx close"""
460 self.server("TX=20M", "RX=0", "qclose=W", "sclose=W",
462 self.client("TX=0", "RX=10M", "qclose=Y", "sclose=N")
463 self.validate_ext_test_results()
466 class QUICEchoExtServerStreamEarlyQcloseTxTestCase(QUICEchoExtTestCase):
467 """QUIC Echo External Transfer Server Stream Early Qclose Tx Test Case"""
468 quic_setup = "serverstream"
470 @unittest.skipUnless(config.extended, "part of extended tests")
471 @unittest.skip("testcase under development")
472 def test_quic_ext_server_stream_early_qclose_tx(self):
473 """QUIC external server transfer, early tx close"""
474 self.server("TX=10M", "RX=0", "qclose=Y", "sclose=N")
475 self.client("TX=0", "RX=20M", "qclose=W", "sclose=W",
477 self.validate_ext_test_results()
480 class QUICEchoExtServerStreamScloseRxTestCase(QUICEchoExtTestCase):
481 """QUIC Echo External Transfer Server Stream Sclose Rx Test Case"""
482 quic_setup = "serverstream"
484 @unittest.skipUnless(config.extended, "part of extended tests")
485 @unittest.skip("testcase under development")
486 def test_quic_ext_server_stream_sclose_rx(self):
487 """QUIC external server transfer, rx stream close"""
488 self.server("TX=10M", "RX=0", "qclose=W", "sclose=W")
489 self.client("TX=0", "RX=10M", "qclose=N", "sclose=Y")
490 self.validate_ext_test_results()
493 class QUICEchoExtServerStreamScloseTxTestCase(QUICEchoExtTestCase):
494 """QUIC Echo External Transfer Server Stream Sclose Tx Test Case"""
495 quic_setup = "serverstream"
497 @unittest.skipUnless(config.extended, "part of extended tests")
498 @unittest.skip("testcase under development")
499 def test_quic_ext_server_stream_sclose_tx(self):
500 """QUIC external server transfer, tx stream close"""
501 self.server("TX=10M", "RX=0", "qclose=Y", "sclose=Y")
502 self.client("TX=0", "RX=10M", "qclose=W", "sclose=W")
503 self.validate_ext_test_results()
506 class QUICEchoExtServerStreamEarlyScloseRxTestCase(QUICEchoExtTestCase):
507 """QUIC Echo External Transfer Server Stream Early Sclose Rx Test Case"""
508 quic_setup = "serverstream"
510 @unittest.skipUnless(config.extended, "part of extended tests")
511 @unittest.skip("testcase under development")
512 def test_quic_ext_server_stream_early_sclose_rx(self):
513 """QUIC external server transfer, early rx stream close"""
514 self.server("TX=20M", "RX=0", "qclose=W", "sclose=W",
516 self.client("TX=0", "RX=10M", "qclose=N", "sclose=Y")
517 self.validate_ext_test_results()
520 class QUICEchoExtServerStreamEarlyScloseTxTestCase(QUICEchoExtTestCase):
521 """QUIC Echo Ext Transfer Server Stream Early Sclose Tx Test Case"""
522 quic_setup = "serverstream"
524 @unittest.skipUnless(config.extended, "part of extended tests")
525 @unittest.skip("testcase under development")
526 def test_quic_ext_server_stream_early_sclose_tx(self):
527 """QUIC external server transfer, early tx stream close"""
528 self.server("TX=10M", "RX=0", "qclose=Y", "sclose=Y")
529 self.client("TX=0", "RX=20M", "qclose=W", "sclose=W",
531 self.validate_ext_test_results()
534 class QUICEchoExtServerStreamWorkersTestCase(QUICEchoExtTestCase):
535 """QUIC Echo External Transfer Server Stream MultiWorker Test Case"""
536 quic_setup = "serverstream"
538 @unittest.skipUnless(config.extended, "part of extended tests")
539 @unittest.skip("testcase under development")
540 def test_quic_ext_transfer_server_stream_multi_workers(self):
541 """QUIC external server transfer, multi-worker"""
542 self.server("nclients", "4", "quic-streams", "4", "TX=10M", "RX=0")
543 self.client("nclients", "4", "quic-streams", "4", "TX=0", "RX=10M")
544 self.validate_ext_test_results()
547 if __name__ == '__main__':
548 unittest.main(testRunner=VppTestRunner)