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 cfc4a15739 Added Api contract test case for cdn_federation, 
user_federation and delivery_service_federation endpoint (#7679)
cfc4a15739 is described below

commit cfc4a15739aaf2dc8c003b1da41ff39ed2bb27ff
Author: Gokula Krishnan <[email protected]>
AuthorDate: Wed Aug 2 01:26:21 2023 +0530

    Added Api contract test case for cdn_federation, user_federation and 
delivery_service_federation endpoint (#7679)
    
    * Initial draft
    
    * updated conftest.py
    
    * added tc for cdn_federation & user_federation & 
delivery_Service_federation endpoints
    
    * updated conftest
    
    * updated tosession file
    
    * Addressed comments
    
    * refactored response_template
---
 .../clients/python/trafficops/tosession.py         |  11 +-
 traffic_ops/testing/api_contract/v4/conftest.py    |  44 +++++++
 .../api_contract/v4/data/request_template.json     |  23 ++++
 .../api_contract/v4/data/response_template.json    | 133 +++++++++++++++++++--
 .../testing/api_contract/v4/test_cdn_federation.py | 131 ++++++++++++++++++++
 5 files changed, 333 insertions(+), 9 deletions(-)

diff --git a/traffic_control/clients/python/trafficops/tosession.py 
b/traffic_control/clients/python/trafficops/tosession.py
index d7d56ca591..83d5843296 100644
--- a/traffic_control/clients/python/trafficops/tosession.py
+++ b/traffic_control/clients/python/trafficops/tosession.py
@@ -1217,6 +1217,15 @@ class TOSession(RestApiSession):
                :raises: Union[LoginError, OperationError]
                """
 
+       @api_request('delete', 'federations', ('3.0', '4.0', '4.1', '5.0'))
+       def delete_federation(self):
+               """
+               Allows a user to delete federations for their delivery 
service(s).
+               :ref:`to-api-federations`
+               :rtype: Tuple[Union[Dict[str, Any], List[Dict[str, Any]]], 
requests.Response]
+               :raises: Union[LoginError, OperationError]
+               """
+
 
        @api_request('get', 'cdns/{cdn_name:s}/federations', ('3.0', '4.0', 
'4.1', '5.0'))
        def get_federations_for_cdn(self, cdn_name=None, query_params=None):
@@ -1244,7 +1253,7 @@ class TOSession(RestApiSession):
                """
 
        @api_request('put', 'cdns/{cdn_name:s}/federations/{federation_id:d}', 
('3.0', '4.0', '4.1', '5.0'))
-       def update_federation_in_cdn(self, cdn_name=None, federation_id=None, 
query_params=None):
+       def update_federation_in_cdn(self, cdn_name=None, federation_id=None, 
data=None):
                """
                Update a federation.
                :ref:`to-api-cdns-name-federations-id`
diff --git a/traffic_ops/testing/api_contract/v4/conftest.py 
b/traffic_ops/testing/api_contract/v4/conftest.py
index de8161a3da..f0199682ad 100644
--- a/traffic_ops/testing/api_contract/v4/conftest.py
+++ b/traffic_ops/testing/api_contract/v4/conftest.py
@@ -1645,6 +1645,50 @@ def delivery_services_regex_data_post(to_session: 
TOSession, request_template_da
                pytest.fail("Response from delete request is empty, Failing 
test_case")
 
 
[email protected](name="cdn_federation_post_data")
+def cdn_federation_data_post(to_session: TOSession, request_template_data: 
list[JSONData],
+                 cdn_post_data:dict[str, object], user_post_data:dict[str, 
object],
+                 delivery_services_post_data: dict[str, object]) -> dict[str, 
object]:
+       """
+       PyTest Fixture to create POST data for cdn_name_federations endpoint.
+       :param to_session: Fixture to get Traffic Ops session.
+       :param request_template_data: Fixture to get federations request 
template.
+       :returns: Sample POST data and the actual API response.
+       """
+
+       cdn_federation = 
check_template_data(request_template_data["cdn_federation"], "cdn_federation")
+       # Return new post data and post response from cdn_federation POST 
request
+       cdn_name = cdn_post_data["name"]
+
+       logger.info("New federations data to hit POST method %s", 
cdn_federation)
+       # Hitting cdn_federation POST methed
+       response: tuple[JSONData, requests.Response] = 
to_session.create_federation_in_cdn(cdn_name=cdn_name, data= cdn_federation)
+       cdn_federation_resp_obj = check_template_data(response, 
"cdn_federation")
+       federation_id = cdn_federation_resp_obj.get("id")
+
+       #Assign created federation to a user
+       user_id = user_post_data["id"]
+       user_federation = 
check_template_data(request_template_data["user_federation"], "user_federation")
+       user_federation["userIds"][0] = user_id
+       response: tuple[JSONData, requests.Response] = 
to_session.create_federation_user(federation_id=federation_id, 
data=user_federation)
+       user_federation_resp_obj = check_template_data(response, 
"user_federation")
+
+       #Assign the federation to a delivery_service
+       delivery_service_id = delivery_services_post_data["id"]
+       delivery_service_federation = 
check_template_data(request_template_data["delivery_service_federation"], 
"delivery_service_federation")
+       delivery_service_federation["dsIds"][0] = delivery_service_id
+       response: tuple[JSONData, requests.Response] = 
to_session.assign_delivery_services_to_federations(federation_id=federation_id, 
data=delivery_service_federation)
+       delivery_service_federation_resp_obj = check_template_data(response, 
"delivery_service_federation")
+
+       yield [cdn_name, cdn_federation_resp_obj, cdn_federation, 
federation_id, delivery_service_federation_resp_obj]
+       
+       msg = to_session.delete_federation_in_cdn(cdn_name=cdn_name, 
federation_id=federation_id)
+       logger.info("Deleting cdn_federation dara... %s", msg)
+       if msg is None:
+               logger.error("cdn_federation returned by Traffic Ops is missing 
an 'id' property")
+               pytest.fail("Response from delete request is empty, Failing 
test_case")
+
+
 @pytest.fixture(name="delivery_service_required_capabilities_post_data")
 def delivery_service_required_capabilities_data_post(to_session: TOSession,
                request_template_data: list[JSONData], 
delivery_services_post_data:dict[str, object],
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 d7af2a8b2d..8817c28a0c 100644
--- a/traffic_ops/testing/api_contract/v4/data/request_template.json
+++ b/traffic_ops/testing/api_contract/v4/data/request_template.json
@@ -396,6 +396,29 @@
                        "setNumber": 1
                }
        ],
+       "cdn_federation": [
+               {
+                       "cname": "test.quest.",
+                       "ttl": 48,
+                       "description": "A test federation"
+               }
+       ],
+       "user_federation": [
+               {
+                       "userIds": [
+                               2
+                       ],
+                       "replace": true
+               }
+       ],
+       "delivery_service_federation": [
+               {
+                       "dsIds": [
+                               37
+                       ],
+                       "replace": true
+      }
+       ],
        "delivery_service_required_capabilities": [
                {
                        "deliveryServiceID": 1,
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 c03a41a991..79a91773ca 100644
--- a/traffic_ops/testing/api_contract/v4/data/response_template.json
+++ b/traffic_ops/testing/api_contract/v4/data/response_template.json
@@ -1680,26 +1680,24 @@
             },
             "pattern": {
                 "type": "string"
-
             }
         }
     },
-     "profile_parameters": {
+    "profile_parameters": {
         "type": "object",
-        "required":[
+        "required": [
             "lastUpdated",
             "profile",
             "parameter"
         ],
-        "properties":{
-            "lastUpdated":{
+        "properties": {
+            "lastUpdated": {
                 "type": "string"
             },
-            "profile":{
+            "profile": {
                 "type": "string"
-
             },
-            "parameter":{
+            "parameter": {
                 "type": "integer"
             }
         }
@@ -1757,5 +1755,124 @@
                 "type": "string"
             }
         }
+    },
+    "cdn_federation": {
+        "definitions": {
+            "deliveryService": {
+                "type": "object",
+                "required": [
+                    "id",
+                    "xmlId"
+                ],
+                "properties": {
+                    "id": {
+                        "type": "integer"
+                    },
+                    "xmlId": {
+                        "type": "string"
+                    }
+                }
+            }
+        },
+        "allOf": [
+            {
+                "type": "object",
+                "required": [
+                    "id",
+                    "cname",
+                    "ttl",
+                    "description",
+                    "lastUpdated"
+                ],
+                "properties": {
+                    "id": {
+                        "type": "integer"
+                    },
+                    "cname": {
+                        "type": "string"
+                    },
+                    "ttl": {
+                        "type": "integer"
+                    },
+                    "description": {
+                        "type": "string"
+                    },
+                    "lastUpdated": {
+                        "type": "string"
+                    }
+                }
+            },
+            {
+                "type": "object",
+                "properties": {
+                    "deliveryService": {
+                        "$ref": "#/definitions/deliveryService"
+                    }
+                }
+            }
+        ]
+    },
+    "user_federation": {
+        "type": "object",
+        "required": [
+            "fullName",
+            "email",
+            "id",
+            "role",
+            "company",
+            "username"
+        ],
+        "properties": {
+            "fullName": {
+                "type": [
+                    "string",
+                    "null"
+                ]
+            },
+            "email": {
+                "type": [
+                    "string",
+                    "null"
+                ]
+            },
+            "id": {
+                "type": "integer"
+            },
+            "role": {
+                "type": "string"
+            },
+            "company": {
+                "type": [
+                    "string",
+                    "null"
+                ]
+            },
+            "username": {
+                "type": "string"
+            }
+        }
+    },
+    "delivery_service_federation": {
+        "type": "object",
+        "required": [
+            "id",
+            "cdn",
+            "type",
+            "xmlId"
+        ],
+        "properties": {
+            "id": {
+                "type": "integer"
+            },
+            "cdn": {
+                "type": "string"
+            },
+            "type": {
+                "type": "string"
+            },
+            "xmlId": {
+                "type": "string"
+            }
+        }
     }
 }
diff --git a/traffic_ops/testing/api_contract/v4/test_cdn_federation.py 
b/traffic_ops/testing/api_contract/v4/test_cdn_federation.py
new file mode 100644
index 0000000000..4aa423794b
--- /dev/null
+++ b/traffic_ops/testing/api_contract/v4/test_cdn_federation.py
@@ -0,0 +1,131 @@
+#
+# 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 cdn_federation endpoint."""
+import logging
+from random import randint
+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_cdn_federation_contract(to_session: TOSession,
+       response_template_data: dict[str, Union[Primitive, list[Union[Primitive,
+                                                       dict[str, object], 
list[object]]], dict[object, object]]],
+       cdn_federation_post_data: dict[str, object]
+) -> None:
+       """
+       Test step to validate keys, values and data types from cdn_federation 
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 cdn_federation_post_data: Fixture to get delivery services 
sslkeys data.
+       """
+       # validate cdn_federation keys from api get response
+       logger.info("Accessing /cdn_federation endpoint through Traffic ops 
session.")
+
+       cdn_name = cdn_federation_post_data[0]
+       cdn_federation_data_post = cdn_federation_post_data[1]
+       cdn_federation_sample_data = cdn_federation_post_data[2]
+       federation_id = cdn_federation_post_data[3]
+       if not isinstance(cdn_name, str):
+               raise TypeError("malformed API response; 'cdn_name' property 
not a string")
+
+       cdn_federation_get_response: tuple[
+               Union[dict[str, object], list[Union[dict[str, object], 
list[object], Primitive]], Primitive],
+               requests.Response
+       ] = to_session.get_federations_for_cdn(cdn_name=cdn_name)
+       
+       user_federation_get_response: tuple[
+               Union[dict[str, object], list[Union[dict[str, object], 
list[object], Primitive]], Primitive],
+               requests.Response
+       ] = to_session.get_federation_users(federation_id=federation_id)
+
+       delivery_service_federation_get_response: tuple[
+               Union[dict[str, object], list[Union[dict[str, object], 
list[object], Primitive]], Primitive],
+               requests.Response
+       ] = 
to_session.get_federation_delivery_services(federation_id=federation_id)
+       
+    # Hitting cdn_federation PUT method
+       cdn_federation_sample_data["description"] = "test" + str(randint(0, 
1000)) 
+       logger.info("Updated cdn federation data to hit PUT method %s", 
cdn_federation_sample_data)
+       cdn_federation_put_response: tuple[
+               Union[dict[str, object], list[Union[dict[str, object], 
list[object], Primitive]], Primitive], 
+               requests.Response] = to_session.update_federation_in_cdn(
+               cdn_name=cdn_name, federation_id=federation_id, data= 
cdn_federation_sample_data)
+    
+       try:
+               cdn_federation = cdn_federation_get_response[0]
+               if not isinstance(cdn_federation, list):
+                       raise TypeError(
+                               "malformed API response; first cdn_federation 
in response is not an dict")
+               first_cdn_federation = cdn_federation[0]
+
+               user_federation = user_federation_get_response[0]
+               if not isinstance(user_federation, list):
+                       raise TypeError(
+                               "malformed API response; first user_federation 
in response is not an dict")
+               first_user_federation = user_federation[0]
+       
+               delivery_service_federation = 
delivery_service_federation_get_response[0]
+               if not isinstance(delivery_service_federation, list):
+                       raise TypeError(
+                               "malformed API response; first 
delivery_service_federation in response is not an dict")
+               first_delivery_service_federation = 
delivery_service_federation[0]
+               
+               cdn_federation_put_data = cdn_federation_put_response[0]
+               if not isinstance(cdn_federation_put_data, dict):
+                       raise TypeError(
+                               "malformed API response; first 
cdn_federation_put in response is not an dict")
+
+               cdn_federation_response_template = response_template_data.get(
+                       "cdn_federation")
+               if not isinstance(cdn_federation_response_template, dict):
+                       raise TypeError(f"cdn_federation response template data 
must be a dict, not '"
+                                                       
f"{type(cdn_federation_response_template)}'")
+
+               user_federation_response_template = response_template_data.get(
+                       "user_federation")
+               if not isinstance(user_federation_response_template, dict):
+                       raise TypeError(f"user_federation response template 
data must be a dict, not '"
+                                                       
f"{type(user_federation_response_template)}'")
+
+               delivery_service_federation_response_template = 
response_template_data.get(
+                       "delivery_service_federation")
+               if not 
isinstance(delivery_service_federation_response_template, dict):
+                       raise TypeError(f"delivery_service_federation response 
template data must be a dict, not '"
+                                                       
f"{type(user_federation_response_template)}'")
+
+               keys = ["cname", "ttl"]
+               prereq_values = [cdn_federation_data_post[key] for key in keys]
+               get_values = [first_cdn_federation[key] for key in keys]
+
+               assert validate(instance=first_cdn_federation, 
schema=cdn_federation_response_template) is None
+               assert validate(instance=first_user_federation, 
schema=user_federation_response_template) is None
+               assert validate(instance=first_delivery_service_federation, 
schema=delivery_service_federation_response_template) is None
+               assert validate(instance=cdn_federation_put_data, 
schema=cdn_federation_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 cdn_federation endpoint: 
API response was malformed")

Reply via email to