8 from framework import tag_fixme_vpp_workers
9 from framework import VppTestCase, VppTestRunner, running_extended_tests, \
11 from vpp_ip_route import VppIpTable, VppIpRoute, VppRoutePath
14 class QUICAppWorker(Worker):
15 """ QUIC Test Application Worker """
18 def __init__(self, build_dir, appname, executable_args, logger, role,
19 testcase, env=None, *args, **kwargs):
22 app = "%s/vpp/bin/%s" % (build_dir, 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()
61 self.build_dir = os.getenv(var, None)
62 if self.build_dir is None:
63 raise Exception("Environment variable `%s' not set" % var)
64 self.vppDebug = 'vpp_debug' in self.build_dir
66 self.create_loopback_interfaces(2)
67 self.uri = "quic://%s/1234" % self.loop0.local_ip4
69 for i in self.lo_interfaces:
73 tbl = VppIpTable(self, table_id)
76 i.set_table_ip4(table_id)
80 # Configure namespaces
81 self.vapi.app_namespace_add_del(namespace_id="server",
82 sw_if_index=self.loop0.sw_if_index)
83 self.vapi.app_namespace_add_del(namespace_id="client",
84 sw_if_index=self.loop1.sw_if_index)
86 # Add inter-table routes
87 self.ip_t01 = VppIpRoute(self, self.loop1.local_ip4, 32,
88 [VppRoutePath("0.0.0.0",
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",
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"))
100 # Delete inter-table routes
101 self.ip_t01.remove_vpp_config()
102 self.ip_t10.remove_vpp_config()
104 for i in self.lo_interfaces:
108 super(QUICTestCase, self).tearDown()
111 class QUICEchoIntTestCase(QUICTestCase):
112 """QUIC Echo Internal Test Case"""
113 test_bytes = ' test-bytes'
114 extra_vpp_punt_config = ["session", "{", "enable", "poll-main", "}"]
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
123 super(QUICEchoIntTestCase, self).tearDown()
125 def server(self, *args):
126 error = self.vapi.cli(
127 "test echo server %s %s" %
128 (self.server_args, ' '.join(args)))
130 self.logger.critical(error)
131 self.assertNotIn("failed", error)
133 def client(self, *args):
134 error = self.vapi.cli(
135 "test echo client %s %s" %
136 (self.client_args, ' '.join(args)))
138 self.logger.critical(error)
139 self.assertNotIn("failed", error)
142 @tag_fixme_vpp_workers
143 class QUICEchoIntTransferTestCase(QUICEchoIntTestCase):
144 """QUIC Echo Internal Transfer Test Case"""
145 def test_quic_int_transfer(self):
146 """QUIC internal transfer"""
148 self.client("no-output", "mbytes", "2")
151 @tag_fixme_vpp_workers
152 class QUICEchoIntSerialTestCase(QUICEchoIntTestCase):
153 """QUIC Echo Internal Serial Transfer Test Case"""
154 def test_quic_serial_int_transfer(self):
155 """QUIC serial internal transfer"""
157 self.client("no-output", "mbytes", "2")
158 self.client("no-output", "mbytes", "2")
159 self.client("no-output", "mbytes", "2")
160 self.client("no-output", "mbytes", "2")
161 self.client("no-output", "mbytes", "2")
164 @tag_fixme_vpp_workers
165 class QUICEchoIntMStreamTestCase(QUICEchoIntTestCase):
166 """QUIC Echo Internal MultiStream Test Case"""
167 def test_quic_int_multistream_transfer(self):
168 """QUIC internal multi-stream transfer"""
170 self.client("nclients", "10", "mbytes", "1", "no-output")
173 class QUICEchoExtTestCase(QUICTestCase):
174 quic_setup = "default"
175 test_bytes = "test-bytes:assert"
181 server_fifo_size = "1M"
182 client_fifo_size = "4M"
183 extra_vpp_punt_config = ["session", "{",
184 "enable", "poll-main", "evt_qs_memfd_seg",
185 "evt_qs_seg_size", "64M",
186 "event-queue-length", f"{evt_q_len}",
187 "preallocated-sessions", "1024",
188 "v4-session-table-buckets", "20000",
189 "v4-session-table-memory", "64M",
190 "v4-halfopen-table-buckets", "20000",
191 "v4-halfopen-table-memory", "64M",
192 "local-endpoints-table-buckets", "250000",
193 "local-endpoints-table-memory", "512M",
197 super(QUICEchoExtTestCase, self).setUp()
202 "socket-name", self.get_api_sock_path(),
203 "quic-setup", self.quic_setup,
205 "mq-size", f"{self.evt_q_len}"
207 self.server_echo_test_args = common_args + \
208 ["server", "appns", "server", "fifo-size",
209 f"{self.server_fifo_size}"]
210 self.client_echo_test_args = common_args + \
211 ["client", "appns", "client", "fifo-size",
212 f"{self.client_fifo_size}"]
213 error = self.vapi.cli("quic set fifo-size 2M")
215 self.logger.critical(error)
216 self.assertNotIn("failed", error)
218 def server(self, *args):
219 _args = self.server_echo_test_args + list(args)
220 self.worker_server = QUICAppWorker(
227 self.worker_server.start()
228 self.sleep(self.pre_test_sleep)
230 def client(self, *args):
231 _args = self.client_echo_test_args + list(args)
232 self.worker_client = QUICAppWorker(
239 self.worker_client.start()
240 timeout = None if self.debug_all else self.timeout
241 self.worker_client.join(timeout)
242 if self.worker_client.is_alive():
243 error = f"Client failed to complete in {timeout} seconds!"
244 self.logger.critical(error)
246 self.worker_server.join(timeout)
247 if self.worker_server.is_alive():
248 error = f"Server failed to complete in {timeout} seconds!"
249 self.logger.critical(error)
250 self.sleep(self.post_test_sleep)
252 def validate_ext_test_results(self):
253 server_result = self.worker_server.result
254 client_result = self.worker_client.result
255 self.logger.info("Server worker result is `%s'" %
257 self.logger.info("Client worker result is `%s'" %
259 server_kill_error = False
260 if self.worker_server.result is None:
261 server_kill_error = self.worker_server.teardown(
262 self.logger, self.timeout)
263 if self.worker_client.result is None:
264 self.worker_client.teardown(self.logger, self.timeout)
265 err_msg = "Wrong server worker return code (%s)" % server_result
266 self.assertEqual(server_result, 0, err_msg)
267 self.assertIsNotNone(
269 "Timeout! Client worker did not finish in %ss" %
271 err_msg = "Wrong client worker return code (%s)" % client_result
272 self.assertEqual(client_result, 0, err_msg)
273 self.assertFalse(server_kill_error, "Server kill errored")
276 class QUICEchoExtTransferTestCase(QUICEchoExtTestCase):
277 """QUIC Echo External Transfer Test Case"""
280 def test_quic_ext_transfer(self):
281 """QUIC external transfer"""
284 self.validate_ext_test_results()
287 class QUICEchoExtTransferBigTestCase(QUICEchoExtTestCase):
288 """QUIC Echo External Transfer Big Test Case"""
289 server_fifo_size = '4M'
290 client_fifo_size = '4M'
294 @unittest.skipUnless(running_extended_tests, "part of extended tests")
295 def test_quic_ext_transfer_big(self):
296 """QUIC external transfer, big stream"""
297 self.server("TX=0", "RX=2G")
298 self.client("TX=2G", "RX=0")
299 self.validate_ext_test_results()
302 class QUICEchoExtQcloseRxTestCase(QUICEchoExtTestCase):
303 """QUIC Echo External Transfer Qclose Rx Test Case"""
305 @unittest.skipUnless(running_extended_tests, "part of extended tests")
306 @unittest.skip("testcase under development")
307 def test_quic_ext_qclose_rx(self):
308 """QUIC external transfer, rx close"""
309 self.server("TX=0", "RX=10M", "qclose=Y", "sclose=N")
310 self.client("TX=10M", "RX=0", "qclose=W", "sclose=W")
311 self.validate_ext_test_results()
314 class QUICEchoExtQcloseTxTestCase(QUICEchoExtTestCase):
315 """QUIC Echo External Transfer Qclose Tx Test Case"""
317 @unittest.skipUnless(running_extended_tests, "part of extended tests")
318 @unittest.skip("testcase under development")
319 def test_quic_ext_qclose_tx(self):
320 """QUIC external transfer, tx close"""
321 self.server("TX=0", "RX=10M", "qclose=W", "sclose=W",
323 self.client("TX=10M", "RX=0", "qclose=Y", "sclose=N")
324 self.validate_ext_test_results()
327 class QUICEchoExtEarlyQcloseRxTestCase(QUICEchoExtTestCase):
328 """QUIC Echo External Transfer Early Qclose Rx Test Case"""
330 @unittest.skipUnless(running_extended_tests, "part of extended tests")
331 @unittest.skip("testcase under development")
332 def test_quic_ext_early_qclose_rx(self):
333 """QUIC external transfer, early rx close"""
334 self.server("TX=0", "RX=10M", "qclose=Y", "sclose=N")
335 self.client("TX=20M", "RX=0", "qclose=W", "sclose=W",
337 self.validate_ext_test_results()
340 class QUICEchoExtEarlyQcloseTxTestCase(QUICEchoExtTestCase):
341 """QUIC Echo External Transfer Early Qclose Tx Test Case"""
343 @unittest.skipUnless(running_extended_tests, "part of extended tests")
344 @unittest.skip("testcase under development")
345 def test_quic_ext_early_qclose_tx(self):
346 """QUIC external transfer, early tx close"""
347 self.server("TX=0", "RX=20M", "qclose=W", "sclose=W",
349 self.client("TX=10M", "RX=0", "qclose=Y", "sclose=N")
350 self.validate_ext_test_results()
353 class QUICEchoExtScloseRxTestCase(QUICEchoExtTestCase):
354 """QUIC Echo External Transfer Sclose Rx Test Case"""
356 @unittest.skipUnless(running_extended_tests, "part of extended tests")
357 @unittest.skip("testcase under development")
358 def test_quic_ext_sclose_rx(self):
359 """QUIC external transfer, rx stream close"""
360 self.server("TX=0", "RX=10M", "qclose=N", "sclose=Y")
361 self.client("TX=10M", "RX=0", "qclose=W", "sclose=W")
362 self.validate_ext_test_results()
365 class QUICEchoExtScloseTxTestCase(QUICEchoExtTestCase):
366 """QUIC Echo External Transfer Sclose Tx Test Case"""
368 @unittest.skipUnless(running_extended_tests, "part of extended tests")
369 @unittest.skip("testcase under development")
370 def test_quic_ext_sclose_tx(self):
371 """QUIC external transfer, tx stream close"""
372 self.server("TX=0", "RX=10M", "qclose=W", "sclose=W")
373 self.client("TX=10M", "RX=0", "qclose=Y", "sclose=Y")
374 self.validate_ext_test_results()
377 class QUICEchoExtEarlyScloseRxTestCase(QUICEchoExtTestCase):
378 """QUIC Echo External Transfer Early Sclose Rx Test Case"""
380 @unittest.skipUnless(running_extended_tests, "part of extended tests")
381 @unittest.skip("testcase under development")
382 def test_quic_ext_early_sclose_rx(self):
383 """QUIC external transfer, early rx stream close"""
384 self.server("TX=0", "RX=10M", "qclose=N", "sclose=Y")
385 self.client("TX=20M", "RX=0", "qclose=W", "sclose=W",
387 self.validate_ext_test_results()
390 class QUICEchoExtEarlyScloseTxTestCase(QUICEchoExtTestCase):
391 """QUIC Echo External Transfer Early Sclose Tx Test Case"""
393 @unittest.skipUnless(running_extended_tests, "part of extended tests")
394 @unittest.skip("testcase under development")
395 def test_quic_ext_early_sclose_tx(self):
396 """QUIC external transfer, early tx stream close"""
397 self.server("TX=0", "RX=20M", "qclose=W", "sclose=W",
399 self.client("TX=10M", "RX=0", "qclose=Y", "sclose=Y")
400 self.validate_ext_test_results()
403 class QUICEchoExtServerStreamTestCase(QUICEchoExtTestCase):
404 """QUIC Echo External Transfer Server Stream Test Case"""
405 quic_setup = "serverstream"
408 def test_quic_ext_transfer_server_stream(self):
409 """QUIC external server transfer"""
410 self.server("TX=10M", "RX=0")
411 self.client("TX=0", "RX=10M")
412 self.validate_ext_test_results()
415 class QUICEchoExtServerStreamBigTestCase(QUICEchoExtTestCase):
416 """QUIC Echo External Transfer Server Stream Big Test Case"""
417 quic_setup = "serverstream"
418 server_fifo_size = '4M'
419 client_fifo_size = '4M'
423 @unittest.skipUnless(running_extended_tests, "part of extended tests")
424 def test_quic_ext_transfer_server_stream_big(self):
425 """QUIC external server transfer, big stream"""
426 self.server("TX=2G", "RX=0")
427 self.client("TX=0", "RX=2G")
428 self.validate_ext_test_results()
431 class QUICEchoExtServerStreamQcloseRxTestCase(QUICEchoExtTestCase):
432 """QUIC Echo External Transfer Server Stream Qclose Rx Test Case"""
433 quic_setup = "serverstream"
435 @unittest.skipUnless(running_extended_tests, "part of extended tests")
436 @unittest.skip("testcase under development")
437 def test_quic_ext_server_stream_qclose_rx(self):
438 """QUIC external server transfer, rx close"""
439 self.server("TX=10M", "RX=0", "qclose=W", "sclose=W")
440 self.client("TX=0", "RX=10M", "qclose=Y", "sclose=N")
441 self.validate_ext_test_results()
444 class QUICEchoExtServerStreamQcloseTxTestCase(QUICEchoExtTestCase):
445 """QUIC Echo External Transfer Server Stream Qclose Tx Test Case"""
446 quic_setup = "serverstream"
448 @unittest.skipUnless(running_extended_tests, "part of extended tests")
449 @unittest.skip("testcase under development")
450 def test_quic_ext_server_stream_qclose_tx(self):
451 """QUIC external server transfer, tx close"""
452 self.server("TX=10M", "RX=0", "qclose=Y", "sclose=N")
453 self.client("TX=0", "RX=10M", "qclose=W", "sclose=W",
455 self.validate_ext_test_results()
458 class QUICEchoExtServerStreamEarlyQcloseRxTestCase(QUICEchoExtTestCase):
459 """QUIC Echo External Transfer Server Stream Early Qclose Rx Test Case"""
460 quic_setup = "serverstream"
462 @unittest.skipUnless(running_extended_tests, "part of extended tests")
463 @unittest.skip("testcase under development")
464 def test_quic_ext_server_stream_early_qclose_rx(self):
465 """QUIC external server transfer, early rx close"""
466 self.server("TX=20M", "RX=0", "qclose=W", "sclose=W",
468 self.client("TX=0", "RX=10M", "qclose=Y", "sclose=N")
469 self.validate_ext_test_results()
472 class QUICEchoExtServerStreamEarlyQcloseTxTestCase(QUICEchoExtTestCase):
473 """QUIC Echo External Transfer Server Stream Early Qclose Tx Test Case"""
474 quic_setup = "serverstream"
476 @unittest.skipUnless(running_extended_tests, "part of extended tests")
477 @unittest.skip("testcase under development")
478 def test_quic_ext_server_stream_early_qclose_tx(self):
479 """QUIC external server transfer, early tx close"""
480 self.server("TX=10M", "RX=0", "qclose=Y", "sclose=N")
481 self.client("TX=0", "RX=20M", "qclose=W", "sclose=W",
483 self.validate_ext_test_results()
486 class QUICEchoExtServerStreamScloseRxTestCase(QUICEchoExtTestCase):
487 """QUIC Echo External Transfer Server Stream Sclose Rx Test Case"""
488 quic_setup = "serverstream"
490 @unittest.skipUnless(running_extended_tests, "part of extended tests")
491 @unittest.skip("testcase under development")
492 def test_quic_ext_server_stream_sclose_rx(self):
493 """QUIC external server transfer, rx stream close"""
494 self.server("TX=10M", "RX=0", "qclose=W", "sclose=W")
495 self.client("TX=0", "RX=10M", "qclose=N", "sclose=Y")
496 self.validate_ext_test_results()
499 class QUICEchoExtServerStreamScloseTxTestCase(QUICEchoExtTestCase):
500 """QUIC Echo External Transfer Server Stream Sclose Tx Test Case"""
501 quic_setup = "serverstream"
503 @unittest.skipUnless(running_extended_tests, "part of extended tests")
504 @unittest.skip("testcase under development")
505 def test_quic_ext_server_stream_sclose_tx(self):
506 """QUIC external server transfer, tx stream close"""
507 self.server("TX=10M", "RX=0", "qclose=Y", "sclose=Y")
508 self.client("TX=0", "RX=10M", "qclose=W", "sclose=W")
509 self.validate_ext_test_results()
512 class QUICEchoExtServerStreamEarlyScloseRxTestCase(QUICEchoExtTestCase):
513 """QUIC Echo External Transfer Server Stream Early Sclose Rx Test Case"""
514 quic_setup = "serverstream"
516 @unittest.skipUnless(running_extended_tests, "part of extended tests")
517 @unittest.skip("testcase under development")
518 def test_quic_ext_server_stream_early_sclose_rx(self):
519 """QUIC external server transfer, early rx stream close"""
520 self.server("TX=20M", "RX=0", "qclose=W", "sclose=W",
522 self.client("TX=0", "RX=10M", "qclose=N", "sclose=Y")
523 self.validate_ext_test_results()
526 class QUICEchoExtServerStreamEarlyScloseTxTestCase(QUICEchoExtTestCase):
527 """QUIC Echo Ext Transfer Server Stream Early Sclose Tx Test Case"""
528 quic_setup = "serverstream"
530 @unittest.skipUnless(running_extended_tests, "part of extended tests")
531 @unittest.skip("testcase under development")
532 def test_quic_ext_server_stream_early_sclose_tx(self):
533 """QUIC external server transfer, early tx stream close"""
534 self.server("TX=10M", "RX=0", "qclose=Y", "sclose=Y")
535 self.client("TX=0", "RX=20M", "qclose=W", "sclose=W",
537 self.validate_ext_test_results()
540 class QUICEchoExtServerStreamWorkersTestCase(QUICEchoExtTestCase):
541 """QUIC Echo External Transfer Server Stream MultiWorker Test Case"""
542 quic_setup = "serverstream"
544 @unittest.skipUnless(running_extended_tests, "part of extended tests")
545 @unittest.skip("testcase under development")
546 def test_quic_ext_transfer_server_stream_multi_workers(self):
547 """QUIC external server transfer, multi-worker"""
548 self.server("nclients", "4", "quic-streams", "4", "TX=10M", "RX=0")
549 self.client("nclients", "4", "quic-streams", "4", "TX=0", "RX=10M")
550 self.validate_ext_test_results()
553 if __name__ == '__main__':
554 unittest.main(testRunner=VppTestRunner)