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")