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"""
32 app = f"{config.vpp_build_dir}/vpp/bin/{appname}"
33 self.args = [app] + executable_args
35 self.wait_for_gdb = "wait-for-gdb"
36 self.testcase = testcase
37 super(QUICAppWorker, self).__init__(self.args, logger, env, *args, **kwargs)
40 super(QUICAppWorker, self).run()
42 def teardown(self, logger, timeout):
43 if self.process is None:
46 logger.debug(f"Killing worker process (pid {self.process.pid})")
47 os.killpg(os.getpgid(self.process.pid), signal.SIGKILL)
50 logger.debug("Couldn't kill worker process")
55 @unittest.skipIf("quic" in config.excluded_plugins, "Exclude QUIC plugin tests")
56 class QUICTestCase(VppTestCase):
62 server_appns = "server"
63 server_appns_secret = None
64 client_appns = "client"
65 client_appns_secret = None
69 cls.extra_vpp_plugin_config.append("plugin quic_plugin.so { enable }")
70 super(QUICTestCase, cls).setUpClass()
73 super(QUICTestCase, self).setUp()
74 self.vppDebug = "vpp_debug" in config.vpp_build_dir
76 self.create_loopback_interfaces(2)
77 self.uri = f"quic://{self.loop0.local_ip4}/1234"
79 for i in self.lo_interfaces:
83 tbl = VppIpTable(self, table_id)
86 i.set_table_ip4(table_id)
90 # Configure namespaces
91 self.vapi.app_namespace_add_del_v4(
92 namespace_id=self.server_appns,
93 secret=self.server_appns_secret,
94 sw_if_index=self.loop0.sw_if_index,
96 self.vapi.app_namespace_add_del_v4(
97 namespace_id=self.client_appns,
98 secret=self.client_appns_secret,
99 sw_if_index=self.loop1.sw_if_index,
102 # Add inter-table routes
103 self.ip_t01 = VppIpRoute(
105 self.loop1.local_ip4,
107 [VppRoutePath("0.0.0.0", 0xFFFFFFFF, nh_table_id=2)],
110 self.ip_t10 = VppIpRoute(
112 self.loop0.local_ip4,
114 [VppRoutePath("0.0.0.0", 0xFFFFFFFF, nh_table_id=1)],
117 self.ip_t01.add_vpp_config()
118 self.ip_t10.add_vpp_config()
119 self.logger.debug(self.vapi.cli("show ip fib"))
122 # Delete inter-table routes
123 self.ip_t01.remove_vpp_config()
124 self.ip_t10.remove_vpp_config()
126 for i in self.lo_interfaces:
130 super(QUICTestCase, self).tearDown()
133 class QUICEchoIntTestCase(QUICTestCase):
134 """QUIC Echo Internal Test Case"""
136 test_bytes = " test-bytes"
137 extra_vpp_config = ["session", "{", "enable", "poll-main", "}"]
140 super(QUICEchoIntTestCase, self).setUp()
142 f"uri {self.uri} fifo-size 64{self.test_bytes} appns {self.client_appns} "
144 self.server_args = f"uri {self.uri} fifo-size 64 appns {self.server_appns} "
147 super(QUICEchoIntTestCase, self).tearDown()
149 def server(self, *args):
150 _args = self.server_args + " ".join(args)
151 error = self.vapi.cli(f"test echo server {_args}")
153 self.logger.critical(error)
154 self.assertNotIn("failed", error)
156 def client(self, *args):
157 _args = self.client_args + " ".join(args)
158 error = self.vapi.cli(f"test echo client {_args}")
160 self.logger.critical(error)
161 self.assertNotIn("failed", error)
164 @tag_fixme_vpp_workers
165 class QUICEchoIntTransferTestCase(QUICEchoIntTestCase):
166 """QUIC Echo Internal Transfer Test Case"""
168 def test_quic_int_transfer(self):
169 """QUIC internal transfer"""
171 self.client("no-output", "mbytes", "2")
174 @tag_fixme_vpp_workers
175 class QUICEchoIntSerialTestCase(QUICEchoIntTestCase):
176 """QUIC Echo Internal Serial Transfer Test Case"""
178 def test_quic_serial_int_transfer(self):
179 """QUIC serial internal transfer"""
181 self.client("no-output", "mbytes", "2")
182 self.client("no-output", "mbytes", "2")
183 self.client("no-output", "mbytes", "2")
184 self.client("no-output", "mbytes", "2")
185 self.client("no-output", "mbytes", "2")
188 @tag_fixme_vpp_workers
189 class QUICEchoIntMStreamTestCase(QUICEchoIntTestCase):
190 """QUIC Echo Internal MultiStream Test Case"""
192 def test_quic_int_multistream_transfer(self):
193 """QUIC internal multi-stream transfer"""
195 self.client("nclients", "10", "mbytes", "1", "no-output")
198 class QUICEchoExtTestCase(QUICTestCase):
199 quic_setup = "default"
200 test_bytes = "test-bytes:assert"
206 server_fifo_size = "1M"
207 client_fifo_size = "4M"
213 "use-app-socket-api",
214 "wrk-mqs-segment-size",
216 "event-queue-length",
218 "preallocated-sessions",
220 "v4-session-table-buckets",
222 "v4-session-table-memory",
224 "v4-halfopen-table-buckets",
226 "v4-halfopen-table-memory",
228 "local-endpoints-table-buckets",
230 "local-endpoints-table-memory",
236 self.server_appns_secret = 1234
237 self.client_appns_secret = 5678
238 super(QUICEchoExtTestCase, self).setUp()
250 "use-app-socket-api",
252 self.server_echo_test_args = common_args + [
255 f"{self.server_appns}",
257 f"{self.server_fifo_size}",
259 f"{self.tempdir}/app_ns_sockets/{self.server_appns}",
261 self.client_echo_test_args = common_args + [
264 f"{self.client_appns}",
266 f"{self.client_fifo_size}",
268 f"{self.tempdir}/app_ns_sockets/{self.client_appns}",
270 error = self.vapi.cli("quic set fifo-size 2M")
272 self.logger.critical(error)
273 self.assertNotIn("failed", error)
275 def server(self, *args):
276 _args = self.server_echo_test_args + list(args)
277 self.worker_server = QUICAppWorker(
278 self.app, _args, self.logger, self.server_appns, self
280 self.worker_server.start()
281 self.sleep(self.pre_test_sleep)
283 def client(self, *args):
284 _args = self.client_echo_test_args + list(args)
285 self.worker_client = QUICAppWorker(
286 self.app, _args, self.logger, self.client_appns, self
288 self.worker_client.start()
289 timeout = None if self.debug_all else self.timeout
290 self.worker_client.join(timeout)
291 if self.worker_client.is_alive():
292 error = f"Client failed to complete in {timeout} seconds!"
293 self.logger.critical(error)
295 self.worker_server.join(timeout)
296 if self.worker_server.is_alive():
297 error = f"Server failed to complete in {timeout} seconds!"
298 self.logger.critical(error)
299 self.sleep(self.post_test_sleep)
301 def validate_ext_test_results(self):
302 server_result = self.worker_server.result
303 self.logger.debug(self.vapi.cli(f"show session verbose 2"))
304 client_result = self.worker_client.result
305 self.logger.info(f"Server worker result is `{server_result}'")
306 self.logger.info(f"Client worker result is `{client_result}'")
307 server_kill_error = False
308 if self.worker_server.result is None:
309 server_kill_error = self.worker_server.teardown(self.logger, self.timeout)
310 if self.worker_client.result is None:
311 self.worker_client.teardown(self.logger, self.timeout)
312 err_msg = f"Wrong server worker return code ({server_result})"
313 self.assertEqual(server_result, 0, err_msg)
314 self.assertIsNotNone(
315 client_result, f"Timeout! Client worker did not finish in {self.timeout}s"
317 err_msg = f"Wrong client worker return code ({client_result})"
318 self.assertEqual(client_result, 0, err_msg)
319 self.assertFalse(server_kill_error, "Server kill errored")
322 class QUICEchoExtTransferTestCase(QUICEchoExtTestCase):
323 """QUIC Echo External Transfer Test Case"""
327 def test_quic_ext_transfer(self):
328 """QUIC external transfer"""
331 self.validate_ext_test_results()
334 class QUICEchoExtTransferBigTestCase(QUICEchoExtTestCase):
335 """QUIC Echo External Transfer Big Test Case"""
337 server_fifo_size = "4M"
338 client_fifo_size = "4M"
342 @unittest.skipUnless(config.extended, "part of extended tests")
343 def test_quic_ext_transfer_big(self):
344 """QUIC external transfer, big stream"""
345 self.server("TX=0", "RX=2G")
346 self.client("TX=2G", "RX=0")
347 self.validate_ext_test_results()
350 class QUICEchoExtQcloseRxTestCase(QUICEchoExtTestCase):
351 """QUIC Echo External Transfer Qclose Rx Test Case"""
353 @unittest.skipUnless(config.extended, "part of extended tests")
354 @unittest.skip("testcase under development")
355 def test_quic_ext_qclose_rx(self):
356 """QUIC external transfer, rx close"""
357 self.server("TX=0", "RX=10M", "qclose=Y", "sclose=N")
358 self.client("TX=10M", "RX=0", "qclose=W", "sclose=W")
359 self.validate_ext_test_results()
362 class QUICEchoExtQcloseTxTestCase(QUICEchoExtTestCase):
363 """QUIC Echo External Transfer Qclose Tx Test Case"""
365 @unittest.skipUnless(config.extended, "part of extended tests")
366 @unittest.skip("testcase under development")
367 def test_quic_ext_qclose_tx(self):
368 """QUIC external transfer, tx close"""
369 self.server("TX=0", "RX=10M", "qclose=W", "sclose=W", "rx-results-diff")
370 self.client("TX=10M", "RX=0", "qclose=Y", "sclose=N")
371 self.validate_ext_test_results()
374 class QUICEchoExtEarlyQcloseRxTestCase(QUICEchoExtTestCase):
375 """QUIC Echo External Transfer Early Qclose Rx Test Case"""
377 @unittest.skipUnless(config.extended, "part of extended tests")
378 @unittest.skip("testcase under development")
379 def test_quic_ext_early_qclose_rx(self):
380 """QUIC external transfer, early rx close"""
381 self.server("TX=0", "RX=10M", "qclose=Y", "sclose=N")
382 self.client("TX=20M", "RX=0", "qclose=W", "sclose=W", "tx-results-diff")
383 self.validate_ext_test_results()
386 class QUICEchoExtEarlyQcloseTxTestCase(QUICEchoExtTestCase):
387 """QUIC Echo External Transfer Early Qclose Tx Test Case"""
389 @unittest.skipUnless(config.extended, "part of extended tests")
390 @unittest.skip("testcase under development")
391 def test_quic_ext_early_qclose_tx(self):
392 """QUIC external transfer, early tx close"""
393 self.server("TX=0", "RX=20M", "qclose=W", "sclose=W", "rx-results-diff")
394 self.client("TX=10M", "RX=0", "qclose=Y", "sclose=N")
395 self.validate_ext_test_results()
398 class QUICEchoExtScloseRxTestCase(QUICEchoExtTestCase):
399 """QUIC Echo External Transfer Sclose Rx Test Case"""
401 @unittest.skipUnless(config.extended, "part of extended tests")
402 @unittest.skip("testcase under development")
403 def test_quic_ext_sclose_rx(self):
404 """QUIC external transfer, rx stream close"""
405 self.server("TX=0", "RX=10M", "qclose=N", "sclose=Y")
406 self.client("TX=10M", "RX=0", "qclose=W", "sclose=W")
407 self.validate_ext_test_results()
410 class QUICEchoExtScloseTxTestCase(QUICEchoExtTestCase):
411 """QUIC Echo External Transfer Sclose Tx Test Case"""
413 @unittest.skipUnless(config.extended, "part of extended tests")
414 @unittest.skip("testcase under development")
415 def test_quic_ext_sclose_tx(self):
416 """QUIC external transfer, tx stream close"""
417 self.server("TX=0", "RX=10M", "qclose=W", "sclose=W")
418 self.client("TX=10M", "RX=0", "qclose=Y", "sclose=Y")
419 self.validate_ext_test_results()
422 class QUICEchoExtEarlyScloseRxTestCase(QUICEchoExtTestCase):
423 """QUIC Echo External Transfer Early Sclose Rx Test Case"""
425 @unittest.skipUnless(config.extended, "part of extended tests")
426 @unittest.skip("testcase under development")
427 def test_quic_ext_early_sclose_rx(self):
428 """QUIC external transfer, early rx stream close"""
429 self.server("TX=0", "RX=10M", "qclose=N", "sclose=Y")
430 self.client("TX=20M", "RX=0", "qclose=W", "sclose=W", "tx-results-diff")
431 self.validate_ext_test_results()
434 class QUICEchoExtEarlyScloseTxTestCase(QUICEchoExtTestCase):
435 """QUIC Echo External Transfer Early Sclose Tx Test Case"""
437 @unittest.skipUnless(config.extended, "part of extended tests")
438 @unittest.skip("testcase under development")
439 def test_quic_ext_early_sclose_tx(self):
440 """QUIC external transfer, early tx stream close"""
441 self.server("TX=0", "RX=20M", "qclose=W", "sclose=W", "rx-results-diff")
442 self.client("TX=10M", "RX=0", "qclose=Y", "sclose=Y")
443 self.validate_ext_test_results()
446 class QUICEchoExtServerStreamTestCase(QUICEchoExtTestCase):
447 """QUIC Echo External Transfer Server Stream Test Case"""
449 quic_setup = "serverstream"
452 def test_quic_ext_transfer_server_stream(self):
453 """QUIC external server transfer"""
454 self.server("TX=10M", "RX=0")
455 self.client("TX=0", "RX=10M")
456 self.validate_ext_test_results()
459 class QUICEchoExtServerStreamBigTestCase(QUICEchoExtTestCase):
460 """QUIC Echo External Transfer Server Stream Big Test Case"""
462 quic_setup = "serverstream"
463 server_fifo_size = "4M"
464 client_fifo_size = "4M"
468 @unittest.skipUnless(config.extended, "part of extended tests")
469 def test_quic_ext_transfer_server_stream_big(self):
470 """QUIC external server transfer, big stream"""
471 self.server("TX=2G", "RX=0")
472 self.client("TX=0", "RX=2G")
473 self.validate_ext_test_results()
476 class QUICEchoExtServerStreamQcloseRxTestCase(QUICEchoExtTestCase):
477 """QUIC Echo External Transfer Server Stream Qclose Rx Test Case"""
479 quic_setup = "serverstream"
481 @unittest.skipUnless(config.extended, "part of extended tests")
482 @unittest.skip("testcase under development")
483 def test_quic_ext_server_stream_qclose_rx(self):
484 """QUIC external server transfer, rx close"""
485 self.server("TX=10M", "RX=0", "qclose=W", "sclose=W")
486 self.client("TX=0", "RX=10M", "qclose=Y", "sclose=N")
487 self.validate_ext_test_results()
490 class QUICEchoExtServerStreamQcloseTxTestCase(QUICEchoExtTestCase):
491 """QUIC Echo External Transfer Server Stream Qclose Tx Test Case"""
493 quic_setup = "serverstream"
495 @unittest.skipUnless(config.extended, "part of extended tests")
496 @unittest.skip("testcase under development")
497 def test_quic_ext_server_stream_qclose_tx(self):
498 """QUIC external server transfer, tx close"""
499 self.server("TX=10M", "RX=0", "qclose=Y", "sclose=N")
500 self.client("TX=0", "RX=10M", "qclose=W", "sclose=W", "rx-results-diff")
501 self.validate_ext_test_results()
504 class QUICEchoExtServerStreamEarlyQcloseRxTestCase(QUICEchoExtTestCase):
505 """QUIC Echo External Transfer Server Stream Early Qclose Rx Test Case"""
507 quic_setup = "serverstream"
509 @unittest.skipUnless(config.extended, "part of extended tests")
510 @unittest.skip("testcase under development")
511 def test_quic_ext_server_stream_early_qclose_rx(self):
512 """QUIC external server transfer, early rx close"""
513 self.server("TX=20M", "RX=0", "qclose=W", "sclose=W", "tx-results-diff")
514 self.client("TX=0", "RX=10M", "qclose=Y", "sclose=N")
515 self.validate_ext_test_results()
518 class QUICEchoExtServerStreamEarlyQcloseTxTestCase(QUICEchoExtTestCase):
519 """QUIC Echo External Transfer Server Stream Early Qclose Tx Test Case"""
521 quic_setup = "serverstream"
523 @unittest.skipUnless(config.extended, "part of extended tests")
524 @unittest.skip("testcase under development")
525 def test_quic_ext_server_stream_early_qclose_tx(self):
526 """QUIC external server transfer, early tx close"""
527 self.server("TX=10M", "RX=0", "qclose=Y", "sclose=N")
528 self.client("TX=0", "RX=20M", "qclose=W", "sclose=W", "rx-results-diff")
529 self.validate_ext_test_results()
532 class QUICEchoExtServerStreamScloseRxTestCase(QUICEchoExtTestCase):
533 """QUIC Echo External Transfer Server Stream Sclose Rx Test Case"""
535 quic_setup = "serverstream"
537 @unittest.skipUnless(config.extended, "part of extended tests")
538 @unittest.skip("testcase under development")
539 def test_quic_ext_server_stream_sclose_rx(self):
540 """QUIC external server transfer, rx stream close"""
541 self.server("TX=10M", "RX=0", "qclose=W", "sclose=W")
542 self.client("TX=0", "RX=10M", "qclose=N", "sclose=Y")
543 self.validate_ext_test_results()
546 class QUICEchoExtServerStreamScloseTxTestCase(QUICEchoExtTestCase):
547 """QUIC Echo External Transfer Server Stream Sclose Tx Test Case"""
549 quic_setup = "serverstream"
551 @unittest.skipUnless(config.extended, "part of extended tests")
552 @unittest.skip("testcase under development")
553 def test_quic_ext_server_stream_sclose_tx(self):
554 """QUIC external server transfer, tx stream close"""
555 self.server("TX=10M", "RX=0", "qclose=Y", "sclose=Y")
556 self.client("TX=0", "RX=10M", "qclose=W", "sclose=W")
557 self.validate_ext_test_results()
560 class QUICEchoExtServerStreamEarlyScloseRxTestCase(QUICEchoExtTestCase):
561 """QUIC Echo External Transfer Server Stream Early Sclose Rx Test Case"""
563 quic_setup = "serverstream"
565 @unittest.skipUnless(config.extended, "part of extended tests")
566 @unittest.skip("testcase under development")
567 def test_quic_ext_server_stream_early_sclose_rx(self):
568 """QUIC external server transfer, early rx stream close"""
569 self.server("TX=20M", "RX=0", "qclose=W", "sclose=W", "tx-results-diff")
570 self.client("TX=0", "RX=10M", "qclose=N", "sclose=Y")
571 self.validate_ext_test_results()
574 class QUICEchoExtServerStreamEarlyScloseTxTestCase(QUICEchoExtTestCase):
575 """QUIC Echo Ext Transfer Server Stream Early Sclose Tx Test Case"""
577 quic_setup = "serverstream"
579 @unittest.skipUnless(config.extended, "part of extended tests")
580 @unittest.skip("testcase under development")
581 def test_quic_ext_server_stream_early_sclose_tx(self):
582 """QUIC external server transfer, early tx stream close"""
583 self.server("TX=10M", "RX=0", "qclose=Y", "sclose=Y")
584 self.client("TX=0", "RX=20M", "qclose=W", "sclose=W", "rx-results-diff")
585 self.validate_ext_test_results()
588 class QUICEchoExtServerStreamWorkersTestCase(QUICEchoExtTestCase):
589 """QUIC Echo External Transfer Server Stream MultiWorker Test Case"""
591 quic_setup = "serverstream"
593 @unittest.skipUnless(config.extended, "part of extended tests")
594 @unittest.skip("testcase under development")
595 def test_quic_ext_transfer_server_stream_multi_workers(self):
596 """QUIC external server transfer, multi-worker"""
597 self.server("nclients", "4", "quic-streams", "4", "TX=10M", "RX=0")
598 self.client("nclients", "4", "quic-streams", "4", "TX=0", "RX=10M")
599 self.validate_ext_test_results()
602 if __name__ == "__main__":
603 unittest.main(testRunner=VppTestRunner)