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 0569aed6de Added api contract test case for delivery_service health ,
capacity and routing endpoints (#7701)
0569aed6de is described below
commit 0569aed6de2bace734ede44afcc75edb06be87dc
Author: Gokula Krishnan <[email protected]>
AuthorDate: Tue Aug 8 01:44:57 2023 +0530
Added api contract test case for delivery_service health , capacity and
routing endpoints (#7701)
* Added api contract test case for delivery_service_health endpoints
* addressed comments
---
.../clients/python/trafficops/tosession.py | 12 +++
.../api_contract/v4/data/response_template.json | 111 +++++++++++++++++++++
.../v4/test_delivery_service_health.py | 104 +++++++++++++++++++
3 files changed, 227 insertions(+)
diff --git a/traffic_control/clients/python/trafficops/tosession.py
b/traffic_control/clients/python/trafficops/tosession.py
index 64aa9b1798..fbb5565e3e 100644
--- a/traffic_control/clients/python/trafficops/tosession.py
+++ b/traffic_control/clients/python/trafficops/tosession.py
@@ -427,6 +427,7 @@ class TOSession(RestApiSession):
:raises: Union[LoginError, OperationError]
"""
+
#
# Capabilities
#
@@ -921,6 +922,17 @@ class TOSession(RestApiSession):
:rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]],
requests.Response]
:raises: Union[LoginError, OperationError]
"""
+
+ @api_request('get', 'deliveryservices/{delivery_service_id:d}/routing',
('3.0', '4.0', '4.1', '5.0'))
+ def get_delivery_service_routing(self, delivery_service_id=None):
+ """
+ Retrieves the aggregated routing percentages for a given
Delivery Service.
+ :ref:`to-api-deliveryservices-id-routing`
+ :param delivery_service_id: The delivery service Id
+ :type delivery_service_id: int
+ :rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]],
requests.Response]
+ :raises: Union[LoginError, OperationError]
+ """
#
# Delivery Service Server
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 ba0151f196..439dbca29a 100644
--- a/traffic_ops/testing/api_contract/v4/data/response_template.json
+++ b/traffic_ops/testing/api_contract/v4/data/response_template.json
@@ -1898,6 +1898,117 @@
}
}
},
+ "delivery_service_capacity": {
+ "type": "object",
+ "required": [
+ "availablePercent",
+ "unavailablePercent",
+ "utilizedPercent",
+ "maintenancePercent"
+ ],
+ "properties": {
+ "availablePercent": {
+ "type": "number"
+ },
+ "unavailablePercent": {
+ "type": "integer"
+ },
+ "utilizedPercent": {
+ "type": "number"
+ },
+ "maintenancePercent": {
+ "type": "integer"
+ }
+ }
+ },
+ "delivery_service_health": {
+ "type": "object",
+ "required": [
+ "totalOffline",
+ "totalOnline",
+ "cachegroups"
+ ],
+ "properties": {
+ "totalOffline": {
+ "type": "integer"
+ },
+ "totalOnline": {
+ "type": "integer"
+ },
+ "cachegroups": {
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "object",
+ "required": [
+ "offline",
+ "name",
+ "online"
+ ],
+ "properties": {
+ "offline": {
+ "type": "integer"
+ },
+ "name": {
+ "type": "string"
+ },
+ "online": {
+ "type": "integer"
+ }
+ }
+ }
+ }
+ }
+ },
+ "delivery_service_routing": {
+ "type": "object",
+ "required": [
+ "cz",
+ "deepCz",
+ "dsr",
+ "err",
+ "fed",
+ "geo",
+ "miss",
+ "regionalAlternate",
+ "regionalDenied",
+ "staticRoute"
+ ],
+ "properties": {
+ "cz": {
+ "type": "integer"
+ },
+ "deepCz": {
+ "type": "number"
+ },
+ "dsr": {
+ "type": "integer"
+ },
+ "err": {
+ "type": "integer"
+ },
+ "fed": {
+ "type": "number"
+ },
+ "geo": {
+ "type": "integer"
+ },
+ "miss": {
+ "type": "number"
+ },
+ "regionalAlternate": {
+ "type": "integer"
+ },
+ "regionalDenied": {
+ "type": "integer"
+ },
+ "staticRoute": {
+ "type": "integer"
+ }
+ }
+ },
"static_dns_entries": {
"type": "object",
"required": [
diff --git
a/traffic_ops/testing/api_contract/v4/test_delivery_service_health.py
b/traffic_ops/testing/api_contract/v4/test_delivery_service_health.py
new file mode 100644
index 0000000000..ca4ac2d8d2
--- /dev/null
+++ b/traffic_ops/testing/api_contract/v4/test_delivery_service_health.py
@@ -0,0 +1,104 @@
+#
+# 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_service health, capacity and routing
endpoints."""
+import logging
+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_service_health_contract(to_session: TOSession,
+ response_template_data: dict[str, Union[Primitive, list[Union[Primitive,
+ dict[str, object],
list[object]]], dict[object, object]]],
+ delivery_services_post_data: dict[str, object]
+) -> None:
+ """
+ Test step to validate keys, values and data types from delivery_service
health, capacity and routing endpoints
+ 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_post_data: Fixture to get sample data and
response.
+ """
+ # validate delivery_service_health keys from api get response
+ logger.info("Accessing /delivery_service_health endpoint through
Traffic ops session.")
+
+ delivery_service_id = delivery_services_post_data["id"]
+ if not isinstance(delivery_service_id, int):
+ raise TypeError("malformed API response; 'id' property not a
integer")
+
+ delivery_service_health_get_response : tuple[
+ Union[dict[str, object], list[Union[dict[str, object],
list[object], Primitive]], Primitive],
+ requests.Response
+ ] =
to_session.get_delivery_service_health(delivery_service_id=delivery_service_id)
+
+ delivery_service_capacity_get_response : tuple[
+ Union[dict[str, object], list[Union[dict[str, object],
list[object], Primitive]], Primitive],
+ requests.Response
+ ] =
to_session.get_delivery_service_capacity(delivery_service_id=delivery_service_id)
+
+ delivery_service_routing_get_response : tuple[
+ Union[dict[str, object], list[Union[dict[str, object],
list[object], Primitive]], Primitive],
+ requests.Response
+ ] =
to_session.get_delivery_service_routing(delivery_service_id=delivery_service_id)
+
+ try:
+ delivery_service_health_data =
delivery_service_health_get_response[0]
+ if not isinstance(delivery_service_health_data, dict):
+ raise TypeError("malformed API response; 'response'
property not an dict")
+ logger.info("delivery_service_health Api response %s",
delivery_service_health_data)
+
+ delivery_service_capacity_data =
delivery_service_capacity_get_response[0]
+ if not isinstance(delivery_service_capacity_data, dict):
+ raise TypeError("malformed API response; 'response'
property not an dict")
+ logger.info("delivery_service_capacity Api response %s",
delivery_service_capacity_data)
+
+ delivery_service_routing_data =
delivery_service_routing_get_response[0]
+ if not isinstance(delivery_service_routing_data, dict):
+ raise TypeError("malformed API response; 'response'
property not an dict")
+ logger.info("delivery_service_routing Api response %s",
delivery_service_routing_data)
+
+ delivery_service_health_response_template =
response_template_data.get(
+ "delivery_service_health")
+ if not isinstance(delivery_service_health_response_template,
dict):
+ raise TypeError(f"delivery_service_health response
template data must be a dict, not '"
+
f"{type(delivery_service_health_response_template)}'")
+
+ delivery_service_capacity_response_template =
response_template_data.get(
+ "delivery_service_capacity")
+ if not isinstance(delivery_service_capacity_response_template,
dict):
+ raise TypeError(f"delivery_service_capacity response
template data must be a dict, not '"
+
f"{type(delivery_service_capacity_response_template)}'")
+
+ delivery_service_routing_response_template =
response_template_data.get(
+ "delivery_service_routing")
+ if not isinstance(delivery_service_routing_response_template,
dict):
+ raise TypeError(f"delivery_service_routing response
template data must be a dict, not '"
+
f"{type(delivery_service_routing_response_template)}'")
+
+ assert validate(instance=delivery_service_health_data,
schema=delivery_service_health_response_template) is None
+ assert validate(instance=delivery_service_capacity_data,
schema=delivery_service_capacity_response_template) is None
+ assert validate(instance=delivery_service_routing_data,
schema=delivery_service_routing_response_template) is None
+ except IndexError:
+ logger.error("Either prerequisite data or API response was
malformed")
+ pytest.fail("API contract test failed for
delivery_service_health endpoints:"
+ "API response was malformed")