forked from phoenix/litellm-mirror
* add unit testing for standard logging payload * unit testing for static methods in litellm_logging * add code coverage check for litellm_logging * litellm_logging_code_coverage * test_get_final_response_obj * fix validate_redacted_message_span_attributes * test validate_redacted_message_span_attributes
95 lines
3.1 KiB
Python
95 lines
3.1 KiB
Python
import ast
|
|
import os
|
|
from typing import List
|
|
|
|
|
|
def get_function_names_from_file(file_path: str) -> List[str]:
|
|
"""
|
|
Extracts all static method names from litellm_logging.py
|
|
"""
|
|
with open(file_path, "r") as file:
|
|
tree = ast.parse(file.read())
|
|
|
|
function_names = []
|
|
|
|
for node in tree.body:
|
|
if isinstance(node, ast.ClassDef):
|
|
# Functions inside classes
|
|
for class_node in node.body:
|
|
if isinstance(class_node, (ast.FunctionDef, ast.AsyncFunctionDef)):
|
|
# Check if the function has @staticmethod decorator
|
|
for decorator in class_node.decorator_list:
|
|
if (
|
|
isinstance(decorator, ast.Name)
|
|
and decorator.id == "staticmethod"
|
|
):
|
|
function_names.append(class_node.name)
|
|
|
|
return function_names
|
|
|
|
|
|
def get_all_functions_called_in_tests(base_dir: str) -> set:
|
|
"""
|
|
Returns a set of function names that are called in test functions
|
|
inside test files containing the word 'logging'.
|
|
"""
|
|
called_functions = set()
|
|
|
|
for root, _, files in os.walk(base_dir):
|
|
for file in files:
|
|
if file.endswith(".py") and "logging" in file.lower():
|
|
file_path = os.path.join(root, file)
|
|
with open(file_path, "r") as f:
|
|
try:
|
|
tree = ast.parse(f.read())
|
|
except SyntaxError:
|
|
print(f"Warning: Syntax error in file {file_path}")
|
|
continue
|
|
|
|
for node in ast.walk(tree):
|
|
if isinstance(node, ast.Call):
|
|
if isinstance(node.func, ast.Name):
|
|
called_functions.add(node.func.id)
|
|
elif isinstance(node.func, ast.Attribute):
|
|
called_functions.add(node.func.attr)
|
|
|
|
return called_functions
|
|
|
|
|
|
# Functions that can be ignored in test coverage
|
|
ignored_function_names = [
|
|
"__init__",
|
|
# Add other functions to ignore here
|
|
]
|
|
|
|
|
|
def main():
|
|
logging_file = "./litellm/litellm_core_utils/litellm_logging.py"
|
|
tests_dir = "./tests/"
|
|
|
|
# LOCAL TESTING
|
|
# logging_file = "../../litellm/litellm_core_utils/litellm_logging.py"
|
|
# tests_dir = "../../tests/"
|
|
|
|
logging_functions = get_function_names_from_file(logging_file)
|
|
print("logging_functions:", logging_functions)
|
|
|
|
called_functions_in_tests = get_all_functions_called_in_tests(tests_dir)
|
|
untested_functions = [
|
|
fn
|
|
for fn in logging_functions
|
|
if fn not in called_functions_in_tests and fn not in ignored_function_names
|
|
]
|
|
|
|
if untested_functions:
|
|
untested_perc = len(untested_functions) / len(logging_functions)
|
|
print(f"untested_percentage: {untested_perc * 100:.2f}%")
|
|
raise Exception(
|
|
f"{untested_perc * 100:.2f}% of functions in litellm_logging.py are not tested: {untested_functions}"
|
|
)
|
|
else:
|
|
print("All functions in litellm_logging.py are covered by tests.")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|