Skip to content

Commit

Permalink
Add DNSPolicy health check tests
Browse files Browse the repository at this point in the history
Signed-off-by: averevki <[email protected]>
  • Loading branch information
averevki committed Nov 18, 2024
1 parent 3ff0175 commit 98bfe91
Show file tree
Hide file tree
Showing 7 changed files with 253 additions and 1 deletion.
40 changes: 39 additions & 1 deletion testsuite/kuadrant/policy/dns.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
"""Module for DNSPolicy related classes"""

from dataclasses import dataclass
from typing import Optional
from typing import Optional, Literal

from testsuite.gateway import Referencable
from testsuite.kubernetes import KubernetesObject
from testsuite.kubernetes.client import KubernetesClient
from testsuite.kuadrant.policy import Policy
from testsuite.utils import asdict, check_condition
Expand Down Expand Up @@ -31,6 +32,33 @@ class LoadBalancing:
weight: Optional[int] = None


@dataclass
class AdditionalHeadersRef:
"""Object representing DNSPolicy additionalHeadersRef field"""

name: str


@dataclass
class HealthCheck: # pylint: disable=invalid-name
"""Object representing DNSPolicy health check specification"""

additionalHeadersRef: Optional[AdditionalHeadersRef] = None
path: Optional[str] = None
failureThreshold: Optional[int] = None
interval: Optional[str] = None
port: Optional[int] = None
protocol: Literal["HTTP", "HTTPS"] = "HTTP"


class DNSHealthCheckProbe(KubernetesObject):
"""DNSHealthCheckProbe object"""

def is_healthy(self) -> bool:
"""Returns True if DNSHealthCheckProbe endpoint is healthy"""
return self.refresh().model.status.healthy


class DNSPolicy(Policy):
"""DNSPolicy object"""

Expand Down Expand Up @@ -61,6 +89,16 @@ def create_instance(

return cls(model, context=cluster.context)

def set_health_check(self, health_check: HealthCheck):
"""Sets health check for DNSPolicy"""
self.model["spec"]["healthCheck"] = asdict(health_check)

def get_dns_health_probe(self) -> DNSHealthCheckProbe:
"""Returns DNSHealthCheckProbe object for the created DNSPolicy"""
with self.context:
dns_probe = self.get_owned("dnsrecords.kuadrant.io")[0].get_owned("DNSHealthCheckProbe")[0]
return DNSHealthCheckProbe(dns_probe.model, context=self.context)

def wait_for_full_enforced(self, timelimit=300):
"""Wait for a Policy to be fully Enforced with increased timelimit for DNSPolicy"""
super().wait_for_full_enforced(timelimit=timelimit)
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
"""Conftest for DNSPolicy health checks"""

import pytest

from testsuite.gateway import Hostname, TLSGatewayListener
from testsuite.gateway.gateway_api.gateway import KuadrantGateway


@pytest.fixture(scope="module")
def subdomain(blame):
"""Subdomain name that will be added to HTTPRoute"""
return blame("hostname")


@pytest.fixture(scope="module")
def hostname(gateway, exposer, subdomain) -> Hostname:
"""Exposed Hostname object"""
return exposer.expose_hostname(subdomain, gateway)


@pytest.fixture(scope="module")
def gateway(request, cluster, blame, base_domain, module_label, subdomain):
"""Returns ready gateway"""
gateway_name = blame("gw")
gw = KuadrantGateway.create_instance(
cluster,
gateway_name,
{"app": module_label},
)
gw.add_listener(TLSGatewayListener(hostname=f"{subdomain}.{base_domain}", gateway_name=gateway_name))
request.addfinalizer(gw.delete)
gw.commit()
gw.wait_for_ready()
return gw


@pytest.fixture(scope="module")
def dns_policy(dns_policy, health_check):
"""Add health check to DNSPolicy"""
dns_policy.set_health_check(health_check)
return dns_policy


@pytest.fixture(scope="module")
def dns_health_probe(dns_policy):
"""Return DNSHealthCheckProbe object for created DNSPolicy"""
return dns_policy.get_dns_health_probe()


@pytest.fixture(scope="module", autouse=True)
def commit(request, route, tls_policy, dns_policy): # pylint: disable=unused-argument
"""Commits dnspolicy"""
for component in [tls_policy, dns_policy]:
request.addfinalizer(component.delete)
component.commit()
component.wait_for_ready()
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
"""Tests for DNSPolicy health checks - healthy endpoint"""

import pytest

from testsuite.kuadrant.policy.dns import HealthCheck

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


@pytest.fixture(scope="module")
def health_check():
"""Returns healthy endpoint specification for DNSPolicy health check"""
return HealthCheck(
path="/get",
interval="5s",
protocol="HTTPS",
port=443,
)


def test_healthy_endpoint(dns_health_probe, client, auth):
"""Test healthy endpoint check"""
assert dns_health_probe.is_healthy()

response = client.get("/get", auth=auth)
assert response.status_code == 200
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
"""Tests for DNSPolicy health checks with HTTP only endpoint - healthy endpoint"""

import pytest

from testsuite.gateway import GatewayListener
from testsuite.gateway.gateway_api.gateway import KuadrantGateway
from testsuite.kuadrant.policy.dns import HealthCheck

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


@pytest.fixture(scope="module")
def health_check():
"""Returns healthy endpoint specification for DNSPolicy health check"""
return HealthCheck(
path="/get",
interval="5s",
protocol="HTTP",
port=80,
)


@pytest.fixture(scope="module")
def gateway(request, cluster, blame, base_domain, module_label, subdomain):
"""Create gateway without TLS enabled"""
gw = KuadrantGateway.create_instance(cluster, blame("gw"), {"app": module_label})
gw.add_listener(GatewayListener(hostname=f"{subdomain}.{base_domain}"))
request.addfinalizer(gw.delete)
gw.commit()
gw.wait_for_ready()
return gw


@pytest.fixture(scope="module", autouse=True)
def commit(request, route, dns_policy): # pylint: disable=unused-argument
"""Commits dnspolicy only"""
request.addfinalizer(dns_policy.delete)
dns_policy.commit()
dns_policy.wait_for_ready()


def test_healthy_endpoint_http(dns_health_probe, client):
"""Test healthy endpoint check without TLS enabled"""
assert dns_health_probe.is_healthy()

response = client.get("/get")
assert response.status_code == 200
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
"""Tests for DNSPolicy health checks - healthy endpoint"""

import pytest

from testsuite.kuadrant.policy import has_condition
from testsuite.kuadrant.policy.dns import HealthCheck, has_record_condition

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


@pytest.fixture(scope="module")
def health_check():
"""Returns healthy endpoint specification for DNSPolicy health check"""
return HealthCheck(
path="/get",
interval="5s",
protocol="HTTPS",
port=443,
)


def test_remove_endpoint(backend, dns_policy, dns_health_probe, client, auth):
"""Scale backend replicas to 0 and back to 1, and check if DNSPolicy will remove the unhealthy endpoint"""
assert dns_health_probe.is_healthy()
response = client.get("/get", auth=auth)
assert response.status_code == 200

backend.deployment.self_selector().scale(0)
assert dns_policy.wait_until(has_condition("SubResourcesHealthy", "False"), timelimit=120)
assert dns_policy.wait_until(
has_record_condition("Healthy", "False", "HealthChecksFailed", "Not healthy addresses:")
)

assert not dns_health_probe.is_healthy()
response = client.get("/get", auth=auth)
assert response.status_code == 503

backend.deployment.self_selector().scale(1)
assert dns_policy.wait_until(has_condition("SubResourcesHealthy", "True"), timelimit=120)

assert dns_health_probe.is_healthy()
response = client.get("/get", auth=auth)
assert response.status_code == 200
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
"""Tests for DNSPolicy health checks - unhealthy endpoint"""

import pytest

from testsuite.kuadrant.policy import has_condition
from testsuite.kuadrant.policy.dns import HealthCheck, has_record_condition

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


@pytest.fixture(scope="module")
def health_check():
"""Returns unhealthy endpoint specification for DNSPolicy health check"""
return HealthCheck(
path="/unknown-endpoint",
interval="5s",
protocol="HTTPS",
port=443,
)


@pytest.fixture(scope="module", autouse=True)
def commit(request, route, tls_policy, dns_policy): # pylint: disable=unused-argument
"""Commits tlspolicy and dnspolicy without waiting for dnspolicy to be enforced"""
request.addfinalizer(tls_policy.delete)
tls_policy.commit()
tls_policy.wait_for_ready()

request.addfinalizer(dns_policy.delete)
dns_policy.commit()


def test_unhealthy_endpoint(dns_policy, dns_health_probe, client, auth):
"""Test unhealthy endpoint check"""
assert not dns_health_probe.is_healthy()
response = client.get("/get", auth=auth)
assert response.has_dns_error()

assert dns_policy.wait_until(has_condition("Enforced", "False"))
assert dns_policy.wait_until(
has_record_condition("Ready", "False", "HealthChecksFailed", "Not publishing unhealthy records")
)

0 comments on commit 98bfe91

Please sign in to comment.