tests: session in interrupt mode
[vpp.git] / test / test_vcl.py
1 #!/usr/bin/env python3
2 """ Vpp VCL tests """
3
4 import unittest
5 import os
6 import subprocess
7 import signal
8 import glob
9 from config import config
10 from framework import VppTestCase, VppTestRunner, Worker
11 from vpp_ip_route import VppIpTable, VppIpRoute, VppRoutePath, FibPathProto
12
13 iperf3 = "/usr/bin/iperf3"
14
15
16 def have_app(app):
17     try:
18         subprocess.check_output([app, "-v"])
19     except (subprocess.CalledProcessError, OSError):
20         return False
21     return True
22
23
24 _have_iperf3 = have_app(iperf3)
25
26
27 class VCLAppWorker(Worker):
28     """VCL Test Application Worker"""
29
30     libname = "libvcl_ldpreload.so"
31
32     class LibraryNotFound(Exception):
33         pass
34
35     def __init__(
36         self, appname, executable_args, logger, env=None, role=None, *args, **kwargs
37     ):
38         self.role = role
39         vcl_ldpreload_glob = f"{config.vpp_install_dir}/**/{self.libname}"
40         vcl_ldpreload_so = glob.glob(vcl_ldpreload_glob, recursive=True)
41
42         if len(vcl_ldpreload_so) < 1:
43             raise LibraryNotFound("cannot locate library: {}".format(self.libname))
44
45         vcl_ldpreload_so = vcl_ldpreload_so[0]
46
47         if env is None:
48             env = {}
49         if "iperf" in appname:
50             app = appname
51             env.update({"LD_PRELOAD": vcl_ldpreload_so})
52         elif "sock" in appname:
53             app = f"{config.vpp_build_dir}/vpp/bin/{appname}"
54             env.update({"LD_PRELOAD": vcl_ldpreload_so})
55         else:
56             app = f"{config.vpp_build_dir}/vpp/bin/{appname}"
57         self.args = [app] + executable_args
58         super(VCLAppWorker, self).__init__(self.args, logger, env, *args, **kwargs)
59
60
61 class VCLTestCase(VppTestCase):
62     """VCL Test Class"""
63
64     session_startup = ["poll-main"]
65
66     @classmethod
67     def setUpClass(cls):
68         if cls.session_startup:
69             conf = "session {" + " ".join(cls.session_startup) + "}"
70             cls.extra_vpp_punt_config = [conf]
71         super(VCLTestCase, cls).setUpClass()
72
73     @classmethod
74     def tearDownClass(cls):
75         super(VCLTestCase, cls).tearDownClass()
76
77     def setUp(self):
78         self.vppDebug = "vpp_debug" in config.vpp_install_dir
79         self.server_addr = "127.0.0.1"
80         self.server_port = "22000"
81         self.server_args = [self.server_port]
82         self.server_ipv6_addr = "::1"
83         self.server_ipv6_args = ["-6", self.server_port]
84         self.timeout = 20
85         self.echo_phrase = "Hello, world! Jenny is a friend of mine."
86         self.pre_test_sleep = 0.3
87         self.post_test_sleep = 0.2
88         self.sapi_client_sock = ""
89         self.sapi_server_sock = ""
90
91         if os.path.isfile("/tmp/ldp_server_af_unix_socket"):
92             os.remove("/tmp/ldp_server_af_unix_socket")
93
94         super(VCLTestCase, self).setUp()
95
96     def update_vcl_app_env(self, ns_id, ns_secret, attach_sock):
97         if not ns_id:
98             if "VCL_APP_NAMESPACE_ID" in self.vcl_app_env:
99                 del self.vcl_app_env["VCL_APP_NAMESPACE_ID"]
100         else:
101             self.vcl_app_env["VCL_APP_NAMESPACE_ID"] = ns_id
102
103         if not ns_secret:
104             if "VCL_APP_NAMESPACE_SECRET" in self.vcl_app_env:
105                 del self.vcl_app_env["VCL_APP_NAMESPACE_SECRET"]
106         else:
107             self.vcl_app_env["VCL_APP_NAMESPACE_SECRET"] = ns_secret
108
109         if not attach_sock:
110             self.vcl_app_env["VCL_VPP_API_SOCKET"] = self.get_api_sock_path()
111             if "VCL_VPP_SAPI_SOCKET" in self.vcl_app_env:
112                 del self.vcl_app_env["VCL_VPP_SAPI_SOCKET"]
113         else:
114             sapi_sock = "%s/app_ns_sockets/%s" % (self.tempdir, attach_sock)
115             self.vcl_app_env["VCL_VPP_SAPI_SOCKET"] = sapi_sock
116             if "VCL_VPP_API_SOCKET" in self.vcl_app_env:
117                 del self.vcl_app_env["VCL_VPP_API_SOCKET"]
118
119     def cut_thru_setup(self):
120         self.vapi.session_enable_disable(is_enable=1)
121
122     def cut_thru_tear_down(self):
123         self.vapi.session_enable_disable(is_enable=0)
124
125     def cut_thru_test(self, server_app, server_args, client_app, client_args):
126         self.vcl_app_env = {"VCL_APP_SCOPE_LOCAL": "true"}
127
128         self.update_vcl_app_env("", "", self.sapi_server_sock)
129         worker_server = VCLAppWorker(
130             server_app, server_args, self.logger, self.vcl_app_env, "server"
131         )
132         worker_server.start()
133         self.sleep(self.pre_test_sleep)
134
135         self.update_vcl_app_env("", "", self.sapi_client_sock)
136         worker_client = VCLAppWorker(
137             client_app, client_args, self.logger, self.vcl_app_env, "client"
138         )
139         worker_client.start()
140         worker_client.join(self.timeout)
141         try:
142             self.validateResults(worker_client, worker_server, self.timeout)
143         except Exception as error:
144             self.fail("Failed with %s" % error)
145         self.sleep(self.post_test_sleep)
146
147     def thru_host_stack_setup(self):
148         self.vapi.session_enable_disable(is_enable=1)
149         self.create_loopback_interfaces(2)
150
151         table_id = 1
152
153         for i in self.lo_interfaces:
154             i.admin_up()
155
156             if table_id != 0:
157                 tbl = VppIpTable(self, table_id)
158                 tbl.add_vpp_config()
159
160             i.set_table_ip4(table_id)
161             i.config_ip4()
162             table_id += 1
163
164         # Configure namespaces
165         self.vapi.app_namespace_add_del(
166             namespace_id="1", secret=1234, sw_if_index=self.loop0.sw_if_index
167         )
168         self.vapi.app_namespace_add_del(
169             namespace_id="2", secret=5678, sw_if_index=self.loop1.sw_if_index
170         )
171
172         # Add inter-table routes
173         ip_t01 = VppIpRoute(
174             self,
175             self.loop1.local_ip4,
176             32,
177             [VppRoutePath("0.0.0.0", 0xFFFFFFFF, nh_table_id=2)],
178             table_id=1,
179         )
180         ip_t10 = VppIpRoute(
181             self,
182             self.loop0.local_ip4,
183             32,
184             [VppRoutePath("0.0.0.0", 0xFFFFFFFF, nh_table_id=1)],
185             table_id=2,
186         )
187         ip_t01.add_vpp_config()
188         ip_t10.add_vpp_config()
189         self.logger.debug(self.vapi.cli("show ip fib"))
190
191     def thru_host_stack_tear_down(self):
192         for i in self.lo_interfaces:
193             i.unconfig_ip4()
194             i.set_table_ip4(0)
195             i.admin_down()
196             i.remove_vpp_config()
197
198     def thru_host_stack_ipv6_setup(self):
199         self.vapi.session_enable_disable(is_enable=1)
200         self.create_loopback_interfaces(2)
201
202         table_id = 1
203
204         for i in self.lo_interfaces:
205             i.admin_up()
206
207             tbl = VppIpTable(self, table_id, is_ip6=1)
208             tbl.add_vpp_config()
209
210             i.set_table_ip6(table_id)
211             i.config_ip6()
212             table_id += 1
213
214         # Configure namespaces
215         self.vapi.app_namespace_add_del(
216             namespace_id="1", secret=1234, sw_if_index=self.loop0.sw_if_index
217         )
218         self.vapi.app_namespace_add_del(
219             namespace_id="2", secret=5678, sw_if_index=self.loop1.sw_if_index
220         )
221
222         # Add inter-table routes
223         ip_t01 = VppIpRoute(
224             self,
225             self.loop1.local_ip6,
226             128,
227             [VppRoutePath("::0", 0xFFFFFFFF, nh_table_id=2)],
228             table_id=1,
229         )
230         ip_t10 = VppIpRoute(
231             self,
232             self.loop0.local_ip6,
233             128,
234             [VppRoutePath("::0", 0xFFFFFFFF, nh_table_id=1)],
235             table_id=2,
236         )
237         ip_t01.add_vpp_config()
238         ip_t10.add_vpp_config()
239         self.logger.debug(self.vapi.cli("show interface addr"))
240         self.logger.debug(self.vapi.cli("show ip6 fib"))
241
242     def thru_host_stack_ipv6_tear_down(self):
243         for i in self.lo_interfaces:
244             i.unconfig_ip6()
245             i.set_table_ip6(0)
246             i.admin_down()
247
248         self.vapi.session_enable_disable(is_enable=0)
249
250     @unittest.skipUnless(_have_iperf3, "'%s' not found, Skipping.")
251     def thru_host_stack_test(self, server_app, server_args, client_app, client_args):
252         self.vcl_app_env = {"VCL_APP_SCOPE_GLOBAL": "true"}
253
254         self.update_vcl_app_env("1", "1234", self.sapi_server_sock)
255         worker_server = VCLAppWorker(
256             server_app, server_args, self.logger, self.vcl_app_env, "server"
257         )
258         worker_server.start()
259         self.sleep(self.pre_test_sleep)
260
261         self.update_vcl_app_env("2", "5678", self.sapi_client_sock)
262         worker_client = VCLAppWorker(
263             client_app, client_args, self.logger, self.vcl_app_env, "client"
264         )
265         worker_client.start()
266         worker_client.join(self.timeout)
267
268         try:
269             self.validateResults(worker_client, worker_server, self.timeout)
270         except Exception as error:
271             self.fail("Failed with %s" % error)
272         self.sleep(self.post_test_sleep)
273
274     def validateResults(self, worker_client, worker_server, timeout):
275         if worker_server.process is None:
276             raise RuntimeError("worker_server is not running.")
277         if os.path.isdir("/proc/{}".format(worker_server.process.pid)):
278             self.logger.info(
279                 "Killing server worker process (pid %d)" % worker_server.process.pid
280             )
281             os.killpg(os.getpgid(worker_server.process.pid), signal.SIGTERM)
282             worker_server.join()
283         self.logger.info("Client worker result is `%s'" % worker_client.result)
284         error = False
285         if worker_client.result is None:
286             try:
287                 error = True
288                 self.logger.error(
289                     "Timeout: %ss! Killing client worker process (pid %d)"
290                     % (timeout, worker_client.process.pid)
291                 )
292                 os.killpg(os.getpgid(worker_client.process.pid), signal.SIGKILL)
293                 worker_client.join()
294             except OSError:
295                 self.logger.debug("Couldn't kill client worker process")
296                 raise
297         if error:
298             raise RuntimeError("Timeout! Client worker did not finish in %ss" % timeout)
299         self.assert_equal(worker_client.result, 0, "Binary test return code")
300
301
302 class LDPCutThruTestCase(VCLTestCase):
303     """LDP Cut Thru Tests"""
304
305     @classmethod
306     def setUpClass(cls):
307         cls.session_startup = ["poll-main", "use-app-socket-api"]
308         super(LDPCutThruTestCase, cls).setUpClass()
309
310     @classmethod
311     def tearDownClass(cls):
312         super(LDPCutThruTestCase, cls).tearDownClass()
313
314     def setUp(self):
315         super(LDPCutThruTestCase, self).setUp()
316
317         self.cut_thru_setup()
318         self.client_echo_test_args = [
319             "-E",
320             self.echo_phrase,
321             "-X",
322             self.server_addr,
323             self.server_port,
324         ]
325         self.client_iperf3_timeout = 20
326         self.client_iperf3_args = ["-4", "-t 2", "-c", self.server_addr]
327         self.server_iperf3_args = ["-4", "-s"]
328         self.client_uni_dir_nsock_timeout = 20
329         self.client_uni_dir_nsock_test_args = [
330             "-N",
331             "1000",
332             "-U",
333             "-X",
334             "-I",
335             "2",
336             self.server_addr,
337             self.server_port,
338         ]
339         self.client_bi_dir_nsock_timeout = 20
340         self.client_bi_dir_nsock_test_args = [
341             "-N",
342             "1000",
343             "-B",
344             "-X",
345             "-I",
346             "2",
347             self.server_addr,
348             self.server_port,
349         ]
350         self.sapi_client_sock = "default"
351         self.sapi_server_sock = "default"
352
353     def tearDown(self):
354         super(LDPCutThruTestCase, self).tearDown()
355         self.cut_thru_tear_down()
356
357     def show_commands_at_teardown(self):
358         self.logger.debug(self.vapi.cli("show session verbose 2"))
359         self.logger.debug(self.vapi.cli("show app mq"))
360
361     @unittest.skipUnless(config.extended, "part of extended tests")
362     def test_ldp_cut_thru_echo(self):
363         """run LDP cut thru echo test"""
364
365         self.cut_thru_test(
366             "sock_test_server",
367             self.server_args,
368             "sock_test_client",
369             self.client_echo_test_args,
370         )
371
372     def test_ldp_cut_thru_iperf3(self):
373         """run LDP cut thru iperf3 test"""
374
375         self.timeout = self.client_iperf3_timeout
376         self.cut_thru_test(
377             iperf3, self.server_iperf3_args, iperf3, self.client_iperf3_args
378         )
379
380     @unittest.skipUnless(config.extended, "part of extended tests")
381     def test_ldp_cut_thru_uni_dir_nsock(self):
382         """run LDP cut thru uni-directional (multiple sockets) test"""
383
384         self.timeout = self.client_uni_dir_nsock_timeout
385         self.cut_thru_test(
386             "sock_test_server",
387             self.server_args,
388             "sock_test_client",
389             self.client_uni_dir_nsock_test_args,
390         )
391
392     @unittest.skipUnless(config.extended, "part of extended tests")
393     @unittest.skip("sock test apps need to be improved")
394     def test_ldp_cut_thru_bi_dir_nsock(self):
395         """run LDP cut thru bi-directional (multiple sockets) test"""
396
397         self.timeout = self.client_bi_dir_nsock_timeout
398         self.cut_thru_test(
399             "sock_test_server",
400             self.server_args,
401             "sock_test_client",
402             self.client_bi_dir_nsock_test_args,
403         )
404
405
406 class VCLCutThruTestCase(VCLTestCase):
407     """VCL Cut Thru Tests"""
408
409     @classmethod
410     def setUpClass(cls):
411         super(VCLCutThruTestCase, cls).setUpClass()
412
413     @classmethod
414     def tearDownClass(cls):
415         super(VCLCutThruTestCase, cls).tearDownClass()
416
417     def setUp(self):
418         super(VCLCutThruTestCase, self).setUp()
419
420         self.cut_thru_setup()
421         self.client_echo_test_args = [
422             "-E",
423             self.echo_phrase,
424             "-X",
425             self.server_addr,
426             self.server_port,
427         ]
428
429         self.client_uni_dir_nsock_timeout = 20
430         self.client_uni_dir_nsock_test_args = [
431             "-N",
432             "1000",
433             "-U",
434             "-X",
435             "-I",
436             "2",
437             self.server_addr,
438             self.server_port,
439         ]
440         self.client_bi_dir_nsock_timeout = 20
441         self.client_bi_dir_nsock_test_args = [
442             "-N",
443             "1000",
444             "-B",
445             "-X",
446             "-I",
447             "2",
448             self.server_addr,
449             self.server_port,
450         ]
451
452     def tearDown(self):
453         super(VCLCutThruTestCase, self).tearDown()
454
455     def show_commands_at_teardown(self):
456         self.logger.debug(self.vapi.cli("show session verbose 2"))
457         self.logger.debug(self.vapi.cli("show app mq"))
458
459     def test_vcl_cut_thru_echo(self):
460         """run VCL cut thru echo test"""
461
462         self.cut_thru_test(
463             "vcl_test_server",
464             self.server_args,
465             "vcl_test_client",
466             self.client_echo_test_args,
467         )
468
469     def test_vcl_cut_thru_uni_dir_nsock(self):
470         """run VCL cut thru uni-directional (multiple sockets) test"""
471
472         self.timeout = self.client_uni_dir_nsock_timeout
473         self.cut_thru_test(
474             "vcl_test_server",
475             self.server_args,
476             "vcl_test_client",
477             self.client_uni_dir_nsock_test_args,
478         )
479
480     def test_vcl_cut_thru_bi_dir_nsock(self):
481         """run VCL cut thru bi-directional (multiple sockets) test"""
482
483         self.timeout = self.client_bi_dir_nsock_timeout
484         self.cut_thru_test(
485             "vcl_test_server",
486             self.server_args,
487             "vcl_test_client",
488             self.client_bi_dir_nsock_test_args,
489         )
490
491
492 class VCLThruHostStackEcho(VCLTestCase):
493     """VCL Thru Host Stack Echo"""
494
495     @classmethod
496     def setUpClass(cls):
497         super(VCLThruHostStackEcho, cls).setUpClass()
498
499     @classmethod
500     def tearDownClass(cls):
501         super(VCLThruHostStackEcho, cls).tearDownClass()
502
503     def setUp(self):
504         super(VCLThruHostStackEcho, self).setUp()
505
506         self.thru_host_stack_setup()
507         self.client_bi_dir_nsock_timeout = 20
508         self.client_bi_dir_nsock_test_args = [
509             "-N",
510             "1000",
511             "-B",
512             "-X",
513             "-I",
514             "2",
515             self.loop0.local_ip4,
516             self.server_port,
517         ]
518         self.client_echo_test_args = [
519             "-E",
520             self.echo_phrase,
521             "-X",
522             self.loop0.local_ip4,
523             self.server_port,
524         ]
525
526     def tearDown(self):
527         self.thru_host_stack_tear_down()
528         super(VCLThruHostStackEcho, self).tearDown()
529
530     def test_vcl_thru_host_stack_echo(self):
531         """run VCL IPv4 thru host stack echo test"""
532
533         self.thru_host_stack_test(
534             "vcl_test_server",
535             self.server_args,
536             "vcl_test_client",
537             self.client_echo_test_args,
538         )
539
540     def show_commands_at_teardown(self):
541         self.logger.debug(self.vapi.cli("show app server"))
542         self.logger.debug(self.vapi.cli("show session verbose"))
543         self.logger.debug(self.vapi.cli("show app mq"))
544
545
546 class VCLThruHostStackTLS(VCLTestCase):
547     """VCL Thru Host Stack TLS"""
548
549     @classmethod
550     def setUpClass(cls):
551         cls.session_startup = ["poll-main", "use-app-socket-api"]
552         super(VCLThruHostStackTLS, cls).setUpClass()
553
554     @classmethod
555     def tearDownClass(cls):
556         super(VCLThruHostStackTLS, cls).tearDownClass()
557
558     def setUp(self):
559         super(VCLThruHostStackTLS, self).setUp()
560
561         self.thru_host_stack_setup()
562         self.client_uni_dir_tls_timeout = 20
563         self.server_tls_args = ["-L", self.server_port]
564         self.client_uni_dir_tls_test_args = [
565             "-N",
566             "1000",
567             "-U",
568             "-X",
569             "-L",
570             self.loop0.local_ip4,
571             self.server_port,
572         ]
573         self.sapi_server_sock = "1"
574         self.sapi_client_sock = "2"
575
576     def test_vcl_thru_host_stack_tls_uni_dir(self):
577         """run VCL thru host stack uni-directional TLS test"""
578
579         self.timeout = self.client_uni_dir_tls_timeout
580         self.thru_host_stack_test(
581             "vcl_test_server",
582             self.server_tls_args,
583             "vcl_test_client",
584             self.client_uni_dir_tls_test_args,
585         )
586
587     def tearDown(self):
588         self.thru_host_stack_tear_down()
589         super(VCLThruHostStackTLS, self).tearDown()
590
591     def show_commands_at_teardown(self):
592         self.logger.debug(self.vapi.cli("show app server"))
593         self.logger.debug(self.vapi.cli("show session verbose 2"))
594         self.logger.debug(self.vapi.cli("show app mq"))
595
596
597 class VCLThruHostStackTLSInterruptMode(VCLThruHostStackTLS):
598     """VCL Thru Host Stack TLS interrupt mode"""
599
600     @classmethod
601     def setUpClass(cls):
602         cls.session_startup = ["poll-main", "use-app-socket-api", "use-private-rx-mqs"]
603         super(VCLThruHostStackTLS, cls).setUpClass()
604
605
606 class VCLThruHostStackDTLS(VCLTestCase):
607     """VCL Thru Host Stack DTLS"""
608
609     @classmethod
610     def setUpClass(cls):
611         super(VCLThruHostStackDTLS, cls).setUpClass()
612
613     @classmethod
614     def tearDownClass(cls):
615         super(VCLThruHostStackDTLS, cls).tearDownClass()
616
617     def setUp(self):
618         super(VCLThruHostStackDTLS, self).setUp()
619
620         self.thru_host_stack_setup()
621         self.client_uni_dir_dtls_timeout = 20
622         self.server_dtls_args = ["-p", "dtls", self.server_port]
623         self.client_uni_dir_dtls_test_args = [
624             "-N",
625             "1000",
626             "-U",
627             "-X",
628             "-p",
629             "dtls",
630             "-T 1400",
631             self.loop0.local_ip4,
632             self.server_port,
633         ]
634
635     def test_vcl_thru_host_stack_dtls_uni_dir(self):
636         """run VCL thru host stack uni-directional DTLS test"""
637
638         self.timeout = self.client_uni_dir_dtls_timeout
639         self.thru_host_stack_test(
640             "vcl_test_server",
641             self.server_dtls_args,
642             "vcl_test_client",
643             self.client_uni_dir_dtls_test_args,
644         )
645
646     def tearDown(self):
647         self.thru_host_stack_tear_down()
648         super(VCLThruHostStackDTLS, self).tearDown()
649
650     def show_commands_at_teardown(self):
651         self.logger.debug(self.vapi.cli("show app server"))
652         self.logger.debug(self.vapi.cli("show session verbose 2"))
653         self.logger.debug(self.vapi.cli("show app mq"))
654
655
656 class VCLThruHostStackQUIC(VCLTestCase):
657     """VCL Thru Host Stack QUIC"""
658
659     @classmethod
660     def setUpClass(cls):
661         cls.extra_vpp_plugin_config.append("plugin quic_plugin.so { enable }")
662         super(VCLThruHostStackQUIC, cls).setUpClass()
663
664     @classmethod
665     def tearDownClass(cls):
666         super(VCLThruHostStackQUIC, cls).tearDownClass()
667
668     def setUp(self):
669         super(VCLThruHostStackQUIC, self).setUp()
670
671         self.thru_host_stack_setup()
672         self.client_uni_dir_quic_timeout = 20
673         self.server_quic_args = ["-p", "quic", self.server_port]
674         self.client_uni_dir_quic_test_args = [
675             "-N",
676             "1000",
677             "-U",
678             "-X",
679             "-p",
680             "quic",
681             self.loop0.local_ip4,
682             self.server_port,
683         ]
684
685     @unittest.skipUnless(config.extended, "part of extended tests")
686     def test_vcl_thru_host_stack_quic_uni_dir(self):
687         """run VCL thru host stack uni-directional QUIC test"""
688
689         self.timeout = self.client_uni_dir_quic_timeout
690         self.thru_host_stack_test(
691             "vcl_test_server",
692             self.server_quic_args,
693             "vcl_test_client",
694             self.client_uni_dir_quic_test_args,
695         )
696
697     def tearDown(self):
698         self.thru_host_stack_tear_down()
699         super(VCLThruHostStackQUIC, self).tearDown()
700
701     def show_commands_at_teardown(self):
702         self.logger.debug(self.vapi.cli("show app server"))
703         self.logger.debug(self.vapi.cli("show session verbose 2"))
704         self.logger.debug(self.vapi.cli("show app mq"))
705
706
707 class VCLThruHostStackBidirNsock(VCLTestCase):
708     """VCL Thru Host Stack Bidir Nsock"""
709
710     @classmethod
711     def setUpClass(cls):
712         super(VCLThruHostStackBidirNsock, cls).setUpClass()
713
714     @classmethod
715     def tearDownClass(cls):
716         super(VCLThruHostStackBidirNsock, cls).tearDownClass()
717
718     def setUp(self):
719         super(VCLThruHostStackBidirNsock, self).setUp()
720
721         self.thru_host_stack_setup()
722         self.client_bi_dir_nsock_timeout = 20
723         self.client_bi_dir_nsock_test_args = [
724             "-N",
725             "1000",
726             "-B",
727             "-X",
728             "-I",
729             "2",
730             self.loop0.local_ip4,
731             self.server_port,
732         ]
733         self.client_echo_test_args = [
734             "-E",
735             self.echo_phrase,
736             "-X",
737             self.loop0.local_ip4,
738             self.server_port,
739         ]
740
741     def tearDown(self):
742         self.thru_host_stack_tear_down()
743         super(VCLThruHostStackBidirNsock, self).tearDown()
744
745     def show_commands_at_teardown(self):
746         self.logger.debug(self.vapi.cli("show session verbose 2"))
747         self.logger.debug(self.vapi.cli("show app mq"))
748
749     def test_vcl_thru_host_stack_bi_dir_nsock(self):
750         """run VCL thru host stack bi-directional (multiple sockets) test"""
751
752         self.timeout = self.client_bi_dir_nsock_timeout
753         self.thru_host_stack_test(
754             "vcl_test_server",
755             self.server_args,
756             "vcl_test_client",
757             self.client_bi_dir_nsock_test_args,
758         )
759
760
761 class LDPThruHostStackBidirNsock(VCLTestCase):
762     """LDP Thru Host Stack Bidir Nsock"""
763
764     @classmethod
765     def setUpClass(cls):
766         super(LDPThruHostStackBidirNsock, cls).setUpClass()
767
768     @classmethod
769     def tearDownClass(cls):
770         super(LDPThruHostStackBidirNsock, cls).tearDownClass()
771
772     def setUp(self):
773         super(LDPThruHostStackBidirNsock, self).setUp()
774
775         self.thru_host_stack_setup()
776         self.client_bi_dir_nsock_timeout = 20
777         self.client_bi_dir_nsock_test_args = [
778             "-N",
779             "1000",
780             "-B",
781             "-X",
782             # OUCH! Host Stack Bug?
783             # Only fails when running
784             # 'make test TEST_JOBS=auto'
785             # or TEST_JOBS > 1
786             # "-I", "2",
787             self.loop0.local_ip4,
788             self.server_port,
789         ]
790
791     def tearDown(self):
792         self.thru_host_stack_tear_down()
793         super(LDPThruHostStackBidirNsock, self).tearDown()
794
795     def show_commands_at_teardown(self):
796         self.logger.debug(self.vapi.cli("show session verbose 2"))
797         self.logger.debug(self.vapi.cli("show app mq"))
798
799     def test_ldp_thru_host_stack_bi_dir_nsock(self):
800         """run LDP thru host stack bi-directional (multiple sockets) test"""
801
802         self.timeout = self.client_bi_dir_nsock_timeout
803         self.thru_host_stack_test(
804             "sock_test_server",
805             self.server_args,
806             "sock_test_client",
807             self.client_bi_dir_nsock_test_args,
808         )
809
810
811 class LDPThruHostStackNsock(VCLTestCase):
812     """LDP Thru Host Stack Nsock"""
813
814     @classmethod
815     def setUpClass(cls):
816         super(LDPThruHostStackNsock, cls).setUpClass()
817
818     @classmethod
819     def tearDownClass(cls):
820         super(LDPThruHostStackNsock, cls).tearDownClass()
821
822     def setUp(self):
823         super(LDPThruHostStackNsock, self).setUp()
824
825         self.thru_host_stack_setup()
826         if self.vppDebug:
827             self.client_uni_dir_nsock_timeout = 20
828             self.numSockets = "2"
829         else:
830             self.client_uni_dir_nsock_timeout = 20
831             self.numSockets = "5"
832
833         self.client_uni_dir_nsock_test_args = [
834             "-N",
835             "1000",
836             "-U",
837             "-X",
838             "-I",
839             self.numSockets,
840             self.loop0.local_ip4,
841             self.server_port,
842         ]
843
844     def tearDown(self):
845         self.thru_host_stack_tear_down()
846         super(LDPThruHostStackNsock, self).tearDown()
847
848     def test_ldp_thru_host_stack_uni_dir_nsock(self):
849         """run LDP thru host stack uni-directional (multiple sockets) test"""
850
851         self.timeout = self.client_uni_dir_nsock_timeout
852         self.thru_host_stack_test(
853             "sock_test_server",
854             self.server_args,
855             "sock_test_client",
856             self.client_uni_dir_nsock_test_args,
857         )
858
859
860 class VCLThruHostStackNsock(VCLTestCase):
861     """VCL Thru Host Stack Nsock"""
862
863     @classmethod
864     def setUpClass(cls):
865         super(VCLThruHostStackNsock, cls).setUpClass()
866
867     @classmethod
868     def tearDownClass(cls):
869         super(VCLThruHostStackNsock, cls).tearDownClass()
870
871     def setUp(self):
872         super(VCLThruHostStackNsock, self).setUp()
873
874         self.thru_host_stack_setup()
875         if self.vppDebug:
876             self.client_uni_dir_nsock_timeout = 20
877             self.numSockets = "2"
878         else:
879             self.client_uni_dir_nsock_timeout = 20
880             self.numSockets = "5"
881
882         self.client_uni_dir_nsock_test_args = [
883             "-N",
884             "1000",
885             "-U",
886             "-X",
887             "-I",
888             self.numSockets,
889             self.loop0.local_ip4,
890             self.server_port,
891         ]
892
893     def tearDown(self):
894         self.thru_host_stack_tear_down()
895         super(VCLThruHostStackNsock, self).tearDown()
896
897     def test_vcl_thru_host_stack_uni_dir_nsock(self):
898         """run VCL thru host stack uni-directional (multiple sockets) test"""
899
900         self.timeout = self.client_uni_dir_nsock_timeout
901         self.thru_host_stack_test(
902             "vcl_test_server",
903             self.server_args,
904             "vcl_test_client",
905             self.client_uni_dir_nsock_test_args,
906         )
907
908
909 class LDPThruHostStackIperf(VCLTestCase):
910     """LDP Thru Host Stack Iperf"""
911
912     @classmethod
913     def setUpClass(cls):
914         super(LDPThruHostStackIperf, cls).setUpClass()
915
916     @classmethod
917     def tearDownClass(cls):
918         super(LDPThruHostStackIperf, cls).tearDownClass()
919
920     def setUp(self):
921         super(LDPThruHostStackIperf, self).setUp()
922
923         self.thru_host_stack_setup()
924         self.client_iperf3_timeout = 20
925         self.client_iperf3_args = ["-4", "-t 2", "-c", self.loop0.local_ip4]
926         self.server_iperf3_args = ["-4", "-s"]
927
928     def tearDown(self):
929         self.thru_host_stack_tear_down()
930         super(LDPThruHostStackIperf, self).tearDown()
931
932     def show_commands_at_teardown(self):
933         self.logger.debug(self.vapi.cli("show session verbose 2"))
934         self.logger.debug(self.vapi.cli("show app mq"))
935
936     @unittest.skipUnless(_have_iperf3, "'%s' not found, Skipping.")
937     def test_ldp_thru_host_stack_iperf3(self):
938         """run LDP thru host stack iperf3 test"""
939
940         self.timeout = self.client_iperf3_timeout
941         self.thru_host_stack_test(
942             iperf3, self.server_iperf3_args, iperf3, self.client_iperf3_args
943         )
944
945     @unittest.skipUnless(_have_iperf3, "'%s' not found, Skipping.")
946     def test_ldp_thru_host_stack_iperf3_mss(self):
947         """run LDP thru host stack iperf3 test with mss option"""
948
949         self.timeout = self.client_iperf3_timeout
950         self.client_iperf3_args.append("-M 1000")
951         self.thru_host_stack_test(
952             iperf3, self.server_iperf3_args, iperf3, self.client_iperf3_args
953         )
954
955
956 class LDPThruHostStackIperfUdp(VCLTestCase):
957     """LDP Thru Host Stack Iperf UDP"""
958
959     @classmethod
960     def setUpClass(cls):
961         super(LDPThruHostStackIperfUdp, cls).setUpClass()
962
963     @classmethod
964     def tearDownClass(cls):
965         super(LDPThruHostStackIperfUdp, cls).tearDownClass()
966
967     def setUp(self):
968         super(LDPThruHostStackIperfUdp, self).setUp()
969
970         self.thru_host_stack_setup()
971         self.client_iperf3_timeout = 20
972         self.client_iperf3_args = [
973             "-4",
974             "-t 2",
975             "-u",
976             "-l 1400",
977             "-c",
978             self.loop0.local_ip4,
979         ]
980         self.server_iperf3_args = ["-4", "-s"]
981
982     def tearDown(self):
983         self.thru_host_stack_tear_down()
984         super(LDPThruHostStackIperfUdp, self).tearDown()
985
986     def show_commands_at_teardown(self):
987         self.logger.debug(self.vapi.cli("show session verbose 2"))
988         self.logger.debug(self.vapi.cli("show app mq"))
989
990     @unittest.skipUnless(_have_iperf3, "'%s' not found, Skipping.")
991     def test_ldp_thru_host_stack_iperf3_udp(self):
992         """run LDP thru host stack iperf3 UDP test"""
993
994         self.timeout = self.client_iperf3_timeout
995         self.thru_host_stack_test(
996             iperf3, self.server_iperf3_args, iperf3, self.client_iperf3_args
997         )
998
999
1000 class LDPIpv6CutThruTestCase(VCLTestCase):
1001     """LDP IPv6 Cut Thru Tests"""
1002
1003     @classmethod
1004     def setUpClass(cls):
1005         super(LDPIpv6CutThruTestCase, cls).setUpClass()
1006
1007     @classmethod
1008     def tearDownClass(cls):
1009         super(LDPIpv6CutThruTestCase, cls).tearDownClass()
1010
1011     def show_commands_at_teardown(self):
1012         self.logger.debug(self.vapi.cli("show session verbose 2"))
1013         self.logger.debug(self.vapi.cli("show app mq"))
1014
1015     def setUp(self):
1016         super(LDPIpv6CutThruTestCase, self).setUp()
1017
1018         self.cut_thru_setup()
1019         self.client_iperf3_timeout = 20
1020         self.client_uni_dir_nsock_timeout = 20
1021         self.client_bi_dir_nsock_timeout = 20
1022         self.client_ipv6_echo_test_args = [
1023             "-6",
1024             "-E",
1025             self.echo_phrase,
1026             "-X",
1027             self.server_ipv6_addr,
1028             self.server_port,
1029         ]
1030         self.client_ipv6_iperf3_args = ["-6", "-t 2", "-c", self.server_ipv6_addr]
1031         self.server_ipv6_iperf3_args = ["-6", "-s"]
1032         self.client_ipv6_uni_dir_nsock_test_args = [
1033             "-N",
1034             "1000",
1035             "-U",
1036             "-X",
1037             "-6",
1038             "-I",
1039             "2",
1040             self.server_ipv6_addr,
1041             self.server_port,
1042         ]
1043         self.client_ipv6_bi_dir_nsock_test_args = [
1044             "-N",
1045             "1000",
1046             "-B",
1047             "-X",
1048             "-6",
1049             "-I",
1050             "2",
1051             self.server_ipv6_addr,
1052             self.server_port,
1053         ]
1054
1055     def tearDown(self):
1056         super(LDPIpv6CutThruTestCase, self).tearDown()
1057         self.cut_thru_tear_down()
1058
1059     @unittest.skipUnless(config.extended, "part of extended tests")
1060     def test_ldp_ipv6_cut_thru_echo(self):
1061         """run LDP IPv6 cut thru echo test"""
1062
1063         self.cut_thru_test(
1064             "sock_test_server",
1065             self.server_ipv6_args,
1066             "sock_test_client",
1067             self.client_ipv6_echo_test_args,
1068         )
1069
1070     @unittest.skipUnless(_have_iperf3, "'%s' not found, Skipping.")
1071     def test_ldp_ipv6_cut_thru_iperf3(self):
1072         """run LDP IPv6 cut thru iperf3 test"""
1073
1074         self.timeout = self.client_iperf3_timeout
1075         self.cut_thru_test(
1076             iperf3, self.server_ipv6_iperf3_args, iperf3, self.client_ipv6_iperf3_args
1077         )
1078
1079     @unittest.skipUnless(config.extended, "part of extended tests")
1080     def test_ldp_ipv6_cut_thru_uni_dir_nsock(self):
1081         """run LDP IPv6 cut thru uni-directional (multiple sockets) test"""
1082
1083         self.timeout = self.client_uni_dir_nsock_timeout
1084         self.cut_thru_test(
1085             "sock_test_server",
1086             self.server_ipv6_args,
1087             "sock_test_client",
1088             self.client_ipv6_uni_dir_nsock_test_args,
1089         )
1090
1091     @unittest.skipUnless(config.extended, "part of extended tests")
1092     @unittest.skip("sock test apps need to be improved")
1093     def test_ldp_ipv6_cut_thru_bi_dir_nsock(self):
1094         """run LDP IPv6 cut thru bi-directional (multiple sockets) test"""
1095
1096         self.timeout = self.client_bi_dir_nsock_timeout
1097         self.cut_thru_test(
1098             "sock_test_server",
1099             self.server_ipv6_args,
1100             "sock_test_client",
1101             self.client_ipv6_bi_dir_nsock_test_args,
1102         )
1103
1104
1105 class VCLIpv6CutThruTestCase(VCLTestCase):
1106     """VCL IPv6 Cut Thru Tests"""
1107
1108     @classmethod
1109     def setUpClass(cls):
1110         super(VCLIpv6CutThruTestCase, cls).setUpClass()
1111
1112     @classmethod
1113     def tearDownClass(cls):
1114         super(VCLIpv6CutThruTestCase, cls).tearDownClass()
1115
1116     def show_commands_at_teardown(self):
1117         self.logger.debug(self.vapi.cli("show session verbose 2"))
1118         self.logger.debug(self.vapi.cli("show app mq"))
1119
1120     def setUp(self):
1121         super(VCLIpv6CutThruTestCase, self).setUp()
1122
1123         self.cut_thru_setup()
1124         self.client_uni_dir_nsock_timeout = 20
1125         self.client_bi_dir_nsock_timeout = 20
1126         self.client_ipv6_echo_test_args = [
1127             "-6",
1128             "-E",
1129             self.echo_phrase,
1130             "-X",
1131             self.server_ipv6_addr,
1132             self.server_port,
1133         ]
1134         self.client_ipv6_uni_dir_nsock_test_args = [
1135             "-N",
1136             "1000",
1137             "-U",
1138             "-X",
1139             "-6",
1140             "-I",
1141             "2",
1142             self.server_ipv6_addr,
1143             self.server_port,
1144         ]
1145         self.client_ipv6_bi_dir_nsock_test_args = [
1146             "-N",
1147             "1000",
1148             "-B",
1149             "-X",
1150             "-6",
1151             "-I",
1152             "2",
1153             self.server_ipv6_addr,
1154             self.server_port,
1155         ]
1156
1157     def tearDown(self):
1158         super(VCLIpv6CutThruTestCase, self).tearDown()
1159         self.cut_thru_tear_down()
1160
1161     def show_commands_at_teardown(self):
1162         self.logger.debug(self.vapi.cli("show session verbose 2"))
1163         self.logger.debug(self.vapi.cli("show app mq"))
1164
1165     def test_vcl_ipv6_cut_thru_echo(self):
1166         """run VCL IPv6 cut thru echo test"""
1167
1168         self.cut_thru_test(
1169             "vcl_test_server",
1170             self.server_ipv6_args,
1171             "vcl_test_client",
1172             self.client_ipv6_echo_test_args,
1173         )
1174
1175     @unittest.skipUnless(config.extended, "part of extended tests")
1176     def test_vcl_ipv6_cut_thru_uni_dir_nsock(self):
1177         """run VCL IPv6 cut thru uni-directional (multiple sockets) test"""
1178
1179         self.timeout = self.client_uni_dir_nsock_timeout
1180         self.cut_thru_test(
1181             "vcl_test_server",
1182             self.server_ipv6_args,
1183             "vcl_test_client",
1184             self.client_ipv6_uni_dir_nsock_test_args,
1185         )
1186
1187     @unittest.skipUnless(config.extended, "part of extended tests")
1188     def test_vcl_ipv6_cut_thru_bi_dir_nsock(self):
1189         """run VCL IPv6 cut thru bi-directional (multiple sockets) test"""
1190
1191         self.timeout = self.client_bi_dir_nsock_timeout
1192         self.cut_thru_test(
1193             "vcl_test_server",
1194             self.server_ipv6_args,
1195             "vcl_test_client",
1196             self.client_ipv6_bi_dir_nsock_test_args,
1197         )
1198
1199
1200 class VCLIpv6ThruHostStackEcho(VCLTestCase):
1201     """VCL IPv6 Thru Host Stack Echo"""
1202
1203     @classmethod
1204     def setUpClass(cls):
1205         super(VCLIpv6ThruHostStackEcho, cls).setUpClass()
1206
1207     @classmethod
1208     def tearDownClass(cls):
1209         super(VCLIpv6ThruHostStackEcho, cls).tearDownClass()
1210
1211     def setUp(self):
1212         super(VCLIpv6ThruHostStackEcho, self).setUp()
1213
1214         self.thru_host_stack_ipv6_setup()
1215         self.client_ipv6_echo_test_args = [
1216             "-6",
1217             "-E",
1218             self.echo_phrase,
1219             "-X",
1220             self.loop0.local_ip6,
1221             self.server_port,
1222         ]
1223
1224     def tearDown(self):
1225         self.thru_host_stack_ipv6_tear_down()
1226         super(VCLIpv6ThruHostStackEcho, self).tearDown()
1227
1228     def test_vcl_ipv6_thru_host_stack_echo(self):
1229         """run VCL IPv6 thru host stack echo test"""
1230
1231         self.thru_host_stack_test(
1232             "vcl_test_server",
1233             self.server_ipv6_args,
1234             "vcl_test_client",
1235             self.client_ipv6_echo_test_args,
1236         )
1237
1238
1239 if __name__ == "__main__":
1240     unittest.main(testRunner=VppTestRunner)