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 72202be7b3 Added Api contract test case for delivery_Service_requests 
endpoint (#7601)
72202be7b3 is described below

commit 72202be7b3538517a77f5b59643cc174bc6158fa
Author: Gokula Krishnan <[email protected]>
AuthorDate: Wed Jul 5 23:44:48 2023 +0530

    Added Api contract test case for delivery_Service_requests endpoint (#7601)
    
    Added delivery_Service_requests TC
---
 .../clients/python/trafficops/tosession.py         |  44 ++++++++
 traffic_ops/testing/api_contract/v4/conftest.py    |  29 ++++-
 .../api_contract/v4/data/request_template.json     |  91 +++++++++++++++
 .../api_contract/v4/data/response_template.json    | 124 ++++++++++++++++++++-
 .../testing/api_contract/v4/requirements.txt       |   3 +-
 .../v4/test_delivery_service_requests.py           |  82 ++++++++++++++
 6 files changed, 370 insertions(+), 3 deletions(-)

diff --git a/traffic_control/clients/python/trafficops/tosession.py 
b/traffic_control/clients/python/trafficops/tosession.py
index e2b820ca87..0772c19dcf 100644
--- a/traffic_control/clients/python/trafficops/tosession.py
+++ b/traffic_control/clients/python/trafficops/tosession.py
@@ -775,6 +775,50 @@ class TOSession(RestApiSession):
                :raises: Union[LoginError, OperationError]
                """
 
+
+    #
+       # Delivery Service Requests
+       #
+       @api_request('get', 'deliveryservice_requests', ('3.0', '4.0', '4.1', 
'5.0'))
+       def get_deliveryservice_requests(self, query_params=None):
+               """
+               Retrieves all delivery service reuests.
+               :ref:`to-api-deliveryservice-requests`
+               :rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], 
requests.Response]
+               :raises: Union[LoginError, OperationError]
+               """
+
+       @api_request('post', 'deliveryservice_requests', ('3.0', '4.0', '4.1', 
'5.0'))
+       def create_deliveryservice_request(self, data=None):
+               """
+               Creates a new delivery service request.
+               :ref:`to-api-deliveryservice-requests`
+               :param data: The request data structure for the API request
+               :type data: Dict[str, Any]
+               :rtype: Tuple[Dict[str, Any], requests.Response]
+               :raises: Union[LoginError, OperationError]
+               """
+
+       @api_request('put', 'deliveryservice_requests', ('3.0', '4.0', '4.1', 
'5.0'))
+       def update_deliveryservice_request(self, query_params=None, data=None):
+               """
+               Updates an existing Delivery Service Request.
+               :ref:`to-api-deliveryservice-requests`
+               :param data: The request data structure for the API request
+               :type data: Dict[str, Any]
+               :rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], 
requests.Response]
+               :raises: Union[LoginError, OperationError]
+               """
+
+       @api_request('delete', 'deliveryservice_requests', ('3.0', '4.0', 
'4.1', '5.0'))
+       def delete_deliveryservice_request(self, query_params=None):
+               """
+               Deletes a Delivery Service Request.
+               :ref:`to-api-deliveryservice-requests`
+               :rtype: Tuple[Dict[str, Any], requests.Response]
+               :raises: Union[LoginError, OperationError]
+               """
+
        #
        # Delivery Service Health
        #
diff --git a/traffic_ops/testing/api_contract/v4/conftest.py 
b/traffic_ops/testing/api_contract/v4/conftest.py
index 9b43b98888..02deae62e9 100644
--- a/traffic_ops/testing/api_contract/v4/conftest.py
+++ b/traffic_ops/testing/api_contract/v4/conftest.py
@@ -1482,7 +1482,7 @@ def cdn_lock_data_post(to_session: TOSession, 
request_template_data: list[JSONDa
 
 @pytest.fixture(name="cdn_notification_post_data")
 def cdn_notification_data_post(to_session: TOSession, request_template_data: 
list[JSONData],
-                 cdn_post_data:dict[str, object], db_connection: 
psycopg2.connect) -> dict[str, object]:
+                 cdn_post_data:dict[str, object]) -> dict[str, object]:
        """
        PyTest Fixture to create POST data for cdn_notifications endpoint.
        :param to_session: Fixture to get Traffic Ops session.
@@ -1507,6 +1507,33 @@ def cdn_notification_data_post(to_session: TOSession, 
request_template_data: lis
                pytest.fail("Response from delete request is empty, Failing 
test_case")
 
 
[email protected](name="deliveryservice_request_post_data")
+def deliveryservice_request_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 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.
+       :returns: Sample POST data and the actual API response.
+       """
+
+       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"]
+       for key in keys:
+               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)
+       resp_obj = check_template_data(response, "deliveryservice_request")
+       yield resp_obj
+       deliveryservice_request_id = resp_obj.get("id")
+       msg = 
to_session.delete_deliveryservice_request(query_params={"id":deliveryservice_request_id})
+       logger.info("Deleting deliveryservice_request data... %s", msg)
+       if msg is None:
+               logger.error("deliveryservice_request returned by Traffic Ops 
is missing an 'id' property")
+
 
 @pytest.fixture(name="steering_post_data")
 def steering_data_post(to_session: TOSession, request_template_data: 
list[JSONData],
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 65cd17a48a..d91277a736 100644
--- a/traffic_ops/testing/api_contract/v4/data/request_template.json
+++ b/traffic_ops/testing/api_contract/v4/data/request_template.json
@@ -284,5 +284,96 @@
                        ],
                        "soft": true
                }
+       ],
+       "deliveryservice_requests": [
+               {
+                       "changeType": "update",
+                       "status": "draft",
+                       "requested": {
+                               "active": false,
+                               "anonymousBlockingEnabled": false,
+                               "cacheurl": null,
+                               "ccrDnsTtl": null,
+                               "cdnId": 2,
+                               "cdnName": "CDN-in-a-Box",
+                               "checkPath": null,
+                               "displayName": "test",
+                               "dnsBypassCname": null,
+                               "dnsBypassIp": null,
+                               "dnsBypassIp6": null,
+                               "dnsBypassTtl": null,
+                               "dscp": 0,
+                               "edgeHeaderRewrite": null,
+                               "firstHeaderRewrite": null,
+                               "geoLimit": 0,
+                               "geoLimitCountries": null,
+                               "geoLimitRedirectURL": null,
+                               "geoProvider": 0,
+                               "globalMaxMbps": null,
+                               "globalMaxTps": null,
+                               "httpBypassFqdn": null,
+                               "id": 3,
+                               "infoUrl": null,
+                               "initialDispersion": 1,
+                               "innerHeaderRewrite": null,
+                               "ipv6RoutingEnabled": true,
+                               "lastHeaderRewrite": null,
+                               "lastUpdated": "2020-02-13T16:43:54Z",
+                               "logsEnabled": true,
+                               "longDesc": "Apachecon North America 2018",
+                               "matchList": [
+                                       {
+                                               "type": "HOST_REGEXP",
+                                               "setNumber": 0,
+                                               "pattern": ".*\\.demo1\\..*"
+                                       }
+                               ],
+                               "maxDnsAnswers": null,
+                               "midHeaderRewrite": null,
+                               "missLat": 42,
+                               "missLong": -88,
+                               "multiSiteOrigin": false,
+                               "originShield": null,
+                               "orgServerFqdn": 
"http://origin.infra.ciab.test";,
+                               "profileDescription": null,
+                               "profileId": null,
+                               "profileName": null,
+                               "protocol": 2,
+                               "qstringIgnore": 0,
+                               "rangeRequestHandling": 0,
+                               "regexRemap": null,
+                               "regionalGeoBlocking": false,
+                               "remapText": null,
+                               "routingName": "video",
+                               "signed": false,
+                               "sslKeyVersion": 1,
+                               "tenantId": 1,
+                               "type": "HTTP",
+                               "typeId": 1,
+                               "xmlId": "test",
+                               "exampleURLs": [
+                                       "http://video.demo1.mycdn.ciab.test";,
+                                       "https://video.demo1.mycdn.ciab.test";
+                               ],
+                               "deepCachingType": "NEVER",
+                               "fqPacingRate": null,
+                               "signingAlgorithm": null,
+                               "tenant": "root",
+                               "topology": null,
+                               "trResponseHeaders": null,
+                               "trRequestHeaders": null,
+                               "consistentHashRegex": null,
+                               "consistentHashQueryParams": [
+                                       "abc",
+                                       "pdq",
+                                       "xxx",
+                                       "zyx"
+                               ],
+                               "maxOriginConnections": 0,
+                               "ecsEnabled": false,
+                               "serviceCategory": null,
+                               "tlsVersions": null
+                       }
+               }
        ]
 }
\ 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 659bde4892..c859ceab71 100644
--- a/traffic_ops/testing/api_contract/v4/data/response_template.json
+++ b/traffic_ops/testing/api_contract/v4/data/response_template.json
@@ -656,9 +656,81 @@
     },
     "delivery_services": {
         "type": "object",
+        "required": [
+            "maxRequestHeaderBytes",
+            "firstHeaderRewrite",
+            "innerHeaderRewrite",
+            "lastHeaderRewrite",
+            "serviceCategory",
+            "topology",
+            "ecsEnabled",
+            "rangeSliceBlockSize",
+            "consistentHashRegex",
+            "consistentHashQueryParams",
+            "maxOriginConnections",
+            "deepCachingType",
+            "fqPacingRate",
+            "signingAlgorithm",
+            "tenant",
+            "trResponseHeaders",
+            "trRequestHeaders",
+            "active",
+            "anonymousBlockingEnabled",
+            "ccrDnsTtl",
+            "cdnId",
+            "cdnName",
+            "checkPath",
+            "displayName",
+            "dnsBypassCname",
+            "dnsBypassIp",
+            "dnsBypassIp6",
+            "dnsBypassTtl",
+            "dscp",
+            "edgeHeaderRewrite",
+            "exampleURLs",
+            "geoLimit",
+            "geoLimitRedirectURL",
+            "geoProvider",
+            "globalMaxMbps",
+            "globalMaxTps",
+            "httpBypassFqdn",
+            "id",
+            "infoUrl",
+            "initialDispersion",
+            "ipv6RoutingEnabled",
+            "lastUpdated",
+            "logsEnabled",
+            "longDesc",
+            "matchList",
+            "maxDnsAnswers",
+            "midHeaderRewrite",
+            "missLat",
+            "missLong",
+            "multiSiteOrigin",
+            "originShield",
+            "orgServerFqdn",
+            "profileDescription",
+            "profileId",
+            "profileName",
+            "protocol",
+            "qstringIgnore",
+            "rangeRequestHandling",
+            "regexRemap",
+            "regionalGeoBlocking",
+            "remapText",
+            "routingName",
+            "signed",
+            "sslKeyVersion",
+            "tenantId",
+            "type",
+            "typeId",
+            "xmlId",
+            "tlsVersions",
+            "geoLimitCountries"
+        ],
         "properties": {
             "maxRequestHeaderBytes": {
-                "type": "integer"
+                "type": ["null","integer"]
             },
             "firstHeaderRewrite": {
                 "type": [
@@ -1460,5 +1532,55 @@
                 "type": "string"
             }
         }
+    },
+    "deliveryservice_requests": {
+        "type": "object",
+        "required": [
+            "assignee",
+            "author",
+            "changeType",
+            "createdAt",
+            "id",
+            "lastEditedBy",
+            "lastUpdated",
+            "original",
+            "requested",
+            "status"
+        ],
+        "properties": {
+            "assignee": {
+                "type": [
+                    "string",
+                    "null"
+                ]
+            },
+            "author": {
+                "type": "string"
+            },
+            "changeType": {
+                "type": "string"
+            },
+            "createdAt": {
+                "type": "string"
+            },
+            "id": {
+                "type": "integer"
+            },
+            "lastEditedBy": {
+                "type": "string"
+            },
+            "lastUpdated": {
+                "type": "string"
+            },
+            "original": {
+                "$ref": "#/delivery_services"
+            },
+            "requested": {
+                "$ref": "#/delivery_services"
+            },
+            "status": {
+                "type": "string"
+            }
+        }
     }
 }
diff --git a/traffic_ops/testing/api_contract/v4/requirements.txt 
b/traffic_ops/testing/api_contract/v4/requirements.txt
index 5076bb3826..00f8f59677 100644
--- a/traffic_ops/testing/api_contract/v4/requirements.txt
+++ b/traffic_ops/testing/api_contract/v4/requirements.txt
@@ -14,4 +14,5 @@
 
 pytest==7.2.1
 jsonschema==4.17.3
-psycopg2-binary==2.9.6
\ No newline at end of file
+psycopg2-binary==2.9.6
+jsonref==1.1.0
\ No newline at end of file
diff --git 
a/traffic_ops/testing/api_contract/v4/test_delivery_service_requests.py 
b/traffic_ops/testing/api_contract/v4/test_delivery_service_requests.py
new file mode 100644
index 0000000000..0c65dc6470
--- /dev/null
+++ b/traffic_ops/testing/api_contract/v4/test_delivery_service_requests.py
@@ -0,0 +1,82 @@
+#
+# 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 deliveryservice_request endpoint."""
+import json
+import logging
+from typing import Union
+import pytest
+import jsonref
+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_deliveryservice_request_contract(to_session: TOSession,
+       response_template_data: dict[str, Union[Primitive, list[Union[Primitive,
+                                                       dict[str, object], 
list[object]]], dict[object, object]]],
+       deliveryservice_request_post_data: dict[str, object]
+) -> None:
+       """
+       Test step to validate keys, values and data types from 
deliveryservice_request 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 deliveryservice_request_post_data: Fixture to get sample 
delivery service data and response.
+       """
+       # validate deliveryservice_request keys from api get response
+       logger.info("Accessing /deliveryservice_request endpoint through 
Traffic ops session.")
+
+       deliveryservice_request_id = deliveryservice_request_post_data["id"]
+       if not isinstance(deliveryservice_request_id, int):
+               raise TypeError("malformed API response; 'id' property not a 
integer")
+
+       deliveryservice_request_get_response: tuple[
+               Union[dict[str, object], list[Union[dict[str, object], 
list[object], Primitive]], Primitive],
+               requests.Response
+       ] = to_session.get_deliveryservice_requests(query_params={"id": 
deliveryservice_request_id})
+       try:
+               deliveryservice_request_data = 
deliveryservice_request_get_response[0]
+               if not isinstance(deliveryservice_request_data, list):
+                       raise TypeError("malformed API response; 'response' 
property not an array")
+
+               first_deliveryservice_request = deliveryservice_request_data[0]
+               if not isinstance(first_deliveryservice_request, dict):
+                       raise TypeError("malformed API response; first 
deliveryservice_request in response is not an dict")
+               logger.info("deliveryservice_request Api response %s", 
first_deliveryservice_request)
+
+               # Resolve $ref references in the schema
+               scheme_str = json.dumps(response_template_data)
+               response_data = jsonref.loads(scheme_str)
+               deliveryservice_request_response_template = 
response_data.get("deliveryservice_requests")
+               if not isinstance(deliveryservice_request_response_template, 
dict):
+                       raise TypeError(f"deliveryservice_request response 
template data must be a dict, not '"
+                                                       
f"{type(deliveryservice_request_response_template)}'")
+
+               keys = ["displayName", "xmlId", "id", "cdnId", "tenantId", 
"type", "typeId"]
+               prereq_values = 
[deliveryservice_request_post_data["requested"][key] for key in keys]
+               get_values = [first_deliveryservice_request["requested"][key] 
for key in keys]
+
+               assert validate(instance=first_deliveryservice_request,
+                 schema=deliveryservice_request_response_template) is None
+               assert get_values == prereq_values
+       except IndexError:
+               logger.error("Either prerequisite data or API response was 
malformed")
+               pytest.fail("API contract test failed for 
deliveryservice_request endpoint: API response was malformed")

Reply via email to