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 2a5cbd0320 Added Api contract test case for steering endpoint (#7589)
2a5cbd0320 is described below
commit 2a5cbd03204c0a266aeb2d6b827e737ce617d8a7
Author: Gokula Krishnan <[email protected]>
AuthorDate: Tue Jun 27 23:51:10 2023 +0530
Added Api contract test case for steering endpoint (#7589)
* Added Api contract test case for steering endpoint
* Update conftest.py
---
.../clients/python/trafficops/tosession.py | 41 ++++++++++-
traffic_ops/testing/api_contract/v4/conftest.py | 39 +++++++++++
.../api_contract/v4/data/request_template.json | 9 ++-
.../api_contract/v4/data/response_template.json | 35 ++++++++++
.../testing/api_contract/v4/test_steering.py | 79 ++++++++++++++++++++++
5 files changed, 201 insertions(+), 2 deletions(-)
diff --git a/traffic_control/clients/python/trafficops/tosession.py
b/traffic_control/clients/python/trafficops/tosession.py
index cd2dfd1208..e2b820ca87 100644
--- a/traffic_control/clients/python/trafficops/tosession.py
+++ b/traffic_control/clients/python/trafficops/tosession.py
@@ -1936,6 +1936,46 @@ class TOSession(RestApiSession):
:raises: Union[LoginError, OperationError]
"""
+ #
+ # steering_id_targets
+ #
+ @api_request('get', 'steering/{delivery_service_id:d}/targets', ('3.0',
'4.0', '4.1', '5.0'))
+ def get_steering_targets(self, delivery_service_id=None,
query_params=None):
+ """
+ Get all targets for a steering Delivery Service.
+ :ref:`to-api-steering-id-targets`
+ :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]
+ """
+
+ @api_request('post', 'steering/{delivery_service_id:d}/targets',
('3.0', '4.0', '4.1', '5.0'))
+ def create_steering_targets(self, delivery_service_id=None, data=None):
+ """
+ Create a steering target.
+ :ref:`to-api-steering-id-targets`
+ :param delivery_service_id: The delivery service Id
+ :type delivery_service_id: int
+ :param data: The steering(s) data to use for steering creation.
+ :type data: Union[Dict[str, Any], List[Dict[str, Any]]]
+ :rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]],
requests.Response]
+ :raises: Union[LoginError, OperationError]
+ """
+
+ @api_request('delete',
'steering/{delivery_service_id:d}/targets/{target_id:d}', ('3.0', '4.0', '4.1',
'5.0'))
+ def delete_steering_targets(self, delivery_service_id=None,
target_id=None):
+ """
+ Removes a specific target mapping from a specific Delivery
Service.
+ :ref:`to-api-steering-id-targets`
+ :param delivery_service_id: The delivery service Id
+ :type delivery_service_id: int
+ :param target_id: The target Id
+ :type target_id: int
+ :rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]],
requests.Response]
+ :raises: Union[LoginError, OperationError]
+ """
+
#
# System
#
@@ -1948,7 +1988,6 @@ class TOSession(RestApiSession):
:raises: Union[LoginError, OperationError]
"""
-
#
# Tenants
#
diff --git a/traffic_ops/testing/api_contract/v4/conftest.py
b/traffic_ops/testing/api_contract/v4/conftest.py
index 4c904043ea..9b43b98888 100644
--- a/traffic_ops/testing/api_contract/v4/conftest.py
+++ b/traffic_ops/testing/api_contract/v4/conftest.py
@@ -1505,3 +1505,42 @@ def cdn_notification_data_post(to_session: TOSession,
request_template_data: lis
if msg is None:
logger.error("cdn_notfication returned by Traffic Ops is
missing an 'id' property")
pytest.fail("Response from delete request is empty, Failing
test_case")
+
+
+
[email protected](name="steering_post_data")
+def steering_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 steering endpoint.
+ :param to_session: Fixture to get Traffic Ops session.
+ :param request_template_data: Fixture to get steering request template
from a prerequisites file.
+ :returns: Sample POST data and the actual API response.
+ """
+
+ steering = check_template_data(request_template_data["steering"],
"steering")
+
+ # Return new post data and post response from steering POST request
+ ds_get_response = to_session.get_deliveryservices()
+ ds_data = ds_get_response[0][0]
+ delivery_service_id = ds_data.get("id")
+
+ steering["targetId"] = 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": "steering_target"})
+ steering["typeId"]= type_object["id"]
+
+ 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)
+ 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)
+ 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")
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 9db884b0b3..65cd17a48a 100644
--- a/traffic_ops/testing/api_contract/v4/data/request_template.json
+++ b/traffic_ops/testing/api_contract/v4/data/request_template.json
@@ -262,6 +262,13 @@
]
}
],
+ "steering": [
+ {
+ "targetId": 61,
+ "value": 100,
+ "typeId": 43
+ }
+ ],
"cdn_notifications": [
{
"cdn": "cdn1",
@@ -278,4 +285,4 @@
"soft": true
}
]
-}
+}
\ 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 307d57b78b..659bde4892 100644
--- a/traffic_ops/testing/api_contract/v4/data/response_template.json
+++ b/traffic_ops/testing/api_contract/v4/data/response_template.json
@@ -1365,6 +1365,41 @@
}
}
},
+ "steering": {
+ "type": "object",
+ "required": [
+ "deliveryService",
+ "deliveryServiceId",
+ "target",
+ "targetId",
+ "type",
+ "typeId",
+ "value"
+ ],
+ "properties": {
+ "deliveryService": {
+ "type": "string"
+ },
+ "deliveryServiceId": {
+ "type": "integer"
+ },
+ "target": {
+ "type": "string"
+ },
+ "targetId": {
+ "type": "integer"
+ },
+ "type": {
+ "type": "string"
+ },
+ "typeId": {
+ "type": "integer"
+ },
+ "value": {
+ "type": "integer"
+ }
+ }
+ },
"cdn_locks": {
"type": "object",
"required": [
diff --git a/traffic_ops/testing/api_contract/v4/test_steering.py
b/traffic_ops/testing/api_contract/v4/test_steering.py
new file mode 100644
index 0000000000..68e33c2667
--- /dev/null
+++ b/traffic_ops/testing/api_contract/v4/test_steering.py
@@ -0,0 +1,79 @@
+#
+# 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 steering endpoint."""
+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_steering_contract(to_session: TOSession,
+ response_template_data: dict[str, Union[Primitive,
+ list[Union[Primitive, dict[str,
object], list[object]]],
+ dict[object, object]]], steering_post_data: dict[str, object]) -> None:
+ """
+ Test step to validate keys, values and data types from steering 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 steering_post_data: Fixture to get sample steering data and
actual steering response.
+ """
+ # validate steering keys from steering get response
+ logger.info("Accessing /steering endpoint through Traffic ops session.")
+
+ target_id = steering_post_data.get("targetId")
+ if not isinstance(target_id, int):
+ raise TypeError("malformed target in prerequisite data;
'target_id' not a integer")
+ deliveryservice_id = steering_post_data.get("deliveryServiceId")
+ if not isinstance(deliveryservice_id, int):
+ raise TypeError("malformed deliveryservice_id in prerequisite
data; 'deliveryservice_id ' not a integer")
+
+ steering_get_response: tuple[
+ Union[dict[str, object], list[Union[dict[str, object],
list[object], Primitive]], Primitive],
+ requests.Response
+ ] = to_session.get_steering_targets(delivery_service_id =
deliveryservice_id, query_params={"target":target_id})
+ try:
+ steering_data = steering_get_response[0]
+ if not isinstance(steering_data, list):
+ raise TypeError("malformed API response; 'response'
property not an array")
+
+ first_steering = steering_data[0]
+ if not isinstance(first_steering, dict):
+ raise TypeError("malformed API response; first steering
in response is not an dict")
+ logger.info("steering Api get response %s", first_steering)
+
+ steering_response_template =
response_template_data.get("steering")
+ if not isinstance(steering_response_template, dict):
+ raise TypeError(
+ f"steering response template data must be a
dict, not '{type(steering_response_template)}'")
+
+ # validate steering values from prereq data in steering get
response.
+ keys = ["targetId", "value", "typeId"]
+ prereq_values = [steering_post_data[key] for key in keys]
+ get_values = [first_steering[key] for key in keys]
+
+ assert validate(instance=first_steering,
schema=steering_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 steering endpoint:
API response was malformed")