Skip to content

Commit

Permalink
Added api contract test case for logs endpoint (#7788)
Browse files Browse the repository at this point in the history
* logs test passing

* updated ticketNum type

* Updated logs_data variable and TicketNum Type

* added null to pointers

---------

Co-authored-by: yblanc545 <Yves-Richard_Blanc@comcast.com>
  • Loading branch information
Kashatlast2 and yblanc545 committed Sep 14, 2023
1 parent a2720ee commit 09bb63b
Show file tree
Hide file tree
Showing 4 changed files with 167 additions and 5 deletions.
28 changes: 24 additions & 4 deletions traffic_ops/testing/api_contract/v4/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -1105,7 +1105,7 @@ def server_data_post(to_session: TOSession, request_template_data: list[JSONData
server["typeId"] = type_id

pytestconfig.cache.set("typeId", type_id)

server["cachegroupId"]= cache_group_post_data["id"]

# Check if cdn already exists, otherwise create it
Expand Down Expand Up @@ -1698,7 +1698,7 @@ def cdn_federation_data_post(to_session: TOSession, request_template_data: list[
federation_federation_resolver_resp_obj = check_template_data(response, "federation_federation_resolver")

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:
Expand Down Expand Up @@ -1774,7 +1774,7 @@ def delivery_service_request_comments_data_post(to_session: TOSession,
logger.error("delivery_service_request_comments returned by Traffic Ops is missing an 'id' property")
pytest.fail("Response from delete request is empty, Failing test_case")


@pytest.fixture(name="profile_parameters_post_data")
def profile_parameters_post_data(to_session: TOSession, request_template_data: list[JSONData],
profile_post_data:dict[str, object], parameter_post_data:dict[str, object]
Expand Down Expand Up @@ -1860,7 +1860,7 @@ def federation_resolver_data_post(to_session: TOSession, request_template_data:
type_object = create_or_get_existing(to_session, "types", "type", type_data,
{"useInTable": "federation"})
federation_resolver["typeId"] = type_object["id"]
federation_resolver["ipAddress"] = ".".join(map(str, (randint(0, 255)
federation_resolver["ipAddress"] = ".".join(map(str, (randint(0, 255)
for _ in range(4))))

logger.info("New federation_resolver data to hit POST method %s", federation_resolver)
Expand Down Expand Up @@ -1949,3 +1949,23 @@ def server_server_capabilities_data_post(to_session: TOSession, edge_type_data:N
if msg is None:
logger.error("Server Server Capability returned by Traffic Ops is missing a 'server_id' property")
pytest.fail("Response from delete request is empty, Failing test_case")


@pytest.fixture(name="logs_data")
def logs_data(to_session: TOSession, request_template_data: list[JSONData],
) -> dict[str, object]:
"""
PyTest Fixture to retrieve log data from logs endpoint.
:param to_session: Fixture to get Traffic Ops session.
:returns: Log data obtained from logs endpoint.
"""

change_logs = check_template_data(request_template_data["logs"], "logs")


# Hitting logs GET methed
response: tuple[JSONData, requests.Response] = to_session.get_change_logs(data=change_logs)
resp_obj = check_template_data(response[0], "change_logs")
change_log_id = resp_obj.get("id")

yield [change_log_id, resp_obj]
11 changes: 10 additions & 1 deletion traffic_ops/testing/api_contract/v4/data/request_template.json
Original file line number Diff line number Diff line change
Expand Up @@ -472,5 +472,14 @@
"serverId": 1,
"serverCapability": "disk"
}
]
],
"logs":[
{
"ticketNum": null,
"level": "APICHANGE",
"user": "admin",
"id": 444,
"message": "log for test purposes"
}
]
}
49 changes: 49 additions & 0 deletions traffic_ops/testing/api_contract/v4/data/response_template.json
Original file line number Diff line number Diff line change
Expand Up @@ -2252,5 +2252,54 @@
}
}
}
},
"logs":{
"type": "object",
"required": [
"ticketNum",
"level",
"lastUpdated",
"user",
"id",
"message"
],
"properties": {
"ticketNum": {
"type": [
"integer",
"null"
]
},
"level": {
"type": [
"string",
"null"
]
},
"lastUpdated": {
"type": [
"string",
"null"
]
},
"user": {
"type": [
"string",
"null"
]
},
"id": {
"type": [
"integer",
"null"
]
},
"message": {
"type": [
"string",
"null"
]
}
}
}
}
84 changes: 84 additions & 0 deletions traffic_ops/testing/api_contract/v4/test_logs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
#
# 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 logs 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_logs_contract(
to_session: TOSession,
response_template_data: dict[str, Union[Primitive, list[Union[Primitive, dict[str, object],
list[object]]], dict[object, object]]], logs_data: list[Union[int, dict[str, object]]]) -> None:
"""
Test step to validate keys, values, and data types from logs endpoint response.
:param to_session: Fixture to get Traffic Ops session.
:param response_template_data: Fixture to get response template data from prerequisites file.
"""
# Validate Log keys from logs get response
logger.info("Accessing /logs endpoint through Traffic ops session.")

for log in logs_data:
if isinstance(log, dict):
change_log_id = log.get("id")
if not isinstance(change_log_id, int):
raise TypeError("Malformed log in prerequisite data; 'id' not an integer")

# Hitting logs GET response
change_logs_get_response: tuple[JSONData, requests.Response] = to_session.get_change_logs()

logs_data, _ = change_logs_get_response

try:
logs_data = change_logs_get_response[0]
if not isinstance(logs_data, list):
raise TypeError("Malformed API response; 'response' property not an array")

first_change_log = logs_data[0]
if not isinstance(first_change_log, dict):
raise TypeError("Malformed API response; first Log in response is not an object")
logger.info("Logs API get response %s", first_change_log)

change_log_response_template = response_template_data.get("logs")
if not isinstance(change_log_response_template, dict):
raise TypeError(
f"Log response template data must be a dict, not '{type(change_log_response_template)}'")

# Validate log values from prereq data in change logs get response.
keys = ["id", "user"]
prereq_values = [change_log_id, first_change_log["user"]]
get_values = [first_change_log[key] for key in keys]

assert validate(instance=first_change_log, schema=change_log_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 logs endpoint: API response was malformed")
elif isinstance(log, int):
# Handle the case where log_data is an integer
pass
else:
raise TypeError(f"Malformed log in prerequisite data; expected dictionary or integer, got {type(log)}")

0 comments on commit 09bb63b

Please sign in to comment.