This is an automated email from the ASF dual-hosted git repository.

ericholguin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficcontrol.git


The following commit(s) were added to refs/heads/master by this push:
     new 0adc2b7595 Added api contract test case for delivery services regex 
endpoint (#7642)
0adc2b7595 is described below

commit 0adc2b7595e1d41843fea482f060507de77c9487
Author: Gokula Krishnan <[email protected]>
AuthorDate: Tue Jul 18 18:43:29 2023 +0530

    Added api contract test case for delivery services regex endpoint (#7642)
    
    * Added api contract test case for delivery services regex endpoint
    
    * Added validation for PUT method for delivery services regex
    
    * modified entrypoint
---
 .../clients/python/trafficops/tosession.py         |  6 +-
 traffic_ops/testing/api_contract/v4/conftest.py    | 59 ++++++++++++--
 .../api_contract/v4/data/request_template.json     | 13 ++-
 .../api_contract/v4/data/response_template.json    | 32 +++++++-
 .../v4/test_delivery_services_regex.py             | 94 ++++++++++++++++++++++
 5 files changed, 189 insertions(+), 15 deletions(-)

diff --git a/traffic_control/clients/python/trafficops/tosession.py 
b/traffic_control/clients/python/trafficops/tosession.py
index 0772c19dcf..13af54ecf3 100644
--- a/traffic_control/clients/python/trafficops/tosession.py
+++ b/traffic_control/clients/python/trafficops/tosession.py
@@ -1025,7 +1025,7 @@ class TOSession(RestApiSession):
 
        @api_request('put', 
'deliveryservices/{delivery_service_id:d}/regexes/{regex_id:d}', ('3.0', '4.0', 
'4.1', '5.0'))
        def update_deliveryservice_regexes(self, delivery_service_id=None, 
regex_id=None,
-                                          query_params=None):
+                                          data=None):
                """
                Update a regex for a delivery service
                :ref:`to-api-deliveryservices-id-regexes-rid`
@@ -1033,8 +1033,8 @@ class TOSession(RestApiSession):
                :type delivery_service_id: int
                :param regex_id: The delivery service regex id
                :type regex_id: int
-               :param query_params: The required data to update delivery 
service regexes
-               :type query_params: Dict[str, Any]
+               :param data: The required data to update delivery service 
regexes
+               :type data: Dict[str, Any]
                :rtype: Tuple[Dict[str, Any], requests.Response]
                :raises: Union[LoginError, OperationError]
                """
diff --git a/traffic_ops/testing/api_contract/v4/conftest.py 
b/traffic_ops/testing/api_contract/v4/conftest.py
index 02deae62e9..db268e50cb 100644
--- a/traffic_ops/testing/api_contract/v4/conftest.py
+++ b/traffic_ops/testing/api_contract/v4/conftest.py
@@ -1486,17 +1486,19 @@ def cdn_notification_data_post(to_session: TOSession, 
request_template_data: lis
        """
        PyTest Fixture to create POST data for cdn_notifications endpoint.
        :param to_session: Fixture to get Traffic Ops session.
-       :param request_template_data: Fixture to get cdn_notification request 
template from a prerequisites file.
+       :param request_template_data: Fixture to get cdn_notification request 
template.
        :returns: Sample POST data and the actual API response.
        """
 
-       cdn_notification = 
check_template_data(request_template_data["cdn_notifications"], 
"cdn_notifications")
+       cdn_notification = check_template_data(
+               request_template_data["cdn_notifications"], "cdn_notifications")
 
        # Return new post data and post response from cdn_notifications POST 
request
        cdn_notification["cdn"] = cdn_post_data["name"]
        logger.info("New cdn_notification data to hit POST method %s", 
cdn_notification)
        # Hitting cdn_notification POST methed
-       response: tuple[JSONData, requests.Response] = 
to_session.create_cdn_notification(data=cdn_notification)
+       response: tuple[JSONData, requests.Response] = 
to_session.create_cdn_notification(
+               data=cdn_notification)
        resp_obj = check_template_data(response, "cdn_notification")
        yield resp_obj
        notification_id = resp_obj.get("id")
@@ -1513,11 +1515,12 @@ def deliveryservice_request_data_post(to_session: 
TOSession, request_template_da
        """
        PyTest Fixture to create POST data for deliveryservice_request endpoint.
        :param to_session: Fixture to get Traffic Ops session.
-       :param request_template_data: Fixture to get deliveryservice_request 
request template from a prerequisites file.
+       :param request_template_data: Fixture to get deliveryservice_request 
request template.
        :returns: Sample POST data and the actual API response.
        """
 
-       deliveryservice_request = 
check_template_data(request_template_data["deliveryservice_requests"], 
"deliveryservice_requests")
+       deliveryservice_request = check_template_data(
+               request_template_data["deliveryservice_requests"], 
"deliveryservice_requests")
 
        # Return new post data and post response from deliveryservice_request 
POST request
        keys = ["displayName", "xmlId", "id", "cdnId", "tenantId", "type", 
"typeId"]
@@ -1525,7 +1528,8 @@ def deliveryservice_request_data_post(to_session: 
TOSession, request_template_da
                deliveryservice_request["requested"][key] = 
delivery_services_post_data[key]
        logger.info("New deliveryservice_request data to hit POST method %s", 
deliveryservice_request)
        # Hitting deliveryservice_request POST methed
-       response: tuple[JSONData, requests.Response] = 
to_session.create_deliveryservice_request(data=deliveryservice_request)
+       response: tuple[JSONData, requests.Response] = 
to_session.create_deliveryservice_request(
+               data=deliveryservice_request)
        resp_obj = check_template_data(response, "deliveryservice_request")
        yield resp_obj
        deliveryservice_request_id = resp_obj.get("id")
@@ -1561,13 +1565,52 @@ def steering_data_post(to_session: TOSession, 
request_template_data: list[JSONDa
 
        logger.info("New steering data to hit POST method %s", steering)
        # Hitting steering POST methed
-       response: tuple[JSONData, requests.Response] = 
to_session.create_steering_targets(delivery_service_id=delivery_service_id, 
data=steering)
+       response: tuple[JSONData, requests.Response] = 
to_session.create_steering_targets(
+               delivery_service_id=delivery_service_id, data=steering)
        resp_obj = check_template_data(response, "steering")
        yield resp_obj
        deliveryservice_id = resp_obj.get("deliveryServiceId")
        target_id = resp_obj.get("targetId")
-       msg = 
to_session.delete_steering_targets(delivery_service_id=deliveryservice_id, 
target_id=target_id)
+       msg = to_session.delete_steering_targets(
+               delivery_service_id=deliveryservice_id, target_id=target_id)
        logger.info("Deleting Steering data... %s", msg)
        if msg is None:
                logger.error("Steering returned by Traffic Ops is missing an 
'id' property")
                pytest.fail("Response from delete request is empty, Failing 
test_case")
+
+
[email protected](name="delivery_services_regex_post_data")
+def delivery_services_regex_data_post(to_session: TOSession, 
request_template_data: list[JSONData],
+                 delivery_services_post_data:dict[str, object]) -> dict[str, 
object]:
+       """
+       PyTest Fixture to create POST data for delivery_services_regex endpoint.
+       :param to_session: Fixture to get Traffic Ops session.
+       :param request_template_data: Fixture to get delivery_services_regex 
request template.
+       :returns: Sample POST data and the actual API response.
+       """
+
+       delivery_services_regex = check_template_data(
+               request_template_data["delivery_services_regex"], 
"delivery_services_regex")
+
+       # Return new post data and post response from delivery_services_regex 
POST request
+
+       delivery_service_id = delivery_services_post_data["id"]
+       # Check if type already exists, otherwise create it
+       type_data = check_template_data(request_template_data["types"], "types")
+       type_object = create_or_get_existing(to_session, "types", "type", 
type_data,
+                                     {"useInTable": "regex"})
+       delivery_services_regex["type"]= type_object["id"]
+
+       logger.info("New delivery_services_regex data to hit POST method %s", 
delivery_services_regex)
+       # Hitting delivery_services_regex POST methed
+       response: tuple[JSONData, requests.Response] = 
to_session.create_deliveryservice_regexes(
+               delivery_service_id=delivery_service_id, 
data=delivery_services_regex)
+       resp_obj = check_template_data(response, "delivery_services_regex")
+       yield [delivery_service_id,resp_obj]
+       regex_id = resp_obj.get("id")
+       msg = to_session.delete_deliveryservice_regex_by_regex_id(
+               delivery_service_id=delivery_service_id, 
delivery_service_regex_id=regex_id)
+       logger.info("Deleting delivery_services_regex data... %s", msg)
+       if msg is None:
+               logger.error("delivery_services_regex returned by Traffic Ops 
is missing an 'id' property")
+               pytest.fail("Response from delete request is empty, Failing 
test_case")
diff --git a/traffic_ops/testing/api_contract/v4/data/request_template.json 
b/traffic_ops/testing/api_contract/v4/data/request_template.json
index d91277a736..988c13ef4a 100644
--- a/traffic_ops/testing/api_contract/v4/data/request_template.json
+++ b/traffic_ops/testing/api_contract/v4/data/request_template.json
@@ -267,8 +267,8 @@
                        "targetId": 61,
                        "value": 100,
                        "typeId": 43
-    }
-  ],
+               }
+       ],
        "cdn_notifications": [
                {
                        "cdn": "cdn1",
@@ -375,5 +375,12 @@
                                "tlsVersions": null
                        }
                }
+       ],
+       "delivery_services_regex": [
+               {
+                       "pattern": ".*\\.foo-bar\\..*",
+                       "type": 33,
+                       "setNumber": 1
+               }
        ]
-}
\ No newline at end of file
+}
diff --git a/traffic_ops/testing/api_contract/v4/data/response_template.json 
b/traffic_ops/testing/api_contract/v4/data/response_template.json
index c859ceab71..8cdeef3a48 100644
--- a/traffic_ops/testing/api_contract/v4/data/response_template.json
+++ b/traffic_ops/testing/api_contract/v4/data/response_template.json
@@ -730,7 +730,10 @@
         ],
         "properties": {
             "maxRequestHeaderBytes": {
-                "type": ["null","integer"]
+                "type": [
+                    "null",
+                    "integer"
+                ]
             },
             "firstHeaderRewrite": {
                 "type": [
@@ -1582,5 +1585,32 @@
                 "type": "string"
             }
         }
+    },
+    "delivery_services_regex": {
+        "type": "object",
+        "required": [
+            "id",
+            "type",
+            "typeName",
+            "setNumber",
+            "pattern"
+        ],
+        "properties": {
+            "id": {
+                "type": "integer"
+            },
+            "type": {
+                "type": "integer"
+            },
+            "typeName": {
+                "type": "string"
+            },
+            "setNumber": {
+                "type": "integer"
+            },
+            "pattern": {
+                "type": "string"
+            }
+        }
     }
 }
diff --git 
a/traffic_ops/testing/api_contract/v4/test_delivery_services_regex.py 
b/traffic_ops/testing/api_contract/v4/test_delivery_services_regex.py
new file mode 100644
index 0000000000..f5f3e9a68d
--- /dev/null
+++ b/traffic_ops/testing/api_contract/v4/test_delivery_services_regex.py
@@ -0,0 +1,94 @@
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+"""API Contract Test Case for delivery_services_regex endpoint."""
+import logging
+from random import randint
+from typing import Union
+import pytest
+import requests
+from jsonschema import validate
+
+from trafficops.tosession import TOSession
+
+# Create and configure logger
+logger = logging.getLogger()
+
+Primitive = Union[bool, int, float, str, None]
+
+
+def test_delivery_services_regex_contract(to_session: TOSession,
+       response_template_data: dict[str, Union[Primitive, list[Union[Primitive,
+                                                       dict[str, object], 
list[object]]], dict[object, object]]],
+       delivery_services_regex_post_data: dict[str, object]
+) -> None:
+       """
+       Test step to validate keys, values and data types from 
delivery_services_regex endpoint
+       response.
+       :param to_session: Fixture to get Traffic Ops session.
+       :param response_template_data: Fixture to get response template data 
from a prerequisites file.
+       :param delivery_services_regex_post_data: Fixture to get sample 
delivery service data and response.
+       """
+       # validate delivery_services_regex_regex keys from api get response
+       logger.info("Accessing /delivery_services_regex endpoint through 
Traffic ops session.")
+       delivery_services_id = delivery_services_regex_post_data[0]
+       delivery_services_regex_data_post = delivery_services_regex_post_data[1]
+
+       delivery_services_regex_id = delivery_services_regex_data_post["id"]
+       if not isinstance(delivery_services_regex_id, int):
+               raise TypeError("malformed API response; 'id' property not a 
integer")
+       delivery_services_regex_get_response: tuple[
+               Union[dict[str, object], list[Union[dict[str, object], 
list[object], Primitive]], Primitive],
+               requests.Response
+       ] = 
to_session.get_deliveryservice_regexes_by_id(delivery_service_id=delivery_services_id,
+                                                 query_params={"id": 
delivery_services_regex_id})
+       delivery_services_regex_data_post["pattern"] = ".*\\.test" + 
str(randint(0, 1000)) + "\\..*"
+       logger.info("Updated delivery services regex data to hit PUT method %s",
+            delivery_services_regex_data_post)
+       # Hitting delivery_services_regex PUT method
+       put_response: tuple[
+               Union[dict[str, object], list[Union[dict[str, object], 
list[object], Primitive]], Primitive],
+               requests.Response] = to_session.update_deliveryservice_regexes(
+               delivery_service_id=delivery_services_id, 
regex_id=delivery_services_regex_id,
+           data= delivery_services_regex_data_post)
+       try:
+               delivery_services_regex_data = 
delivery_services_regex_get_response[0]
+               if not isinstance(delivery_services_regex_data, list):
+                       raise TypeError("malformed API response; 'response' 
property not an array")
+
+               first_delivery_services_regex = delivery_services_regex_data[0]
+               if not isinstance(first_delivery_services_regex, dict):
+                       raise TypeError(
+                               "malformed API response; first 
delivery_services_regex in response is not an dict")
+               logger.info("delivery_services_regex Api get response %s", 
first_delivery_services_regex)
+               delivery_services_regex_put_response = put_response[0]
+               if not isinstance(delivery_services_regex_put_response, dict):
+                       raise TypeError("malformed API response; 
delivery_services in response is not an dict")
+               logger.info("delivery_services_regex Api put response %s", 
delivery_services_regex_put_response)
+               delivery_services_regex_response_template = 
response_template_data.get("delivery_services_regex")
+               if not isinstance(delivery_services_regex_response_template, 
dict):
+                       raise TypeError(f"delivery_services_regex response 
template data must be a dict, not '"
+                                                       
f"{type(delivery_services_regex_response_template)}'")
+
+               keys = ["type", "setNumber"]
+               prereq_values = [delivery_services_regex_data_post[key] for key 
in keys]
+               get_values = [first_delivery_services_regex[key] for key in 
keys]
+               assert validate(instance=first_delivery_services_regex,
+                 schema=delivery_services_regex_response_template) is None
+               assert get_values == prereq_values
+               assert validate(instance=delivery_services_regex_put_response,
+                 schema=delivery_services_regex_response_template) is None
+       except IndexError:
+               logger.error("Either prerequisite data or API response was 
malformed")
+               pytest.fail("API contract test failed : API response was 
malformed")

Reply via email to