Skip to content

Commit

Permalink
Refactor and add gateway listener tests
Browse files Browse the repository at this point in the history
Signed-off-by: Alex Zgabur <[email protected]>
  • Loading branch information
azgabur committed Sep 17, 2024
1 parent 44db6b7 commit 15744b6
Show file tree
Hide file tree
Showing 6 changed files with 164 additions and 1 deletion.
12 changes: 11 additions & 1 deletion testsuite/gateway/gateway_api/gateway.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""Module containing all gateway classes"""

from typing import Any
from typing import Any, Optional

import openshift_client as oc

Expand Down Expand Up @@ -46,6 +46,16 @@ def remove_listener(self, hostname: GatewayListener | str):
hostname = hostname.hostname
self.model.spec.listeners = list(filter(lambda i: i["hostname"] != hostname, self.model.spec.listeners))

def get_listener_dns_ttl(self, hostname: Optional[str] = None) -> int:
"""Returns TTL stored in DNSRecord CR under the default hostname or specific hostname if argument is defined."""
listener_name = "api"
if hostname:
listener_name = [i for i in self.model.spec.listeners if i["hostname"] == hostname][0]["name"]
dns_record = self.cluster.do_action(
"get", ["-o", "yaml", f"dnsrecords.kuadrant.io/{self.name()}-{listener_name}"], parse_output=True
)
return dns_record.model.spec.endpoints[0].recordTTL

@property
def service_name(self) -> str:
return f"{self.name()}-istio"
Expand Down
1 change: 1 addition & 0 deletions testsuite/httpx/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ def should_backoff(self):
or (self.error is None and self.status_code in self.retry_codes)
or self.has_error("Server disconnected without sending a response.")
or self.has_error("timed out")
or self.has_error("SSL: UNEXPECTED_EOF_WHILE_READING")
)

def has_error(self, error_msg: str) -> bool:
Expand Down
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
"""
Conftest for Gateway listeners tests.
The main change consists of replacing the default wildcard domain for an exact one.
"""

import pytest

from testsuite.gateway.gateway_api.hostname import StaticHostname


@pytest.fixture(scope="module")
def domain_prefix():
"""Prefix of default domain."""
return "prefix"


@pytest.fixture(scope="module")
def wildcard_domain(base_domain, domain_prefix, blame):
"""
For these tests we want specific default domain, not wildcard.
"""
return f'{blame(domain_prefix + "1")}.{base_domain}'


@pytest.fixture(scope="module")
def second_domain(base_domain, domain_prefix, blame):
"""Second domain string, not used in any object yet. To be assigned inside test."""
return f'{blame(domain_prefix + "2")}.{base_domain}'


@pytest.fixture(scope="module")
def custom_client(gateway):
"""
While changing TLS listeners the TLS certificate changes so a new client needs to be generated
to fetch newest tls cert from cluster.
"""

def _client_new(hostname: str):
return StaticHostname(hostname, gateway.get_tls_cert).client()

return _client_new


@pytest.fixture(scope="module")
def check_ok_https(custom_client, auth):
"""
Assert that HTTPS connection to domain works and returns 200. Authorization is used.
Assert that no DNS and TLS errors happened.
"""

def _check_ok_https(domain: str):
response = custom_client(domain).get("/get", auth=auth)
assert not response.has_dns_error()
assert not response.has_cert_verify_error()
assert response.status_code == 200

return _check_ok_https


@pytest.fixture(scope="module")
def route(route, wildcard_domain):
"""Ensure that route hostname matches the gateway hostname."""
route.remove_all_hostnames()
route.add_hostname(wildcard_domain)
return route
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
"""
Test case:
- Add new listener and add it to HTTPRoute and test both work
- Remove the new listener and remove it from HTTPRoute and test removed one is not working
"""

from time import sleep
import pytest

from testsuite.gateway import GatewayListenerTls
from testsuite.utils import is_nxdomain


pytestmark = [pytest.mark.kuadrant_only, pytest.mark.dnspolicy, pytest.mark.tlspolicy]


@pytest.fixture(scope="module")
def domain_prefix():
"""Prefix for this test"""
return "listen"


def test_listeners(custom_client, check_ok_https, gateway, route, wildcard_domain, second_domain):
"""
This test checks reconciliation of dns/tls policy on addition and removal of listeners in gateway and HTTPRoute.
"""

# Check the default domain works and second domain does not exist yet
check_ok_https(wildcard_domain)
assert is_nxdomain(second_domain)
assert custom_client(second_domain).get("/get").has_dns_error()

# Add second domain to gateway and route
gateway.add_listener(GatewayListenerTls(hostname=second_domain, gateway_name=gateway.name()))
route.add_hostname(second_domain)

# Check both domains work
for domain in [wildcard_domain, second_domain]:
check_ok_https(domain)

# Remove second domain, store TTL value of to be removed DNS record
second_domain_ttl = gateway.get_listener_dns_ttl(second_domain)
route.remove_hostname(second_domain)
gateway.remove_listener(second_domain)

# Check the default domain still works and second domain does not exist anymore
check_ok_https(wildcard_domain)
sleep(second_domain_ttl)
assert is_nxdomain(second_domain)
assert custom_client(second_domain).get("/get").has_dns_error()
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
"""Testing specific bug that happens when listener hostname in Gateway gets changed while DNSPolicy is applied."""

from time import sleep
import pytest

from testsuite.gateway import GatewayListenerTls
from testsuite.utils import is_nxdomain

pytestmark = [pytest.mark.kuadrant_only, pytest.mark.dnspolicy, pytest.mark.tlspolicy]


@pytest.fixture(scope="module")
def domain_prefix():
"""Prefix for this test"""
return "dnsbug"


@pytest.mark.issue("https://github.com/Kuadrant/kuadrant-operator/issues/794")
def test_change_listener(custom_client, check_ok_https, gateway, route, second_domain, wildcard_domain):
"""
This test checks if after change of listener hostname in a Gateway while having DNSPolicy applied, that
the old hostname gets deleted from DNS provider. After editing the hostname in HTTPRoute to the new value
this test checks the reconciliation of such procedure.
"""
check_ok_https(wildcard_domain)
wildcard_domain_ttl = gateway.get_listener_dns_ttl(wildcard_domain)

gateway.remove_listener(wildcard_domain)
gateway.add_listener(GatewayListenerTls(hostname=second_domain, gateway_name=gateway.name(), name="api"))
route.remove_hostname(wildcard_domain)
route.add_hostname(second_domain)

check_ok_https(second_domain)

sleep(wildcard_domain_ttl)
assert is_nxdomain(wildcard_domain)
assert custom_client(wildcard_domain).get("/get").has_dns_error()

0 comments on commit 15744b6

Please sign in to comment.