Skip to content

Commit

Permalink
Merge pull request #490 from averevki/defaults-tests
Browse files Browse the repository at this point in the history
Add tests for Defaults
  • Loading branch information
averevki committed Aug 1, 2024
2 parents d9cf272 + fd37511 commit 98c5cfb
Show file tree
Hide file tree
Showing 7 changed files with 154 additions and 8 deletions.
28 changes: 24 additions & 4 deletions testsuite/kuadrant/policy/authorization/auth_policy.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@
class AuthPolicy(Policy, AuthConfig):
"""AuthPolicy object, it serves as Kuadrants AuthConfig"""

@property
def auth_section(self):
return self.model.spec.setdefault("rules", {})
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.spec_section = None

@classmethod
def create_instance(
Expand All @@ -35,7 +35,6 @@ def create_instance(
"metadata": {"name": name, "namespace": cluster.project, "labels": labels},
"spec": {
"targetRef": target.reference,
"rules": {},
},
}

Expand All @@ -46,3 +45,24 @@ def add_rule(self, when: list["Rule"]):
"""Add rule for the skip of entire AuthPolicy"""
self.model.spec.setdefault("when", [])
self.model.spec["when"].extend([asdict(x) for x in when])

@property
def auth_section(self):
if self.spec_section is None:
self.spec_section = self.model.spec

spec_section = self.spec_section
self.spec_section = None
return spec_section.setdefault("rules", {})

@property
def defaults(self):
"""Add new rule into the `defaults` AuthPolicy section"""
self.spec_section = self.model.spec.setdefault("defaults", {})
return self

@property
def overrides(self):
"""Add new rule into the `overrides` AuthPolicy section"""
self.spec_section = self.model.spec.setdefault("overrides", {})
return self
24 changes: 22 additions & 2 deletions testsuite/kuadrant/policy/rate_limit.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ def __init__(self, *matches: RouteMatch, hostnames: Optional[List[str]] = None):
class RateLimitPolicy(Policy):
"""RateLimitPolicy (or RLP for short) object, used for applying rate limiting rules to a Gateway/HTTPRoute"""

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.spec_section = None

@classmethod
def create_instance(cls, cluster: KubernetesClient, name, target: Referencable, labels: dict[str, str] = None):
"""Creates new instance of RateLimitPolicy"""
Expand All @@ -50,7 +54,6 @@ def create_instance(cls, cluster: KubernetesClient, name, target: Referencable,
"metadata": {"name": name, "labels": labels},
"spec": {
"targetRef": target.reference,
"limits": {},
},
}

Expand All @@ -75,7 +78,24 @@ def add_limit(
limit["counters"] = counters
if route_selectors:
limit["routeSelectors"] = [asdict(rule) for rule in route_selectors]
self.model.spec.limits[name] = limit

if self.spec_section is None:
self.spec_section = self.model.spec

self.spec_section.setdefault("limits", {})[name] = limit
self.spec_section = None

@property
def defaults(self):
"""Add new rule into the `defaults` RateLimitPolicy section"""
self.spec_section = self.model.spec.setdefault("defaults", {})
return self

@property
def overrides(self):
"""Add new rule into the `overrides` RateLimitPolicy section"""
self.spec_section = self.model.spec.setdefault("overrides", {})
return self

def wait_for_ready(self):
"""Wait for RLP to be enforced"""
Expand Down
6 changes: 4 additions & 2 deletions testsuite/tests/singlecluster/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,12 @@ def authorization_name(blame):


@pytest.fixture(scope="module")
def authorization(kuadrant, route, authorization_name, cluster, label):
def authorization(request, kuadrant, route, gateway, blame, cluster, label): # pylint: disable=unused-argument
"""Authorization object (In case of Kuadrant AuthPolicy)"""
target_ref = request.getfixturevalue(getattr(request, "param", "route"))

if kuadrant:
return AuthPolicy.create_instance(cluster, authorization_name, route, labels={"testRun": label})
return AuthPolicy.create_instance(cluster, blame("authz"), target_ref, labels={"testRun": label})
return None


Expand Down
Empty file.
36 changes: 36 additions & 0 deletions testsuite/tests/singlecluster/defaults/test_basic_authorization.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
"""Test basic enforcement of the rules inside the 'defaults' block of the AuthPolicy"""

import pytest

from testsuite.httpx.auth import HttpxOidcClientAuth

pytestmark = [pytest.mark.kuadrant_only]


@pytest.fixture(scope="module")
def authorization(authorization, oidc_provider):
"""Add oidc identity to defaults block of AuthPolicy"""
authorization.defaults.identity.add_oidc("default", oidc_provider.well_known["issuer"])
return authorization


@pytest.fixture(scope="module")
def auth(oidc_provider):
"""Returns Authentication object for HTTPX"""
return HttpxOidcClientAuth(oidc_provider.get_token, "authorization")


@pytest.fixture(scope="module")
def rate_limit():
"""No RateLimitPolicy is required for this test"""
return None


@pytest.mark.parametrize("authorization", ["route", "gateway"], indirect=True)
def test_basic_authorization(authorization, route, client, auth):
"""Test that default identity is applied successfully and shows affected status in the route"""
route.refresh()
assert route.is_affected_by(authorization)

assert client.get("/get").status_code == 401
assert client.get("/get", auth=auth).status_code == 200 # assert that AuthPolicy is enforced
33 changes: 33 additions & 0 deletions testsuite/tests/singlecluster/defaults/test_basic_rate_limit.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
"""Test basic enforcement of the rules inside the 'defaults' block of the RateLimitPolicy"""

import pytest

from testsuite.kuadrant.policy.rate_limit import Limit

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

LIMIT = Limit(3, 5)


@pytest.fixture(scope="module")
def authorization():
"""No authorization is required for this test"""
return None


@pytest.fixture(scope="module")
def rate_limit(rate_limit):
"""Add basic requests limit to defaults block of RateLimitPolicy"""
rate_limit.defaults.add_limit("basic", [LIMIT])
return rate_limit


@pytest.mark.parametrize("rate_limit", ["route", "gateway"], indirect=True)
def test_basic_rate_limit(rate_limit, route, client):
"""Test that default rate limit is applied successfully and shows affected status in the route"""
route.refresh()
assert route.is_affected_by(rate_limit)

responses = client.get_many("/get", LIMIT.limit)
responses.assert_all(status_code=200)
assert client.get("/get").status_code == 429 # assert that RateLimitPolicy is enforced
35 changes: 35 additions & 0 deletions testsuite/tests/singlecluster/defaults/test_rules_exclusivity.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
"""Test mutual exclusivity of defaults block and implicit defaults"""

import pytest
from openshift_client import OpenShiftPythonException

from testsuite.kuadrant.policy.authorization.auth_policy import AuthPolicy
from testsuite.kuadrant.policy.rate_limit import RateLimitPolicy, Limit

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


@pytest.fixture(scope="module")
def commit():
"""We need to try to commit objects during the actual test"""
return None


def test_rules_exclusivity_authorization(cluster, route, oidc_provider, module_label, blame):
"""Test that server will reject object with implicit and explicit defaults defined simultaneously in AuthPolicy"""
authorization = AuthPolicy.create_instance(cluster, blame("authz"), route, labels={"testRun": module_label})
authorization.defaults.identity.add_oidc("inside-defaults", oidc_provider.well_known["issuer"])
authorization.identity.add_oidc("outside-defaults", oidc_provider.well_known["issuer"])

with pytest.raises(OpenShiftPythonException, match="Implicit and explicit defaults are mutually exclusive"):
authorization.commit()


def test_rules_exclusivity_rate_limit(cluster, route, module_label, blame):
"""Test that server will reject object with implicit and explicit defaults simultaneously in RateLimitPolicy"""
rate_limit = RateLimitPolicy.create_instance(cluster, blame("limit"), route, labels={"testRun": module_label})
rate_limit.defaults.add_limit("inside-defaults", [Limit(2, 5)])
rate_limit.add_limit("outside-defaults", [Limit(2, 5)])

with pytest.raises(OpenShiftPythonException, match="Implicit and explicit defaults are mutually exclusive"):
rate_limit.commit()

0 comments on commit 98c5cfb

Please sign in to comment.