diff --git a/kuryr_tempest_plugin/config.py b/kuryr_tempest_plugin/config.py index 00cdd52d..8fe29470 100644 --- a/kuryr_tempest_plugin/config.py +++ b/kuryr_tempest_plugin/config.py @@ -67,6 +67,8 @@ kuryr_k8s_opts = [ "Pods"), cfg.BoolOpt("test_udp_services", default=False, help="Whether or not service UDP tests will be running"), + cfg.BoolOpt("test_sctp_services", default=False, + help="Whether or not service SCTP tests will be running"), cfg.BoolOpt("multi_worker_setup", default=False, help="Whether or not we " "have a multi-worker setup"), cfg.BoolOpt("cloud_provider", default=False, help="Whether or not a " diff --git a/kuryr_tempest_plugin/tests/scenario/base.py b/kuryr_tempest_plugin/tests/scenario/base.py index b967e8eb..c76672fb 100644 --- a/kuryr_tempest_plugin/tests/scenario/base.py +++ b/kuryr_tempest_plugin/tests/scenario/base.py @@ -633,8 +633,13 @@ class BaseKuryrScenarioTest(manager.NetworkScenarioTest): label = label or data_utils.rand_name('kuryr-app') for i in range(pod_num): - pod_name, pod = cls.create_pod( - labels={"app": label}, namespace=namespace) + if protocol == "SCTP": + pod_name, pod = cls.create_pod( + labels={"app": label}, image='quay.io/kuryr/sctp-demo', + namespace=namespace) + else: + pod_name, pod = cls.create_pod( + labels={"app": label}, namespace=namespace) if cleanup: cls.addClassResourceCleanup(cls.delete_pod, pod_name, namespace=namespace) @@ -956,6 +961,20 @@ class BaseKuryrScenarioTest(manager.NetworkScenarioTest): return return stdout + def req_sctp(): + cmd = "python3 sctp_client.py {} {}".format( + server_ip, server_port) + pod_cmd = ["/bin/sh", "-c", cmd] + stdout, stderr = self.exec_command_in_pod(pod, pod_cmd, + namespace=namespace_name, + stderr=True) + if stderr: + LOG.error('Failed to reach service at {}:{} ' + 'Err: {}'.format(server_ip, server_port, stderr)) + time.sleep(10) + return + return stdout + def pred(tester, responses): if protocol == 'TCP': unique_resps = set(resp for resp in responses if resp) @@ -972,6 +991,10 @@ class BaseKuryrScenarioTest(manager.NetworkScenarioTest): self.assertIsNotNone(server_port, "server_port must be " "provided for UDP protocol") req = req_udp + elif protocol == "SCTP": + self.assertIsNotNone(server_port, "server_port must be " + "provided for SCTP protocol") + req = req_sctp else: LOG.info("Unsupported protocol %s, returning", protocol) return @@ -1322,7 +1345,13 @@ class BaseKuryrScenarioTest(manager.NetworkScenarioTest): namespace=namespace) pod_num = pod_num or self.pod_num if not pod_name: - pod_name, _ = self.create_pod(namespace=namespace, labels=labels) + if protocol == "SCTP": + pod_name, _ = self.create_pod( + labels=labels, image='quay.io/kuryr/sctp-demo', + namespace=namespace) + else: + pod_name, _ = self.create_pod( + namespace=namespace, labels=labels) if cleanup: self.addClassResourceCleanup(self.delete_pod, pod_name, namespace=namespace) diff --git a/kuryr_tempest_plugin/tests/scenario/test_service.py b/kuryr_tempest_plugin/tests/scenario/test_service.py index abaa0d57..68e4baba 100644 --- a/kuryr_tempest_plugin/tests/scenario/test_service.py +++ b/kuryr_tempest_plugin/tests/scenario/test_service.py @@ -136,3 +136,22 @@ class TestServiceWithoutSelectorScenario(base.BaseKuryrScenarioTest): self.service_without_selector_base(namespace=ns_name) self.check_service_internal_connectivity(namespace=ns_name) + + +class TestSCTPServiceScenario(base.BaseKuryrScenarioTest): + + @classmethod + def skip_checks(cls): + super(TestSCTPServiceScenario, cls).skip_checks() + if not CONF.kuryr_kubernetes.service_tests_enabled: + raise cls.skipException("Service tests are not enabled") + if not CONF.kuryr_kubernetes.test_sctp_services: + raise cls.skipException("Service SCTP tests are not enabled") + + @decorators.idempotent_id('bb8cc977-c867-4766-b623-137d8395cb60') + def test_service_sctp_ping(self): + self.create_setup_for_service_test( + protocol="SCTP", port=90, target_port=9090) + + self.check_service_internal_connectivity( + service_port='90', protocol='SCTP') diff --git a/test_container/kuryr_sctp_demo/sctp_client.py b/test_container/kuryr_sctp_demo/sctp_client.py index b81f2aa0..bd7600bf 100644 --- a/test_container/kuryr_sctp_demo/sctp_client.py +++ b/test_container/kuryr_sctp_demo/sctp_client.py @@ -15,17 +15,31 @@ import sys import sctp -sk = sctp.sctpsocket_tcp(socket.AF_INET) - def connect_plus_message(out_ip, out_port): - sk.connect((out_ip, out_port)) - print("Sending Message") - sk.sctp_send(msg='HELLO, I AM ALIVE!!!') - msgFromServer = sk.recvfrom(1024) - print(msgFromServer[0].decode('utf-8')) - sk.shutdown(0) - sk.close() + for res in socket.getaddrinfo(out_ip, out_port, socket.AF_UNSPEC, + socket.SOCK_STREAM, 0, socket.AI_PASSIVE): + addr_fam, socktype, proto, canonname, sa = res + try: + sock = sctp.sctpsocket_tcp(addr_fam) + except OSError: + sock = None + continue + try: + sock.connect(sa) + except OSError: + sock.close() + sock = None + continue + break + + if sock: + print("Sending Message") + sock.sctp_send(msg='HELLO, I AM ALIVE!!!') + msg_from_server = sock.recvfrom(1024) + print(msg_from_server[0].decode('utf-8')) + sock.shutdown(0) + sock.close() if __name__ == '__main__': diff --git a/test_container/kuryr_sctp_demo/sctp_server.py b/test_container/kuryr_sctp_demo/sctp_server.py index 79d6e6a2..2d8d3c0a 100644 --- a/test_container/kuryr_sctp_demo/sctp_server.py +++ b/test_container/kuryr_sctp_demo/sctp_server.py @@ -11,14 +11,16 @@ # limitations under the License. import platform -import sctp import socket +import sctp -host = '0.0.0.0' + +host = '::' port = 9090 -sock = sctp.sctpsocket_tcp(socket.AF_INET) +sock = sctp.sctpsocket_tcp(socket.AF_INET6) +sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 0) sock.bind((host, port)) sock.listen(1)