From 0d1a4f34e3e2b0026670e35a2071cb56661a1f88 Mon Sep 17 00:00:00 2001 From: phala Date: Thu, 23 Nov 2023 13:46:27 +0100 Subject: [PATCH] Reorganize testsuite --- .../__init__.py => certificates.py} | 4 +- .../gateway.py => gateway/__init__.py} | 40 ++++++- .../objects => gateway}/envoy/__init__.py | 4 +- .../objects => gateway}/envoy/config.py | 4 +- .../objects => gateway}/envoy/route.py | 14 ++- .../objects => gateway}/envoy/tls.py | 2 +- .../objects => gateway}/envoy/wristband.py | 2 +- .../gateway_api/__init__.py | 0 .../gateway_api/gateway.py | 4 +- .../gateway_api/hostname.py | 7 +- .../objects => gateway}/gateway_api/route.py | 4 +- testsuite/httpx/auth.py | 2 +- testsuite/lifecycle.py | 16 +++ testsuite/objects/hostname.py | 33 ----- testsuite/oidc/rhsso/__init__.py | 2 +- testsuite/openshift/__init__.py | 54 +++++++++ testsuite/openshift/{objects => }/api_key.py | 4 +- .../openshift/{objects => }/authorino.py | 59 ++++++++- testsuite/openshift/client.py | 4 +- .../openshift/{objects => }/config_map.py | 2 +- testsuite/openshift/httpbin.py | 4 +- testsuite/openshift/{objects => }/ingress.py | 2 +- .../{objects => }/metrics/__init__.py | 0 .../{objects => }/metrics/prometheus.py | 0 .../{objects => }/metrics/service_monitor.py | 4 +- testsuite/openshift/objects/__init__.py | 54 --------- testsuite/openshift/{objects => }/route.py | 4 +- testsuite/openshift/{objects => }/secret.py | 2 +- testsuite/policy/__init__.py | 0 .../authorization}/__init__.py | 113 +----------------- .../authorization/auth_config.py} | 10 +- .../authorization}/auth_policy.py | 17 +-- .../authorization}/sections.py | 16 +-- .../dnspolicy.py => policy/dns_policy.py} | 6 +- .../rate_limit_policy.py} | 7 +- .../tlspolicy.py => policy/tls_policy.py} | 4 +- testsuite/tests/conftest.py | 13 +- .../caching/metadata/test_caching.py | 2 +- .../test_authorization_condition.py | 2 +- .../test_identity_condition.py | 2 +- .../test_metadata_condition.py | 2 +- .../test_response_condition.py | 2 +- .../conditions/test_top_level_condition.py | 2 +- .../tests/kuadrant/authorino/conftest.py | 7 +- .../kuadrant/authorino/dinosaur/conftest.py | 2 +- .../identity/api_key/test_auth_credentials.py | 2 +- .../identity/api_key/test_match_expression.py | 2 +- .../identity/api_key/test_reconciliation.py | 2 +- .../test_extended_properties.py | 2 +- .../extended_properties/test_overwriting.py | 2 +- .../test_token_normalization.py | 2 +- .../identity/rhsso/test_auth_credentials.py | 2 +- .../identity/rhsso/test_rhsso_context.py | 2 +- .../kuadrant/authorino/metadata/conftest.py | 2 +- .../authorino/metadata/test_user_info.py | 2 +- .../kuadrant/authorino/metrics/conftest.py | 4 +- .../authorino/metrics/test_deep_metrics.py | 2 +- .../operator/clusterwide/conftest.py | 2 +- .../clusterwide/test_wildcard_collision.py | 4 +- .../authorino/operator/raw_http/conftest.py | 6 +- .../authorino/operator/sharding/conftest.py | 8 +- .../sharding/test_preexisting_auth.py | 2 +- .../authorino/operator/test_wildcard.py | 2 +- .../authorino/operator/tls/conftest.py | 10 +- .../authorino/operator/tls/mtls/conftest.py | 2 +- .../operator/tls/mtls/test_mtls_attributes.py | 2 +- .../authorino/operator/tls/test_webhook.py | 6 +- .../priority/test_sequence_api_key.py | 2 +- .../authorino/response/test_auth_json.py | 2 +- .../authorino/response/test_base64.py | 2 +- .../authorino/response/test_deny_with.py | 2 +- .../authorino/response/test_headers.py | 2 +- .../response/test_multiple_responses.py | 2 +- .../response/test_simple_response.py | 2 +- .../tests/kuadrant/authorino/test_redirect.py | 2 +- .../kuadrant/authorino/wristband/conftest.py | 10 +- testsuite/tests/kuadrant/conftest.py | 4 +- .../kuadrant/limitador/test_basic_limit.py | 2 +- .../limitador/test_multiple_iterations.py | 2 +- .../tests/kuadrant/test_rate_limit_authz.py | 4 +- testsuite/tests/mgc/conftest.py | 13 +- testsuite/tests/mgc/dnspolicy/conftest.py | 2 +- .../mgc/dnspolicy/health_check/conftest.py | 4 +- .../health_check/test_healthy_endpoint.py | 2 +- .../health_check/test_unhealthy_endpoint.py | 2 +- testsuite/utils.py | 40 +++++++ 86 files changed, 357 insertions(+), 352 deletions(-) rename testsuite/{certificates/__init__.py => certificates.py} (99%) rename testsuite/{objects/gateway.py => gateway/__init__.py} (71%) rename testsuite/{openshift/objects => gateway}/envoy/__init__.py (96%) rename testsuite/{openshift/objects => gateway}/envoy/config.py (97%) rename testsuite/{openshift/objects => gateway}/envoy/route.py (84%) rename testsuite/{openshift/objects => gateway}/envoy/tls.py (97%) rename testsuite/{openshift/objects => gateway}/envoy/wristband.py (94%) rename testsuite/{openshift/objects => gateway}/gateway_api/__init__.py (100%) rename testsuite/{openshift/objects => gateway}/gateway_api/gateway.py (98%) rename testsuite/{openshift/objects => gateway}/gateway_api/hostname.py (90%) rename testsuite/{openshift/objects => gateway}/gateway_api/route.py (95%) create mode 100644 testsuite/lifecycle.py delete mode 100644 testsuite/objects/hostname.py rename testsuite/openshift/{objects => }/api_key.py (93%) rename testsuite/openshift/{objects => }/authorino.py (66%) rename testsuite/openshift/{objects => }/config_map.py (93%) rename testsuite/openshift/{objects => }/ingress.py (97%) rename testsuite/openshift/{objects => }/metrics/__init__.py (100%) rename testsuite/openshift/{objects => }/metrics/prometheus.py (100%) rename testsuite/openshift/{objects => }/metrics/service_monitor.py (93%) delete mode 100644 testsuite/openshift/objects/__init__.py rename testsuite/openshift/{objects => }/route.py (92%) rename testsuite/openshift/{objects => }/secret.py (96%) create mode 100644 testsuite/policy/__init__.py rename testsuite/{objects => policy/authorization}/__init__.py (58%) rename testsuite/{openshift/objects/auth_config/__init__.py => policy/authorization/auth_config.py} (88%) rename testsuite/{openshift/objects/auth_config => policy/authorization}/auth_policy.py (75%) rename testsuite/{openshift/objects/auth_config => policy/authorization}/sections.py (98%) rename testsuite/{openshift/objects/dnspolicy.py => policy/dns_policy.py} (93%) rename testsuite/{openshift/objects/rate_limit.py => policy/rate_limit_policy.py} (91%) rename testsuite/{openshift/objects/tlspolicy.py => policy/tls_policy.py} (92%) diff --git a/testsuite/certificates/__init__.py b/testsuite/certificates.py similarity index 99% rename from testsuite/certificates/__init__.py rename to testsuite/certificates.py index 7e39c990..8cac1aec 100644 --- a/testsuite/certificates/__init__.py +++ b/testsuite/certificates.py @@ -1,12 +1,12 @@ """Module containing classes for working with TLS certificates""" -import datetime import dataclasses +import datetime import json import shutil import subprocess from functools import cached_property from importlib import resources -from typing import Optional, List, Dict, Any, Tuple, Collection, Union +from typing import Optional, List, Dict, Collection, Union from cryptography import x509 diff --git a/testsuite/objects/gateway.py b/testsuite/gateway/__init__.py similarity index 71% rename from testsuite/objects/gateway.py rename to testsuite/gateway/__init__.py index cf37fa54..b8d26068 100644 --- a/testsuite/objects/gateway.py +++ b/testsuite/gateway/__init__.py @@ -1,10 +1,13 @@ -"""Module containing Proxy related stuff""" -from abc import abstractmethod, ABC +"""Classes related to Gateways""" +from abc import ABC, abstractmethod from dataclasses import dataclass -from typing import TYPE_CHECKING, Optional, Any +from typing import Any, Optional, TYPE_CHECKING -from . import LifecycleObject, asdict -from ..certificates import Certificate +from httpx import Client + +from testsuite.certificates import Certificate +from testsuite.lifecycle import LifecycleObject +from testsuite.utils import asdict if TYPE_CHECKING: from testsuite.openshift.client import OpenShiftClient @@ -103,3 +106,30 @@ def add_backend(self, backend: "Httpbin", prefix): @abstractmethod def remove_all_backend(self): """Sets match for a specific backend""" + + +class Hostname(ABC): + """ + Abstraction layer on top of externally exposed hostname + Simplified: Does not have any equal Kubernetes object. It is a hostname you can send HTTP request to + """ + + @abstractmethod + def client(self, **kwargs) -> Client: + """Return Httpx client for the requests to this backend""" + + @property + @abstractmethod + def hostname(self) -> str: + """Returns full hostname in string form associated with this object""" + + +class Exposer: + """Exposes hostnames to be accessible from outside""" + + @abstractmethod + def expose_hostname(self, name, gateway: Gateway) -> Hostname: + """ + Exposes hostname, so it is accessible from outside + Actual hostname is generated from "name" and is returned in a form of a Hostname object + """ diff --git a/testsuite/openshift/objects/envoy/__init__.py b/testsuite/gateway/envoy/__init__.py similarity index 96% rename from testsuite/openshift/objects/envoy/__init__.py rename to testsuite/gateway/envoy/__init__.py index 5da5fe34..8b836409 100644 --- a/testsuite/openshift/objects/envoy/__init__.py +++ b/testsuite/gateway/envoy/__init__.py @@ -6,9 +6,9 @@ import openshift as oc from testsuite.certificates import Certificate -from testsuite.objects.gateway import Gateway +from testsuite.gateway import Gateway from testsuite.openshift.client import OpenShiftClient -from testsuite.openshift.objects.envoy.config import EnvoyConfig +from testsuite.gateway.envoy.config import EnvoyConfig class Envoy(Gateway): # pylint: disable=too-many-instance-attributes diff --git a/testsuite/openshift/objects/envoy/config.py b/testsuite/gateway/envoy/config.py similarity index 97% rename from testsuite/openshift/objects/envoy/config.py rename to testsuite/gateway/envoy/config.py index 5a66c8e4..f3d373da 100644 --- a/testsuite/openshift/objects/envoy/config.py +++ b/testsuite/gateway/envoy/config.py @@ -2,8 +2,8 @@ import yaml from testsuite.openshift.httpbin import Httpbin -from testsuite.openshift.objects import modify -from testsuite.openshift.objects.config_map import ConfigMap +from testsuite.openshift import modify +from testsuite.openshift.config_map import ConfigMap BASE_CONFIG = """ diff --git a/testsuite/openshift/objects/envoy/route.py b/testsuite/gateway/envoy/route.py similarity index 84% rename from testsuite/openshift/objects/envoy/route.py rename to testsuite/gateway/envoy/route.py index 260ec461..e032aace 100644 --- a/testsuite/openshift/objects/envoy/route.py +++ b/testsuite/gateway/envoy/route.py @@ -1,8 +1,12 @@ """GatewayRoute implementation for pure Envoy Deployment""" -from testsuite.objects.gateway import GatewayRoute, Gateway -from testsuite.openshift.client import OpenShiftClient -from testsuite.openshift.httpbin import Httpbin -from testsuite.openshift.objects.auth_config import AuthConfig +import typing + +from testsuite.gateway import Gateway, GatewayRoute + +if typing.TYPE_CHECKING: + from testsuite.openshift.client import OpenShiftClient + from testsuite.openshift.httpbin import Httpbin + from testsuite.policy.authorization.auth_config import AuthConfig class EnvoyVirtualRoute(GatewayRoute): @@ -47,7 +51,7 @@ def remove_all_hostnames(self): for auth_config in self.auth_configs: auth_config.remove_all_hosts() - def add_auth_config(self, auth_config: AuthConfig): + def add_auth_config(self, auth_config: "AuthConfig"): """Adds AuthConfig to this virtual route""" self.auth_configs.append(auth_config) for hostname in self.hostnames: diff --git a/testsuite/openshift/objects/envoy/tls.py b/testsuite/gateway/envoy/tls.py similarity index 97% rename from testsuite/openshift/objects/envoy/tls.py rename to testsuite/gateway/envoy/tls.py index 7efe1eab..4ed05d14 100644 --- a/testsuite/openshift/objects/envoy/tls.py +++ b/testsuite/gateway/envoy/tls.py @@ -7,7 +7,7 @@ from . import Envoy, EnvoyConfig if TYPE_CHECKING: - from ...client import OpenShiftClient + from testsuite.openshift.client import OpenShiftClient TLS_TRANSPORT = """ name: envoy.transport_sockets.tls diff --git a/testsuite/openshift/objects/envoy/wristband.py b/testsuite/gateway/envoy/wristband.py similarity index 94% rename from testsuite/openshift/objects/envoy/wristband.py rename to testsuite/gateway/envoy/wristband.py index f510b2b0..cde6c2be 100644 --- a/testsuite/openshift/objects/envoy/wristband.py +++ b/testsuite/gateway/envoy/wristband.py @@ -1,7 +1,7 @@ """Wristband Envoy""" import yaml -from testsuite.openshift.objects.envoy import Envoy, EnvoyConfig +from testsuite.gateway.envoy import Envoy, EnvoyConfig class WristbandEnvoy(Envoy): diff --git a/testsuite/openshift/objects/gateway_api/__init__.py b/testsuite/gateway/gateway_api/__init__.py similarity index 100% rename from testsuite/openshift/objects/gateway_api/__init__.py rename to testsuite/gateway/gateway_api/__init__.py diff --git a/testsuite/openshift/objects/gateway_api/gateway.py b/testsuite/gateway/gateway_api/gateway.py similarity index 98% rename from testsuite/openshift/objects/gateway_api/gateway.py rename to testsuite/gateway/gateway_api/gateway.py index ba72797a..8ca951fb 100644 --- a/testsuite/openshift/objects/gateway_api/gateway.py +++ b/testsuite/gateway/gateway_api/gateway.py @@ -6,9 +6,9 @@ import openshift as oc from testsuite.certificates import Certificate -from testsuite.objects.gateway import Gateway +from testsuite.gateway import Gateway from testsuite.openshift.client import OpenShiftClient -from testsuite.openshift.objects import OpenShiftObject +from testsuite.openshift import OpenShiftObject class KuadrantGateway(OpenShiftObject, Gateway): diff --git a/testsuite/openshift/objects/gateway_api/hostname.py b/testsuite/gateway/gateway_api/hostname.py similarity index 90% rename from testsuite/openshift/objects/gateway_api/hostname.py rename to testsuite/gateway/gateway_api/hostname.py index d2271923..df535f5b 100644 --- a/testsuite/openshift/objects/gateway_api/hostname.py +++ b/testsuite/gateway/gateway_api/hostname.py @@ -3,10 +3,9 @@ from testsuite.certificates import Certificate from testsuite.httpx import KuadrantClient -from testsuite.objects import LifecycleObject -from testsuite.objects.gateway import Gateway -from testsuite.objects.hostname import Exposer, Hostname -from testsuite.openshift.objects.route import OpenshiftRoute +from testsuite.lifecycle import LifecycleObject +from testsuite.gateway import Gateway, Hostname, Exposer +from testsuite.openshift.route import OpenshiftRoute class OpenShiftExposer(Exposer, LifecycleObject): diff --git a/testsuite/openshift/objects/gateway_api/route.py b/testsuite/gateway/gateway_api/route.py similarity index 95% rename from testsuite/openshift/objects/gateway_api/route.py rename to testsuite/gateway/gateway_api/route.py index f5f4660c..bf04fc76 100644 --- a/testsuite/openshift/objects/gateway_api/route.py +++ b/testsuite/gateway/gateway_api/route.py @@ -5,9 +5,9 @@ from httpx import Client from testsuite.httpx import KuadrantClient -from testsuite.objects.gateway import GatewayRoute, Gateway +from testsuite.gateway import Gateway, GatewayRoute from testsuite.openshift.client import OpenShiftClient -from testsuite.openshift.objects import modify, OpenShiftObject +from testsuite.openshift import OpenShiftObject, modify if typing.TYPE_CHECKING: from testsuite.openshift.httpbin import Httpbin diff --git a/testsuite/httpx/auth.py b/testsuite/httpx/auth.py index 4ee87e85..d78a5f86 100644 --- a/testsuite/httpx/auth.py +++ b/testsuite/httpx/auth.py @@ -5,7 +5,7 @@ from httpx import Auth, Request, URL, Response from testsuite.oidc.rhsso import User -from testsuite.openshift.objects.api_key import APIKey +from testsuite.openshift.api_key import APIKey from testsuite.oidc import Token TokenType = Union[Token, Callable[[], Token]] diff --git a/testsuite/lifecycle.py b/testsuite/lifecycle.py new file mode 100644 index 00000000..7f7d6bae --- /dev/null +++ b/testsuite/lifecycle.py @@ -0,0 +1,16 @@ +"""Classes related to lifecycle management""" +import abc + + +class LifecycleObject(abc.ABC): + """Any objects which has its lifecycle controlled by create() and delete() methods""" + + @abc.abstractmethod + def commit(self): + """Commits resource. + if there is some reconciliation needed, the method should wait until it is all reconciled""" + + @abc.abstractmethod + def delete(self): + """Removes resource, + if there is some reconciliation needed, the method should wait until it is all reconciled""" diff --git a/testsuite/objects/hostname.py b/testsuite/objects/hostname.py deleted file mode 100644 index 4d9babdf..00000000 --- a/testsuite/objects/hostname.py +++ /dev/null @@ -1,33 +0,0 @@ -"""Abstract classes for Hostname related stuff""" -from abc import ABC, abstractmethod - -from httpx import Client - -from .gateway import Gateway - - -class Hostname(ABC): - """ - Abstraction layer on top of externally exposed hostname - Simplified: Does not have any equal Kubernetes object. It is a hostname you can send HTTP request to - """ - - @abstractmethod - def client(self, **kwargs) -> Client: - """Return Httpx client for the requests to this backend""" - - @property - @abstractmethod - def hostname(self) -> str: - """Returns full hostname in string form associated with this object""" - - -class Exposer: - """Exposes hostnames to be accessible from outside""" - - @abstractmethod - def expose_hostname(self, name, gateway: Gateway) -> Hostname: - """ - Exposes hostname, so it is accessible from outside - Actual hostname is generated from "name" and is returned in a form of a Hostname object - """ diff --git a/testsuite/oidc/rhsso/__init__.py b/testsuite/oidc/rhsso/__init__.py index 1e44c663..f9fd3a3f 100644 --- a/testsuite/oidc/rhsso/__init__.py +++ b/testsuite/oidc/rhsso/__init__.py @@ -5,7 +5,7 @@ from keycloak import KeycloakOpenID, KeycloakAdmin, KeycloakPostError from testsuite.oidc import OIDCProvider, Token -from testsuite.objects import LifecycleObject +from testsuite.lifecycle import LifecycleObject from .objects import Realm, Client, User diff --git a/testsuite/openshift/__init__.py b/testsuite/openshift/__init__.py index e69de29b..84499a57 100644 --- a/testsuite/openshift/__init__.py +++ b/testsuite/openshift/__init__.py @@ -0,0 +1,54 @@ +"""OpenShift common objects""" +import functools + +from openshift import APIObject, timeout + +from testsuite.lifecycle import LifecycleObject + + +class OpenShiftObject(APIObject, LifecycleObject): + """Custom APIObjects which tracks if the object was already committed to the server or not""" + + def __init__(self, dict_to_model=None, string_to_model=None, context=None): + super().__init__(dict_to_model, string_to_model, context) + self.committed = False + + def commit(self): + """ + Creates object on the server and returns created entity. + It will be the same class but attributes might differ, due to server adding/rejecting some of them. + """ + self.create(["--save-config=true"]) + self.committed = True + return self.refresh() + + def delete(self, ignore_not_found=True, cmd_args=None): + """Deletes the resource, by default ignored not found""" + with timeout(30): + deleted = super().delete(ignore_not_found, cmd_args) + self.committed = False + return deleted + + +def modify(func): + """Wraps method of a subclass of OpenShiftObject to use modify_and_apply when the object + is already committed to the server, or run it normally if it isn't. + All methods modifying the target object in any way should be decorated by this""" + + def _custom_partial(func, *args, **kwargs): + """Custom partial function which makes sure that self is always assigned correctly""" + + def _func(self): + func(self, *args, **kwargs) + + return _func + + @functools.wraps(func) + def _wrap(self, *args, **kwargs): + if self.committed: + result, _ = self.modify_and_apply(_custom_partial(func, *args, **kwargs)) + assert result.status + else: + func(self, *args, **kwargs) + + return _wrap diff --git a/testsuite/openshift/objects/api_key.py b/testsuite/openshift/api_key.py similarity index 93% rename from testsuite/openshift/objects/api_key.py rename to testsuite/openshift/api_key.py index be09f2ce..ed945093 100644 --- a/testsuite/openshift/objects/api_key.py +++ b/testsuite/openshift/api_key.py @@ -2,9 +2,9 @@ import base64 from functools import cached_property -from testsuite.objects import Selector +from testsuite.policy.authorization import Selector from testsuite.openshift.client import OpenShiftClient -from testsuite.openshift.objects import OpenShiftObject, modify +from testsuite.openshift import OpenShiftObject, modify class APIKey(OpenShiftObject): diff --git a/testsuite/openshift/objects/authorino.py b/testsuite/openshift/authorino.py similarity index 66% rename from testsuite/openshift/objects/authorino.py rename to testsuite/openshift/authorino.py index 0a9ce69b..3b8cf85d 100644 --- a/testsuite/openshift/objects/authorino.py +++ b/testsuite/openshift/authorino.py @@ -1,12 +1,36 @@ """Authorino CR object""" +import abc from typing import Any, Dict, List import openshift from openshift import selector -from testsuite.objects import Authorino from testsuite.openshift.client import OpenShiftClient -from testsuite.openshift.objects import OpenShiftObject +from testsuite.openshift import OpenShiftObject +from testsuite.lifecycle import LifecycleObject + + +class Authorino(LifecycleObject): + """Authorino interface""" + + @abc.abstractmethod + def wait_for_ready(self): + """True, if after some waiting the Authorino is ready""" + + @property + @abc.abstractmethod + def metrics_service(self): + """Authorino metrics service name""" + + @property + @abc.abstractmethod + def authorization_url(self): + """Authorization URL that can be plugged into envoy""" + + @property + @abc.abstractmethod + def oidc_url(self): + """Authorino oidc url""" class AuthorinoCR(OpenShiftObject, Authorino): @@ -78,3 +102,34 @@ def authorization_url(self): def oidc_url(self): """Return authorino oidc endpoint""" return f"{self.name()}-authorino-oidc.{self.namespace()}.svc.cluster.local" + + +class PreexistingAuthorino(Authorino): + """Authorino which is already deployed prior to the testrun""" + + def __init__(self, authorization_url, oidc_url, metrics_service) -> None: + super().__init__() + self._authorization_url = authorization_url + self._oidc_url = oidc_url + self._metrics_service = metrics_service + + def wait_for_ready(self): + return True + + @property + def metrics_service(self): + return self._metrics_service + + @property + def authorization_url(self): + return self._authorization_url + + @property + def oidc_url(self): + return self._oidc_url + + def commit(self): + return + + def delete(self): + return diff --git a/testsuite/openshift/client.py b/testsuite/openshift/client.py index d013b134..6676636c 100644 --- a/testsuite/openshift/client.py +++ b/testsuite/openshift/client.py @@ -9,8 +9,8 @@ import openshift as oc from openshift import Context, Selector, OpenShiftPythonException -from testsuite.openshift.objects.route import OpenshiftRoute -from testsuite.openshift.objects.secret import Secret +from .route import OpenshiftRoute +from .secret import Secret class ServiceTypes(enum.Enum): diff --git a/testsuite/openshift/objects/config_map.py b/testsuite/openshift/config_map.py similarity index 93% rename from testsuite/openshift/objects/config_map.py rename to testsuite/openshift/config_map.py index 01ef5528..87e57b8b 100644 --- a/testsuite/openshift/objects/config_map.py +++ b/testsuite/openshift/config_map.py @@ -1,5 +1,5 @@ """Config map""" -from testsuite.openshift.objects import OpenShiftObject +from testsuite.openshift import OpenShiftObject class ConfigMap(OpenShiftObject): diff --git a/testsuite/openshift/httpbin.py b/testsuite/openshift/httpbin.py index 270fe6b2..43024dd7 100644 --- a/testsuite/openshift/httpbin.py +++ b/testsuite/openshift/httpbin.py @@ -2,8 +2,8 @@ from functools import cached_property from importlib import resources -from testsuite.objects import LifecycleObject -from testsuite.objects.gateway import Referencable +from testsuite.lifecycle import LifecycleObject +from testsuite.gateway import Referencable from testsuite.openshift.client import OpenShiftClient diff --git a/testsuite/openshift/objects/ingress.py b/testsuite/openshift/ingress.py similarity index 97% rename from testsuite/openshift/objects/ingress.py rename to testsuite/openshift/ingress.py index e4652ed4..e5ce59d9 100644 --- a/testsuite/openshift/objects/ingress.py +++ b/testsuite/openshift/ingress.py @@ -1,7 +1,7 @@ """Kubernetes Ingress object""" from typing import Any, Dict, List, Optional, TYPE_CHECKING -from testsuite.openshift.objects import OpenShiftObject +from testsuite.openshift import OpenShiftObject if TYPE_CHECKING: # pylint: disable=cyclic-import diff --git a/testsuite/openshift/objects/metrics/__init__.py b/testsuite/openshift/metrics/__init__.py similarity index 100% rename from testsuite/openshift/objects/metrics/__init__.py rename to testsuite/openshift/metrics/__init__.py diff --git a/testsuite/openshift/objects/metrics/prometheus.py b/testsuite/openshift/metrics/prometheus.py similarity index 100% rename from testsuite/openshift/objects/metrics/prometheus.py rename to testsuite/openshift/metrics/prometheus.py diff --git a/testsuite/openshift/objects/metrics/service_monitor.py b/testsuite/openshift/metrics/service_monitor.py similarity index 93% rename from testsuite/openshift/objects/metrics/service_monitor.py rename to testsuite/openshift/metrics/service_monitor.py index 15b0de37..504bb5a1 100644 --- a/testsuite/openshift/objects/metrics/service_monitor.py +++ b/testsuite/openshift/metrics/service_monitor.py @@ -1,9 +1,9 @@ """Module implements Service Monitor CR for OpenShift""" from dataclasses import dataclass -from testsuite.objects import asdict +from testsuite.utils import asdict from testsuite.openshift.client import OpenShiftClient -from testsuite.openshift.objects import OpenShiftObject +from testsuite.openshift import OpenShiftObject @dataclass diff --git a/testsuite/openshift/objects/__init__.py b/testsuite/openshift/objects/__init__.py deleted file mode 100644 index 2c323e86..00000000 --- a/testsuite/openshift/objects/__init__.py +++ /dev/null @@ -1,54 +0,0 @@ -"""Base classes/methods for our own APIObjects""" -import functools - -from openshift import APIObject, timeout - -from testsuite.objects import LifecycleObject - - -def modify(func): - """Wraps method of a subclass of OpenShiftObject to use modify_and_apply when the object - is already committed to the server, or run it normally if it isn't. - All methods modifying the target object in any way should be decorated by this""" - - def _custom_partial(func, *args, **kwargs): - """Custom partial function which makes sure that self is always assigned correctly""" - - def _func(self): - func(self, *args, **kwargs) - - return _func - - @functools.wraps(func) - def _wrap(self, *args, **kwargs): - if self.committed: - result, _ = self.modify_and_apply(_custom_partial(func, *args, **kwargs)) - assert result.status - else: - func(self, *args, **kwargs) - - return _wrap - - -class OpenShiftObject(APIObject, LifecycleObject): - """Custom APIObjects which tracks if the object was already committed to the server or not""" - - def __init__(self, dict_to_model=None, string_to_model=None, context=None): - super().__init__(dict_to_model, string_to_model, context) - self.committed = False - - def commit(self): - """ - Creates object on the server and returns created entity. - It will be the same class but attributes might differ, due to server adding/rejecting some of them. - """ - self.create(["--save-config=true"]) - self.committed = True - return self.refresh() - - def delete(self, ignore_not_found=True, cmd_args=None): - """Deletes the resource, by default ignored not found""" - with timeout(30): - deleted = super().delete(ignore_not_found, cmd_args) - self.committed = False - return deleted diff --git a/testsuite/openshift/objects/route.py b/testsuite/openshift/route.py similarity index 92% rename from testsuite/openshift/objects/route.py rename to testsuite/openshift/route.py index 5bd60874..08092c2b 100644 --- a/testsuite/openshift/objects/route.py +++ b/testsuite/openshift/route.py @@ -4,8 +4,8 @@ from httpx import Client from testsuite.httpx import KuadrantClient -from testsuite.objects.hostname import Hostname -from testsuite.openshift.objects import OpenShiftObject +from testsuite.gateway import Hostname +from testsuite.openshift import OpenShiftObject class OpenshiftRoute(OpenShiftObject, Hostname): diff --git a/testsuite/openshift/objects/secret.py b/testsuite/openshift/secret.py similarity index 96% rename from testsuite/openshift/objects/secret.py rename to testsuite/openshift/secret.py index e93c0e06..7f0fb7bd 100644 --- a/testsuite/openshift/objects/secret.py +++ b/testsuite/openshift/secret.py @@ -3,7 +3,7 @@ from typing import Literal from testsuite.certificates import Certificate -from testsuite.openshift.objects import OpenShiftObject +from testsuite.openshift import OpenShiftObject class Secret(OpenShiftObject): diff --git a/testsuite/policy/__init__.py b/testsuite/policy/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/testsuite/objects/__init__.py b/testsuite/policy/authorization/__init__.py similarity index 58% rename from testsuite/objects/__init__.py rename to testsuite/policy/authorization/__init__.py index c2124a95..5d044331 100644 --- a/testsuite/objects/__init__.py +++ b/testsuite/policy/authorization/__init__.py @@ -1,50 +1,11 @@ -"""Module containing base classes for common objects""" +"""Authorization related objects""" import abc -from dataclasses import dataclass, is_dataclass, fields, field -from copy import deepcopy +from dataclasses import dataclass, field from typing import Literal, Optional +from testsuite.utils import asdict, JSONValues -JSONValues = None | str | int | bool | list["JSONValues"] | dict[str, "JSONValues"] # pylint: disable=invalid-name - - -def asdict(obj) -> dict[str, JSONValues]: - """ - This function converts dataclass object to dictionary. - While it works similar to `dataclasses.asdict` a notable change is usage of - overriding `asdict()` function if dataclass contains it. - This function works recursively in lists, tuples and dicts. All other values are passed to copy.deepcopy function. - """ - if not is_dataclass(obj): - raise TypeError("asdict() should be called on dataclass instances") - return _asdict_recurse(obj) - - -def _asdict_recurse(obj): - if hasattr(obj, "asdict"): - return obj.asdict() - - if not is_dataclass(obj): - return deepcopy(obj) - - result = {} - for field in fields(obj): - value = getattr(obj, field.name) - if value is None: - continue # do not include None values - - if is_dataclass(value): - result[field.name] = _asdict_recurse(value) - elif isinstance(value, (list, tuple)): - result[field.name] = type(value)(_asdict_recurse(i) for i in value) - elif isinstance(value, dict): - result[field.name] = type(value)((_asdict_recurse(k), _asdict_recurse(v)) for k, v in value.items()) - else: - result[field.name] = deepcopy(value) - return result - - @dataclass class MatchExpression: """ @@ -204,71 +165,3 @@ class PatternRef: """Dataclass for specifying Pattern reference in Authorization""" patternRef: str - - -class LifecycleObject(abc.ABC): - """Any objects which has its lifecycle controlled by create() and delete() methods""" - - @abc.abstractmethod - def commit(self): - """Commits resource. - if there is some reconciliation needed, the method should wait until it is all reconciled""" - - @abc.abstractmethod - def delete(self): - """Removes resource, - if there is some reconciliation needed, the method should wait until it is all reconciled""" - - -class Authorino(LifecycleObject): - """Authorino interface""" - - @abc.abstractmethod - def wait_for_ready(self): - """True, if after some waiting the Authorino is ready""" - - @property - @abc.abstractmethod - def metrics_service(self): - """Authorino metrics service name""" - - @property - @abc.abstractmethod - def authorization_url(self): - """Authorization URL that can be plugged into envoy""" - - @property - @abc.abstractmethod - def oidc_url(self): - """Authorino oidc url""" - - -class PreexistingAuthorino(Authorino): - """Authorino which is already deployed prior to the testrun""" - - def __init__(self, authorization_url, oidc_url, metrics_service) -> None: - super().__init__() - self._authorization_url = authorization_url - self._oidc_url = oidc_url - self._metrics_service = metrics_service - - def wait_for_ready(self): - return True - - @property - def metrics_service(self): - return self._metrics_service - - @property - def authorization_url(self): - return self._authorization_url - - @property - def oidc_url(self): - return self._oidc_url - - def commit(self): - return - - def delete(self): - return diff --git a/testsuite/openshift/objects/auth_config/__init__.py b/testsuite/policy/authorization/auth_config.py similarity index 88% rename from testsuite/openshift/objects/auth_config/__init__.py rename to testsuite/policy/authorization/auth_config.py index 802e507e..2a60a47f 100644 --- a/testsuite/openshift/objects/auth_config/__init__.py +++ b/testsuite/policy/authorization/auth_config.py @@ -1,11 +1,11 @@ -"""AuthConfig CR object""" +"""AuthConfig object""" from functools import cached_property -from typing import Dict, List, Optional +from typing import Dict -from testsuite.objects import Rule, asdict +from testsuite.utils import asdict +from testsuite.openshift import OpenShiftObject, modify from testsuite.openshift.client import OpenShiftClient -from testsuite.openshift.objects import OpenShiftObject, modify -from .sections import IdentitySection, MetadataSection, ResponseSection, AuthorizationSection +from .sections import AuthorizationSection, IdentitySection, MetadataSection, ResponseSection, Rule class AuthConfig(OpenShiftObject): diff --git a/testsuite/openshift/objects/auth_config/auth_policy.py b/testsuite/policy/authorization/auth_policy.py similarity index 75% rename from testsuite/openshift/objects/auth_config/auth_policy.py rename to testsuite/policy/authorization/auth_policy.py index d7ec82a1..2510a906 100644 --- a/testsuite/openshift/objects/auth_config/auth_policy.py +++ b/testsuite/policy/authorization/auth_policy.py @@ -1,11 +1,14 @@ -"""Module containing classes related to Auth Policy""" -from typing import Dict +"""Module containing classes related to AuthPolicy""" +from typing import Dict, TYPE_CHECKING -from testsuite.objects import Rule, asdict -from testsuite.objects.gateway import Referencable +from testsuite.utils import asdict +from testsuite.gateway import Referencable from testsuite.openshift.client import OpenShiftClient -from testsuite.openshift.objects import modify -from testsuite.openshift.objects.auth_config import AuthConfig +from testsuite.openshift import modify +from .auth_config import AuthConfig + +if TYPE_CHECKING: + from . import Rule class AuthPolicy(AuthConfig): @@ -37,7 +40,7 @@ def create_instance( # type: ignore return cls(model, context=openshift.context) @modify - def add_rule(self, when: list[Rule]): + 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]) diff --git a/testsuite/openshift/objects/auth_config/sections.py b/testsuite/policy/authorization/sections.py similarity index 98% rename from testsuite/openshift/objects/auth_config/sections.py rename to testsuite/policy/authorization/sections.py index 142bdc64..27ae9100 100644 --- a/testsuite/openshift/objects/auth_config/sections.py +++ b/testsuite/policy/authorization/sections.py @@ -1,23 +1,23 @@ -"""AuthConfig CR object""" +"""Sections inside of AuthConfig""" from typing import Literal, Iterable, TYPE_CHECKING, Union -from testsuite.objects import ( - asdict, - Rule, - Cache, - ABCValue, +from testsuite.policy.authorization import ( Selector, Credentials, + Rule, + ABCValue, ValueFrom, JsonResponse, PlainResponse, WristbandResponse, DenyResponse, + Cache, ) -from testsuite.openshift.objects import modify +from testsuite.utils import asdict +from testsuite.openshift import modify if TYPE_CHECKING: - from testsuite.openshift.objects.auth_config import AuthConfig + from .auth_config import AuthConfig def add_common_features( diff --git a/testsuite/openshift/objects/dnspolicy.py b/testsuite/policy/dns_policy.py similarity index 93% rename from testsuite/openshift/objects/dnspolicy.py rename to testsuite/policy/dns_policy.py index 2d59b77e..4d277450 100644 --- a/testsuite/openshift/objects/dnspolicy.py +++ b/testsuite/policy/dns_policy.py @@ -4,10 +4,10 @@ import openshift as oc -from testsuite.objects import asdict -from testsuite.objects.gateway import Referencable +from testsuite.utils import asdict +from testsuite.gateway import Referencable from testsuite.openshift.client import OpenShiftClient -from testsuite.openshift.objects import OpenShiftObject +from testsuite.openshift import OpenShiftObject @dataclass diff --git a/testsuite/openshift/objects/rate_limit.py b/testsuite/policy/rate_limit_policy.py similarity index 91% rename from testsuite/openshift/objects/rate_limit.py rename to testsuite/policy/rate_limit_policy.py index 24674850..c72af1f6 100644 --- a/testsuite/openshift/objects/rate_limit.py +++ b/testsuite/policy/rate_limit_policy.py @@ -5,10 +5,11 @@ import openshift as oc -from testsuite.objects import Rule, asdict -from testsuite.objects.gateway import Referencable +from testsuite.policy.authorization import Rule +from testsuite.utils import asdict +from testsuite.gateway import Referencable from testsuite.openshift.client import OpenShiftClient -from testsuite.openshift.objects import OpenShiftObject, modify +from testsuite.openshift import OpenShiftObject, modify @dataclass diff --git a/testsuite/openshift/objects/tlspolicy.py b/testsuite/policy/tls_policy.py similarity index 92% rename from testsuite/openshift/objects/tlspolicy.py rename to testsuite/policy/tls_policy.py index f32cfbcf..e257a61b 100644 --- a/testsuite/openshift/objects/tlspolicy.py +++ b/testsuite/policy/tls_policy.py @@ -1,7 +1,7 @@ """Module for TLSPolicy related classes""" -from testsuite.objects.gateway import Referencable +from testsuite.gateway import Referencable from testsuite.openshift.client import OpenShiftClient -from testsuite.openshift.objects import OpenShiftObject +from testsuite.openshift import OpenShiftObject class TLSPolicy(OpenShiftObject): diff --git a/testsuite/tests/conftest.py b/testsuite/tests/conftest.py index 1c2d5b16..3306707d 100644 --- a/testsuite/tests/conftest.py +++ b/testsuite/tests/conftest.py @@ -9,17 +9,16 @@ from testsuite.certificates import CFSSLClient from testsuite.config import settings from testsuite.mockserver import Mockserver -from testsuite.objects.gateway import Gateway, GatewayRoute -from testsuite.objects.hostname import Exposer, Hostname +from testsuite.gateway import Gateway, GatewayRoute, Hostname, Exposer from testsuite.oidc import OIDCProvider from testsuite.oidc.auth0 import Auth0Provider from testsuite.openshift.httpbin import Httpbin from testsuite.oidc.rhsso import RHSSO -from testsuite.openshift.objects.envoy import Envoy -from testsuite.openshift.objects.envoy.route import EnvoyVirtualRoute -from testsuite.openshift.objects.gateway_api.gateway import KuadrantGateway -from testsuite.openshift.objects.gateway_api.hostname import OpenShiftExposer -from testsuite.openshift.objects.gateway_api.route import HTTPRoute +from testsuite.gateway.envoy import Envoy +from testsuite.gateway.envoy.route import EnvoyVirtualRoute +from testsuite.gateway.gateway_api.gateway import KuadrantGateway +from testsuite.gateway.gateway_api.hostname import OpenShiftExposer +from testsuite.gateway.gateway_api.route import HTTPRoute from testsuite.utils import randomize, _whoami diff --git a/testsuite/tests/kuadrant/authorino/caching/metadata/test_caching.py b/testsuite/tests/kuadrant/authorino/caching/metadata/test_caching.py index 920737e5..834a8758 100644 --- a/testsuite/tests/kuadrant/authorino/caching/metadata/test_caching.py +++ b/testsuite/tests/kuadrant/authorino/caching/metadata/test_caching.py @@ -3,7 +3,7 @@ import pytest -from testsuite.objects import Cache, ValueFrom +from testsuite.policy.authorization import ValueFrom, Cache from testsuite.utils import extract_response diff --git a/testsuite/tests/kuadrant/authorino/conditions/section_conditions/test_authorization_condition.py b/testsuite/tests/kuadrant/authorino/conditions/section_conditions/test_authorization_condition.py index 9f554390..bde4ce28 100644 --- a/testsuite/tests/kuadrant/authorino/conditions/section_conditions/test_authorization_condition.py +++ b/testsuite/tests/kuadrant/authorino/conditions/section_conditions/test_authorization_condition.py @@ -1,7 +1,7 @@ """Test condition to skip the authorization section of AuthConfig""" import pytest -from testsuite.objects import Rule +from testsuite.policy.authorization import Rule @pytest.fixture(scope="module") diff --git a/testsuite/tests/kuadrant/authorino/conditions/section_conditions/test_identity_condition.py b/testsuite/tests/kuadrant/authorino/conditions/section_conditions/test_identity_condition.py index b60cc3ac..ac306858 100644 --- a/testsuite/tests/kuadrant/authorino/conditions/section_conditions/test_identity_condition.py +++ b/testsuite/tests/kuadrant/authorino/conditions/section_conditions/test_identity_condition.py @@ -1,7 +1,7 @@ """Test condition to skip the identity section of AuthConfig""" import pytest -from testsuite.objects import Rule +from testsuite.policy.authorization import Rule from testsuite.httpx.auth import HeaderApiKeyAuth diff --git a/testsuite/tests/kuadrant/authorino/conditions/section_conditions/test_metadata_condition.py b/testsuite/tests/kuadrant/authorino/conditions/section_conditions/test_metadata_condition.py index 481c3cd5..2032bcb2 100644 --- a/testsuite/tests/kuadrant/authorino/conditions/section_conditions/test_metadata_condition.py +++ b/testsuite/tests/kuadrant/authorino/conditions/section_conditions/test_metadata_condition.py @@ -1,7 +1,7 @@ """Test condition to skip the metadata section of AuthConfig""" import pytest -from testsuite.objects import Rule +from testsuite.policy.authorization import Rule @pytest.fixture(scope="module") diff --git a/testsuite/tests/kuadrant/authorino/conditions/section_conditions/test_response_condition.py b/testsuite/tests/kuadrant/authorino/conditions/section_conditions/test_response_condition.py index 5d6a8a45..b23bc245 100644 --- a/testsuite/tests/kuadrant/authorino/conditions/section_conditions/test_response_condition.py +++ b/testsuite/tests/kuadrant/authorino/conditions/section_conditions/test_response_condition.py @@ -1,7 +1,7 @@ """Test condition to skip the response section of AuthConfig""" import pytest -from testsuite.objects import Rule, Value, JsonResponse +from testsuite.policy.authorization import Rule, Value, JsonResponse from testsuite.utils import extract_response diff --git a/testsuite/tests/kuadrant/authorino/conditions/test_top_level_condition.py b/testsuite/tests/kuadrant/authorino/conditions/test_top_level_condition.py index a6ea17ff..34f54459 100644 --- a/testsuite/tests/kuadrant/authorino/conditions/test_top_level_condition.py +++ b/testsuite/tests/kuadrant/authorino/conditions/test_top_level_condition.py @@ -1,7 +1,7 @@ """Test condition to skip the entire AuthConfig""" import pytest -from testsuite.objects import Rule +from testsuite.policy.authorization import Rule @pytest.fixture(scope="module") diff --git a/testsuite/tests/kuadrant/authorino/conftest.py b/testsuite/tests/kuadrant/authorino/conftest.py index 6ec7c025..2fe8b8ab 100644 --- a/testsuite/tests/kuadrant/authorino/conftest.py +++ b/testsuite/tests/kuadrant/authorino/conftest.py @@ -2,11 +2,10 @@ import pytest from testsuite.httpx.auth import HttpxOidcClientAuth -from testsuite.objects import Authorino, PreexistingAuthorino from testsuite.openshift.client import OpenShiftClient -from testsuite.openshift.objects.api_key import APIKey -from testsuite.openshift.objects.auth_config import AuthConfig -from testsuite.openshift.objects.authorino import AuthorinoCR +from testsuite.openshift.api_key import APIKey +from testsuite.policy.authorization.auth_config import AuthConfig +from testsuite.openshift.authorino import AuthorinoCR, Authorino, PreexistingAuthorino @pytest.fixture(scope="module") diff --git a/testsuite/tests/kuadrant/authorino/dinosaur/conftest.py b/testsuite/tests/kuadrant/authorino/dinosaur/conftest.py index 95b318c8..1bcc8ead 100644 --- a/testsuite/tests/kuadrant/authorino/dinosaur/conftest.py +++ b/testsuite/tests/kuadrant/authorino/dinosaur/conftest.py @@ -7,7 +7,7 @@ from testsuite.httpx.auth import HttpxOidcClientAuth from testsuite.oidc.rhsso import RHSSO -from testsuite.openshift.objects.auth_config import AuthConfig +from testsuite.policy.authorization.auth_config import AuthConfig from testsuite.utils import ContentType diff --git a/testsuite/tests/kuadrant/authorino/identity/api_key/test_auth_credentials.py b/testsuite/tests/kuadrant/authorino/identity/api_key/test_auth_credentials.py index e6132eca..cc6416fe 100644 --- a/testsuite/tests/kuadrant/authorino/identity/api_key/test_auth_credentials.py +++ b/testsuite/tests/kuadrant/authorino/identity/api_key/test_auth_credentials.py @@ -1,7 +1,7 @@ """Test for API key auth credentials""" import pytest -from testsuite.objects import Credentials +from testsuite.policy.authorization import Credentials @pytest.fixture(scope="module", params=["authorizationHeader", "customHeader", "queryString", "cookie"]) diff --git a/testsuite/tests/kuadrant/authorino/identity/api_key/test_match_expression.py b/testsuite/tests/kuadrant/authorino/identity/api_key/test_match_expression.py index 529f8620..2917c683 100644 --- a/testsuite/tests/kuadrant/authorino/identity/api_key/test_match_expression.py +++ b/testsuite/tests/kuadrant/authorino/identity/api_key/test_match_expression.py @@ -5,7 +5,7 @@ """ import pytest -from testsuite.objects import MatchExpression, Selector +from testsuite.policy.authorization import MatchExpression, Selector @pytest.fixture(scope="module") diff --git a/testsuite/tests/kuadrant/authorino/identity/api_key/test_reconciliation.py b/testsuite/tests/kuadrant/authorino/identity/api_key/test_reconciliation.py index 16833aac..05afadce 100644 --- a/testsuite/tests/kuadrant/authorino/identity/api_key/test_reconciliation.py +++ b/testsuite/tests/kuadrant/authorino/identity/api_key/test_reconciliation.py @@ -2,7 +2,7 @@ import pytest from testsuite.httpx.auth import HeaderApiKeyAuth -from testsuite.objects import Selector +from testsuite.policy.authorization import Selector @pytest.fixture(scope="function") diff --git a/testsuite/tests/kuadrant/authorino/identity/extended_properties/test_extended_properties.py b/testsuite/tests/kuadrant/authorino/identity/extended_properties/test_extended_properties.py index 0cb1f021..7ef11a1b 100644 --- a/testsuite/tests/kuadrant/authorino/identity/extended_properties/test_extended_properties.py +++ b/testsuite/tests/kuadrant/authorino/identity/extended_properties/test_extended_properties.py @@ -1,7 +1,7 @@ """Basic tests for extended properties""" import pytest -from testsuite.objects import Value, ValueFrom +from testsuite.policy.authorization import Value, ValueFrom from testsuite.utils import extract_response diff --git a/testsuite/tests/kuadrant/authorino/identity/extended_properties/test_overwriting.py b/testsuite/tests/kuadrant/authorino/identity/extended_properties/test_overwriting.py index c4c52b8c..311ca020 100644 --- a/testsuite/tests/kuadrant/authorino/identity/extended_properties/test_overwriting.py +++ b/testsuite/tests/kuadrant/authorino/identity/extended_properties/test_overwriting.py @@ -1,7 +1,7 @@ """https://github.com/Kuadrant/authorino/pull/399""" import pytest -from testsuite.objects import Value +from testsuite.policy.authorization import Value from testsuite.utils import extract_response diff --git a/testsuite/tests/kuadrant/authorino/identity/extended_properties/test_token_normalization.py b/testsuite/tests/kuadrant/authorino/identity/extended_properties/test_token_normalization.py index 071e71f3..09b82978 100644 --- a/testsuite/tests/kuadrant/authorino/identity/extended_properties/test_token_normalization.py +++ b/testsuite/tests/kuadrant/authorino/identity/extended_properties/test_token_normalization.py @@ -1,6 +1,6 @@ """https://github.com/Kuadrant/authorino/blob/main/docs/user-guides/token-normalization.md""" import pytest -from testsuite.objects import Value, ValueFrom, Rule +from testsuite.policy.authorization import Rule, Value, ValueFrom from testsuite.httpx.auth import HeaderApiKeyAuth, HttpxOidcClientAuth diff --git a/testsuite/tests/kuadrant/authorino/identity/rhsso/test_auth_credentials.py b/testsuite/tests/kuadrant/authorino/identity/rhsso/test_auth_credentials.py index df580f62..b2089998 100644 --- a/testsuite/tests/kuadrant/authorino/identity/rhsso/test_auth_credentials.py +++ b/testsuite/tests/kuadrant/authorino/identity/rhsso/test_auth_credentials.py @@ -1,7 +1,7 @@ """Test for RHSSO auth credentials""" import pytest -from testsuite.objects import Credentials +from testsuite.policy.authorization import Credentials @pytest.fixture(scope="module", params=["authorizationHeader", "customHeader", "queryString", "cookie"]) diff --git a/testsuite/tests/kuadrant/authorino/identity/rhsso/test_rhsso_context.py b/testsuite/tests/kuadrant/authorino/identity/rhsso/test_rhsso_context.py index 476d5447..a28fe7a2 100644 --- a/testsuite/tests/kuadrant/authorino/identity/rhsso/test_rhsso_context.py +++ b/testsuite/tests/kuadrant/authorino/identity/rhsso/test_rhsso_context.py @@ -4,7 +4,7 @@ import pytest -from testsuite.objects import ValueFrom, JsonResponse +from testsuite.policy.authorization import ValueFrom, JsonResponse @pytest.fixture(scope="module") diff --git a/testsuite/tests/kuadrant/authorino/metadata/conftest.py b/testsuite/tests/kuadrant/authorino/metadata/conftest.py index d98a9917..7161685f 100644 --- a/testsuite/tests/kuadrant/authorino/metadata/conftest.py +++ b/testsuite/tests/kuadrant/authorino/metadata/conftest.py @@ -1,7 +1,7 @@ """Conftest for metadata feature tests""" import pytest -from testsuite.openshift.objects import OpenShiftObject +from testsuite.openshift import OpenShiftObject @pytest.fixture(scope="module") diff --git a/testsuite/tests/kuadrant/authorino/metadata/test_user_info.py b/testsuite/tests/kuadrant/authorino/metadata/test_user_info.py index 7a5a3c29..0e26c828 100644 --- a/testsuite/tests/kuadrant/authorino/metadata/test_user_info.py +++ b/testsuite/tests/kuadrant/authorino/metadata/test_user_info.py @@ -5,7 +5,7 @@ import pytest from testsuite.httpx.auth import HttpxOidcClientAuth -from testsuite.objects import Rule +from testsuite.policy.authorization import Rule @pytest.fixture(scope="module") diff --git a/testsuite/tests/kuadrant/authorino/metrics/conftest.py b/testsuite/tests/kuadrant/authorino/metrics/conftest.py index bec53a95..bcc831c0 100644 --- a/testsuite/tests/kuadrant/authorino/metrics/conftest.py +++ b/testsuite/tests/kuadrant/authorino/metrics/conftest.py @@ -4,8 +4,8 @@ import pytest from openshift import selector -from testsuite.openshift.objects.config_map import ConfigMap -from testsuite.openshift.objects.metrics import ServiceMonitor, MetricsEndpoint, Prometheus +from testsuite.openshift.config_map import ConfigMap +from testsuite.openshift.metrics import ServiceMonitor, MetricsEndpoint, Prometheus @pytest.fixture(scope="module") diff --git a/testsuite/tests/kuadrant/authorino/metrics/test_deep_metrics.py b/testsuite/tests/kuadrant/authorino/metrics/test_deep_metrics.py index 2d96ed21..459085e7 100644 --- a/testsuite/tests/kuadrant/authorino/metrics/test_deep_metrics.py +++ b/testsuite/tests/kuadrant/authorino/metrics/test_deep_metrics.py @@ -1,7 +1,7 @@ """Tests for the functionality of the deep-evaluator metric samples""" import pytest -from testsuite.objects import Value, JsonResponse +from testsuite.policy.authorization import Value, JsonResponse @pytest.fixture(scope="module") diff --git a/testsuite/tests/kuadrant/authorino/operator/clusterwide/conftest.py b/testsuite/tests/kuadrant/authorino/operator/clusterwide/conftest.py index 5a96b270..b9244fa0 100644 --- a/testsuite/tests/kuadrant/authorino/operator/clusterwide/conftest.py +++ b/testsuite/tests/kuadrant/authorino/operator/clusterwide/conftest.py @@ -1,7 +1,7 @@ """Conftest for clusterwide tests""" import pytest -from testsuite.openshift.objects.auth_config import AuthConfig +from testsuite.policy.authorization.auth_config import AuthConfig @pytest.fixture(scope="module") diff --git a/testsuite/tests/kuadrant/authorino/operator/clusterwide/test_wildcard_collision.py b/testsuite/tests/kuadrant/authorino/operator/clusterwide/test_wildcard_collision.py index a7c2936e..e9226e99 100644 --- a/testsuite/tests/kuadrant/authorino/operator/clusterwide/test_wildcard_collision.py +++ b/testsuite/tests/kuadrant/authorino/operator/clusterwide/test_wildcard_collision.py @@ -4,8 +4,8 @@ import pytest -from testsuite.objects import Value, JsonResponse -from testsuite.openshift.objects.auth_config import AuthConfig +from testsuite.policy.authorization import Value, JsonResponse +from testsuite.policy.authorization.auth_config import AuthConfig @pytest.fixture(scope="module") diff --git a/testsuite/tests/kuadrant/authorino/operator/raw_http/conftest.py b/testsuite/tests/kuadrant/authorino/operator/raw_http/conftest.py index 7c3efa6e..f16e26a3 100644 --- a/testsuite/tests/kuadrant/authorino/operator/raw_http/conftest.py +++ b/testsuite/tests/kuadrant/authorino/operator/raw_http/conftest.py @@ -1,10 +1,10 @@ """Conftest for all tests requiring custom deployment of Authorino""" import pytest -from testsuite.objects import Value, JsonResponse +from testsuite.policy.authorization import Value, JsonResponse from testsuite.httpx import KuadrantClient -from testsuite.openshift.objects.auth_config import AuthConfig -from testsuite.openshift.objects.route import OpenshiftRoute +from testsuite.policy.authorization.auth_config import AuthConfig +from testsuite.openshift.route import OpenshiftRoute # pylint: disable=unused-argument diff --git a/testsuite/tests/kuadrant/authorino/operator/sharding/conftest.py b/testsuite/tests/kuadrant/authorino/operator/sharding/conftest.py index 846fce74..e76c89ca 100644 --- a/testsuite/tests/kuadrant/authorino/operator/sharding/conftest.py +++ b/testsuite/tests/kuadrant/authorino/operator/sharding/conftest.py @@ -1,10 +1,10 @@ """Conftest for authorino sharding tests""" import pytest -from testsuite.objects import Value, JsonResponse -from testsuite.openshift.objects.envoy import Envoy -from testsuite.openshift.objects.auth_config import AuthConfig -from testsuite.openshift.objects.envoy.route import EnvoyVirtualRoute +from testsuite.policy.authorization import Value, JsonResponse +from testsuite.gateway.envoy import Envoy +from testsuite.policy.authorization.auth_config import AuthConfig +from testsuite.gateway.envoy.route import EnvoyVirtualRoute @pytest.fixture(scope="module") diff --git a/testsuite/tests/kuadrant/authorino/operator/sharding/test_preexisting_auth.py b/testsuite/tests/kuadrant/authorino/operator/sharding/test_preexisting_auth.py index aa647a7d..8fb79936 100644 --- a/testsuite/tests/kuadrant/authorino/operator/sharding/test_preexisting_auth.py +++ b/testsuite/tests/kuadrant/authorino/operator/sharding/test_preexisting_auth.py @@ -3,7 +3,7 @@ import pytest from weakget import weakget -from testsuite.openshift.objects.authorino import AuthorinoCR +from testsuite.openshift.authorino import AuthorinoCR @pytest.fixture(scope="module") diff --git a/testsuite/tests/kuadrant/authorino/operator/test_wildcard.py b/testsuite/tests/kuadrant/authorino/operator/test_wildcard.py index 1ae73b4b..63728d9f 100644 --- a/testsuite/tests/kuadrant/authorino/operator/test_wildcard.py +++ b/testsuite/tests/kuadrant/authorino/operator/test_wildcard.py @@ -3,7 +3,7 @@ """ import pytest -from testsuite.openshift.objects.auth_config import AuthConfig +from testsuite.policy.authorization.auth_config import AuthConfig @pytest.fixture(scope="module") diff --git a/testsuite/tests/kuadrant/authorino/operator/tls/conftest.py b/testsuite/tests/kuadrant/authorino/operator/tls/conftest.py index 965f256e..cc299c70 100644 --- a/testsuite/tests/kuadrant/authorino/operator/tls/conftest.py +++ b/testsuite/tests/kuadrant/authorino/operator/tls/conftest.py @@ -4,11 +4,11 @@ import pytest from testsuite.certificates import Certificate, CertInfo -from testsuite.objects import Selector -from testsuite.objects.hostname import Exposer -from testsuite.openshift.objects.envoy.tls import TLSEnvoy -from testsuite.openshift.objects.gateway_api.hostname import OpenShiftExposer -from testsuite.openshift.objects.secret import TLSSecret +from testsuite.policy.authorization import Selector +from testsuite.gateway import Exposer +from testsuite.gateway.envoy.tls import TLSEnvoy +from testsuite.gateway.gateway_api.hostname import OpenShiftExposer +from testsuite.openshift.secret import TLSSecret from testsuite.utils import cert_builder diff --git a/testsuite/tests/kuadrant/authorino/operator/tls/mtls/conftest.py b/testsuite/tests/kuadrant/authorino/operator/tls/mtls/conftest.py index 3fdf19d3..b801d8f0 100644 --- a/testsuite/tests/kuadrant/authorino/operator/tls/mtls/conftest.py +++ b/testsuite/tests/kuadrant/authorino/operator/tls/mtls/conftest.py @@ -3,7 +3,7 @@ from testsuite.certificates import CertInfo from testsuite.utils import cert_builder -from testsuite.objects import Rule +from testsuite.policy.authorization import Rule @pytest.fixture(scope="module", autouse=True) diff --git a/testsuite/tests/kuadrant/authorino/operator/tls/mtls/test_mtls_attributes.py b/testsuite/tests/kuadrant/authorino/operator/tls/mtls/test_mtls_attributes.py index 192468e8..b367dc8f 100644 --- a/testsuite/tests/kuadrant/authorino/operator/tls/mtls/test_mtls_attributes.py +++ b/testsuite/tests/kuadrant/authorino/operator/tls/mtls/test_mtls_attributes.py @@ -1,7 +1,7 @@ """Tests on mTLS authentication with multiple attributes""" import pytest -from testsuite.objects import Rule +from testsuite.policy.authorization import Rule @pytest.fixture(scope="module", autouse=True) diff --git a/testsuite/tests/kuadrant/authorino/operator/tls/test_webhook.py b/testsuite/tests/kuadrant/authorino/operator/tls/test_webhook.py index 23910ab8..6a48d425 100644 --- a/testsuite/tests/kuadrant/authorino/operator/tls/test_webhook.py +++ b/testsuite/tests/kuadrant/authorino/operator/tls/test_webhook.py @@ -8,11 +8,11 @@ import openshift as oc from openshift import OpenShiftPythonException -from testsuite.objects import Rule, ValueFrom +from testsuite.policy.authorization import Rule, ValueFrom from testsuite.certificates import CertInfo -from testsuite.openshift.objects.auth_config import AuthConfig +from testsuite.policy.authorization.auth_config import AuthConfig from testsuite.utils import cert_builder -from testsuite.openshift.objects.ingress import Ingress +from testsuite.openshift.ingress import Ingress OPA_POLICY = """ request := json.unmarshal(input.context.request.http.body).request diff --git a/testsuite/tests/kuadrant/authorino/priority/test_sequence_api_key.py b/testsuite/tests/kuadrant/authorino/priority/test_sequence_api_key.py index cae9e5d3..03bb18f7 100644 --- a/testsuite/tests/kuadrant/authorino/priority/test_sequence_api_key.py +++ b/testsuite/tests/kuadrant/authorino/priority/test_sequence_api_key.py @@ -1,7 +1,7 @@ """Test for api key identities, with different credential methods, sequential trigger according to their priorities""" import pytest -from testsuite.objects import Credentials +from testsuite.policy.authorization import Credentials from testsuite.utils import extract_response diff --git a/testsuite/tests/kuadrant/authorino/response/test_auth_json.py b/testsuite/tests/kuadrant/authorino/response/test_auth_json.py index 7b6eb6e4..591f7013 100644 --- a/testsuite/tests/kuadrant/authorino/response/test_auth_json.py +++ b/testsuite/tests/kuadrant/authorino/response/test_auth_json.py @@ -4,7 +4,7 @@ import pytest -from testsuite.objects import ValueFrom, JsonResponse +from testsuite.policy.authorization import ValueFrom, JsonResponse @pytest.fixture(scope="module") diff --git a/testsuite/tests/kuadrant/authorino/response/test_base64.py b/testsuite/tests/kuadrant/authorino/response/test_base64.py index 52e94153..27eab6bc 100644 --- a/testsuite/tests/kuadrant/authorino/response/test_base64.py +++ b/testsuite/tests/kuadrant/authorino/response/test_base64.py @@ -6,7 +6,7 @@ import pytest -from testsuite.objects import ValueFrom, JsonResponse +from testsuite.policy.authorization import ValueFrom, JsonResponse @pytest.fixture(scope="module") diff --git a/testsuite/tests/kuadrant/authorino/response/test_deny_with.py b/testsuite/tests/kuadrant/authorino/response/test_deny_with.py index 419b8664..a5d82f51 100644 --- a/testsuite/tests/kuadrant/authorino/response/test_deny_with.py +++ b/testsuite/tests/kuadrant/authorino/response/test_deny_with.py @@ -2,7 +2,7 @@ from json import loads import pytest -from testsuite.objects import Value, ValueFrom, Rule, DenyResponse +from testsuite.policy.authorization import Rule, Value, ValueFrom, DenyResponse HEADERS = { "x-string-header": Value("abc"), diff --git a/testsuite/tests/kuadrant/authorino/response/test_headers.py b/testsuite/tests/kuadrant/authorino/response/test_headers.py index fcc9f0c3..432b44ee 100644 --- a/testsuite/tests/kuadrant/authorino/response/test_headers.py +++ b/testsuite/tests/kuadrant/authorino/response/test_headers.py @@ -3,7 +3,7 @@ import pytest -from testsuite.objects import Value, JsonResponse +from testsuite.policy.authorization import Value, JsonResponse @pytest.fixture(scope="module", params=["123456789", "standardCharacters", "specialcharacters+*-."]) diff --git a/testsuite/tests/kuadrant/authorino/response/test_multiple_responses.py b/testsuite/tests/kuadrant/authorino/response/test_multiple_responses.py index 2f76de96..7fe2a0b2 100644 --- a/testsuite/tests/kuadrant/authorino/response/test_multiple_responses.py +++ b/testsuite/tests/kuadrant/authorino/response/test_multiple_responses.py @@ -3,7 +3,7 @@ import pytest -from testsuite.objects import Value, JsonResponse +from testsuite.policy.authorization import Value, JsonResponse @pytest.fixture(scope="module") diff --git a/testsuite/tests/kuadrant/authorino/response/test_simple_response.py b/testsuite/tests/kuadrant/authorino/response/test_simple_response.py index 4b70ca61..9da2202a 100644 --- a/testsuite/tests/kuadrant/authorino/response/test_simple_response.py +++ b/testsuite/tests/kuadrant/authorino/response/test_simple_response.py @@ -3,7 +3,7 @@ import pytest -from testsuite.objects import Value, JsonResponse +from testsuite.policy.authorization import Value, JsonResponse @pytest.fixture(scope="module") diff --git a/testsuite/tests/kuadrant/authorino/test_redirect.py b/testsuite/tests/kuadrant/authorino/test_redirect.py index 026c21d6..6f8656af 100644 --- a/testsuite/tests/kuadrant/authorino/test_redirect.py +++ b/testsuite/tests/kuadrant/authorino/test_redirect.py @@ -3,7 +3,7 @@ """ import pytest -from testsuite.objects import ValueFrom, DenyResponse +from testsuite.policy.authorization import ValueFrom, DenyResponse STATUS_CODE = 302 REDIRECT_URL = "http://anything.inavlid?redirect_to=" diff --git a/testsuite/tests/kuadrant/authorino/wristband/conftest.py b/testsuite/tests/kuadrant/authorino/wristband/conftest.py index 17399442..46aedeeb 100644 --- a/testsuite/tests/kuadrant/authorino/wristband/conftest.py +++ b/testsuite/tests/kuadrant/authorino/wristband/conftest.py @@ -3,11 +3,11 @@ import pytest from testsuite.certificates import CertInfo -from testsuite.objects import WristbandResponse, WristbandSigningKeyRef -from testsuite.openshift.objects.auth_config import AuthConfig -from testsuite.openshift.objects.envoy.route import EnvoyVirtualRoute -from testsuite.openshift.objects.envoy.wristband import WristbandEnvoy -from testsuite.openshift.objects.secret import TLSSecret +from testsuite.policy.authorization import WristbandSigningKeyRef, WristbandResponse +from testsuite.policy.authorization.auth_config import AuthConfig +from testsuite.gateway.envoy.route import EnvoyVirtualRoute +from testsuite.gateway.envoy.wristband import WristbandEnvoy +from testsuite.openshift.secret import TLSSecret from testsuite.utils import cert_builder diff --git a/testsuite/tests/kuadrant/conftest.py b/testsuite/tests/kuadrant/conftest.py index a5d8b378..0fc07c0e 100644 --- a/testsuite/tests/kuadrant/conftest.py +++ b/testsuite/tests/kuadrant/conftest.py @@ -2,8 +2,8 @@ all methods are placeholders for now since we do not work with Kuadrant""" import pytest -from testsuite.openshift.objects.auth_config.auth_policy import AuthPolicy -from testsuite.openshift.objects.rate_limit import RateLimitPolicy +from testsuite.policy.authorization.auth_policy import AuthPolicy +from testsuite.policy.rate_limit_policy import RateLimitPolicy @pytest.fixture(scope="session") diff --git a/testsuite/tests/kuadrant/limitador/test_basic_limit.py b/testsuite/tests/kuadrant/limitador/test_basic_limit.py index 93261ffe..d9da022a 100644 --- a/testsuite/tests/kuadrant/limitador/test_basic_limit.py +++ b/testsuite/tests/kuadrant/limitador/test_basic_limit.py @@ -4,7 +4,7 @@ import pytest -from testsuite.openshift.objects.rate_limit import Limit +from testsuite.policy.rate_limit_policy import Limit @pytest.fixture( diff --git a/testsuite/tests/kuadrant/limitador/test_multiple_iterations.py b/testsuite/tests/kuadrant/limitador/test_multiple_iterations.py index 92de415e..2ac7259c 100644 --- a/testsuite/tests/kuadrant/limitador/test_multiple_iterations.py +++ b/testsuite/tests/kuadrant/limitador/test_multiple_iterations.py @@ -5,7 +5,7 @@ import pytest -from testsuite.openshift.objects.rate_limit import Limit +from testsuite.policy.rate_limit_policy import Limit @pytest.fixture(scope="module") diff --git a/testsuite/tests/kuadrant/test_rate_limit_authz.py b/testsuite/tests/kuadrant/test_rate_limit_authz.py index 92693207..0bc5fb2a 100644 --- a/testsuite/tests/kuadrant/test_rate_limit_authz.py +++ b/testsuite/tests/kuadrant/test_rate_limit_authz.py @@ -3,8 +3,8 @@ import pytest from testsuite.httpx.auth import HttpxOidcClientAuth -from testsuite.objects import ValueFrom, JsonResponse -from testsuite.openshift.objects.rate_limit import Limit +from testsuite.policy.authorization import ValueFrom, JsonResponse +from testsuite.policy.rate_limit_policy import Limit @pytest.fixture(scope="module") diff --git a/testsuite/tests/mgc/conftest.py b/testsuite/tests/mgc/conftest.py index c04229bd..ec599664 100644 --- a/testsuite/tests/mgc/conftest.py +++ b/testsuite/tests/mgc/conftest.py @@ -3,13 +3,12 @@ from openshift import selector from weakget import weakget -from testsuite.objects.gateway import GatewayRoute, CustomReference -from testsuite.objects.hostname import Exposer -from testsuite.openshift.objects.dnspolicy import DNSPolicy -from testsuite.openshift.objects.gateway_api.gateway import MGCGateway -from testsuite.openshift.objects.gateway_api.hostname import DNSPolicyExposer -from testsuite.openshift.objects.gateway_api.route import HTTPRoute -from testsuite.openshift.objects.tlspolicy import TLSPolicy +from testsuite.gateway import CustomReference, GatewayRoute, Exposer +from testsuite.policy.dns_policy import DNSPolicy +from testsuite.gateway.gateway_api.gateway import MGCGateway +from testsuite.gateway.gateway_api.hostname import DNSPolicyExposer +from testsuite.gateway.gateway_api.route import HTTPRoute +from testsuite.policy.tls_policy import TLSPolicy @pytest.fixture(scope="session") diff --git a/testsuite/tests/mgc/dnspolicy/conftest.py b/testsuite/tests/mgc/dnspolicy/conftest.py index 14a27bdb..86a1495a 100644 --- a/testsuite/tests/mgc/dnspolicy/conftest.py +++ b/testsuite/tests/mgc/dnspolicy/conftest.py @@ -1,7 +1,7 @@ """Conftest for DNSPolicy tests""" import pytest -from testsuite.openshift.objects.gateway_api.gateway import MGCGateway +from testsuite.gateway.gateway_api.gateway import MGCGateway @pytest.fixture(scope="module") diff --git a/testsuite/tests/mgc/dnspolicy/health_check/conftest.py b/testsuite/tests/mgc/dnspolicy/health_check/conftest.py index c50b0377..2135a2c6 100644 --- a/testsuite/tests/mgc/dnspolicy/health_check/conftest.py +++ b/testsuite/tests/mgc/dnspolicy/health_check/conftest.py @@ -2,8 +2,8 @@ import time import pytest -from testsuite.objects.hostname import Hostname -from testsuite.openshift.objects.gateway_api.gateway import MGCGateway +from testsuite.gateway import Hostname +from testsuite.gateway.gateway_api.gateway import MGCGateway @pytest.fixture(scope="module") diff --git a/testsuite/tests/mgc/dnspolicy/health_check/test_healthy_endpoint.py b/testsuite/tests/mgc/dnspolicy/health_check/test_healthy_endpoint.py index c8334039..4fe2ad05 100644 --- a/testsuite/tests/mgc/dnspolicy/health_check/test_healthy_endpoint.py +++ b/testsuite/tests/mgc/dnspolicy/health_check/test_healthy_endpoint.py @@ -1,7 +1,7 @@ """Tests for DNSPolicy health checks - healthy endpoint""" import pytest -from testsuite.openshift.objects.dnspolicy import HealthCheck +from testsuite.policy.dns_policy import HealthCheck pytestmark = [pytest.mark.mgc] diff --git a/testsuite/tests/mgc/dnspolicy/health_check/test_unhealthy_endpoint.py b/testsuite/tests/mgc/dnspolicy/health_check/test_unhealthy_endpoint.py index 72554ddd..b5df3589 100644 --- a/testsuite/tests/mgc/dnspolicy/health_check/test_unhealthy_endpoint.py +++ b/testsuite/tests/mgc/dnspolicy/health_check/test_unhealthy_endpoint.py @@ -1,7 +1,7 @@ """Tests for DNSPolicy health checks - unhealthy endpoint""" import pytest -from testsuite.openshift.objects.dnspolicy import HealthCheck +from testsuite.policy.dns_policy import HealthCheck pytestmark = [pytest.mark.mgc] diff --git a/testsuite/utils.py b/testsuite/utils.py index 1e703eb4..2697a727 100644 --- a/testsuite/utils.py +++ b/testsuite/utils.py @@ -5,6 +5,8 @@ import os import secrets from collections.abc import Collection +from copy import deepcopy +from dataclasses import is_dataclass, fields from importlib import resources from io import StringIO from typing import Dict, Union @@ -17,6 +19,8 @@ MESSAGE_1KB = resources.files("testsuite.resources.performance.files").joinpath("message_1kb.txt") +JSONValues = None | str | int | bool | list["JSONValues"] | dict[str, "JSONValues"] + class ContentType(enum.Enum): """Content-type options for expectation headers""" @@ -119,3 +123,39 @@ def extract_response(response, header="Simple", key="data"): :return: Extracted value """ return weakget(json.loads(response.json()["headers"][header]))[key] + + +def asdict(obj) -> dict[str, JSONValues]: + """ + This function converts dataclass object to dictionary. + While it works similar to `dataclasses.asdict` a notable change is usage of + overriding `asdict()` function if dataclass contains it. + This function works recursively in lists, tuples and dicts. All other values are passed to copy.deepcopy function. + """ + if not is_dataclass(obj): + raise TypeError("asdict() should be called on dataclass instances") + return _asdict_recurse(obj) + + +def _asdict_recurse(obj): + if hasattr(obj, "asdict"): + return obj.asdict() + + if not is_dataclass(obj): + return deepcopy(obj) + + result = {} + for field in fields(obj): + value = getattr(obj, field.name) + if value is None: + continue # do not include None values + + if is_dataclass(value): + result[field.name] = _asdict_recurse(value) + elif isinstance(value, (list, tuple)): + result[field.name] = type(value)(_asdict_recurse(i) for i in value) + elif isinstance(value, dict): + result[field.name] = type(value)((_asdict_recurse(k), _asdict_recurse(v)) for k, v in value.items()) + else: + result[field.name] = deepcopy(value) + return result