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