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

Reply via email to