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 09bb63bc9a Added api contract test case for logs endpoint (#7788)
09bb63bc9a is described below

commit 09bb63bc9a4321420f287dafb1eb78c814a68c76
Author: Kash Blanc <[email protected]>
AuthorDate: Thu Sep 14 12:55:01 2023 -0400

    Added api contract test case for logs endpoint (#7788)
    
    * logs test passing
    
    * updated ticketNum type
    
    * Updated logs_data variable and TicketNum Type
    
    * added null to pointers
    
    ---------
    
    Co-authored-by: yblanc545 <[email protected]>
---
 traffic_ops/testing/api_contract/v4/conftest.py    | 28 ++++++--
 .../api_contract/v4/data/request_template.json     | 11 ++-
 .../api_contract/v4/data/response_template.json    | 49 +++++++++++++
 traffic_ops/testing/api_contract/v4/test_logs.py   | 84 ++++++++++++++++++++++
 4 files changed, 167 insertions(+), 5 deletions(-)

diff --git a/traffic_ops/testing/api_contract/v4/conftest.py 
b/traffic_ops/testing/api_contract/v4/conftest.py
index 3a7e48e30c..660dbb167d 100644
--- a/traffic_ops/testing/api_contract/v4/conftest.py
+++ b/traffic_ops/testing/api_contract/v4/conftest.py
@@ -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
@@ -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:
@@ -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]
@@ -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)
@@ -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")
+
+
[email protected](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]
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 25a838ecf0..51227dff34 100644
--- a/traffic_ops/testing/api_contract/v4/data/request_template.json
+++ b/traffic_ops/testing/api_contract/v4/data/request_template.json
@@ -472,5 +472,14 @@
                        "serverId": 1,
                        "serverCapability": "disk"
        }
-       ]
+       ],
+         "logs":[
+               {
+                       "ticketNum": null,
+                       "level": "APICHANGE",
+                       "user": "admin",
+                       "id": 444,
+                       "message": "log for test purposes"
+               }
+       ]
 }
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 7353afd971..a2454f3483 100644
--- a/traffic_ops/testing/api_contract/v4/data/response_template.json
+++ b/traffic_ops/testing/api_contract/v4/data/response_template.json
@@ -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"
+                ]
+            }
+        }
     }
 }
diff --git a/traffic_ops/testing/api_contract/v4/test_logs.py 
b/traffic_ops/testing/api_contract/v4/test_logs.py
new file mode 100644
index 0000000000..430a72142f
--- /dev/null
+++ b/traffic_ops/testing/api_contract/v4/test_logs.py
@@ -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)}")

Reply via email to