mirror of
https://github.com/BerriAI/litellm.git
synced 2026-08-28 05:25:59 +00:00
fix(tests): drop module-level test calls that break local_testing collection (#29520)
* fix(tests): drop module-level test calls that break local_testing collection Several files in tests/local_testing invoked their test functions at module scope (e.g. test_register_model.py ran test_update_model_cost_via_completion() at the bottom of the file). Those calls execute during pytest collection, so they fire real network requests at import time. test_register_model.py's call hit an OpenAI 429 and raised, turning into a collection error. A collection error aborts the whole session for every job that globs tests/local_testing/**/test_*.py, which is why unrelated jobs like langfuse_logging_unit_tests (-k langfuse) and litellm_assistants_api_testing (-k assistants) both failed even though neither touches register_model; the -k filter only applies after collection. pytest discovers and runs these test_* functions on its own, so the top-level calls were dead and harmful. Removes them from test_register_model.py, test_wandb.py, test_lunary.py, and test_multiple_deployments.py, and adds a regression test that scans the directory for module-level test invocations. * test(local_testing): skip unparseable files in module-scope invocation guardrail A syntax error in any tests/local_testing file would make ast.parse raise an unhandled SyntaxError, so the guardrail itself would crash with a confusing traceback instead of its assertion message. Such a file already fails pytest collection on its own, which is the clearer signal, so the guardrail now skips files it cannot parse and stays focused on detecting module-scope test calls. Reads files as utf-8 for deterministic behavior across platforms.
This commit is contained in:
parent
4a81ec4982
commit
c1602587c1
5 changed files with 36 additions and 12 deletions
|
|
@ -26,9 +26,6 @@ def test_lunary_logging():
|
|||
print(e)
|
||||
|
||||
|
||||
test_lunary_logging()
|
||||
|
||||
|
||||
def test_lunary_template():
|
||||
import lunary
|
||||
|
||||
|
|
|
|||
|
|
@ -49,6 +49,3 @@ def test_multiple_deployments():
|
|||
except Exception as e:
|
||||
traceback.print_exc()
|
||||
pytest.fail(f"An exception occurred: {e}")
|
||||
|
||||
|
||||
test_multiple_deployments()
|
||||
|
|
|
|||
36
tests/local_testing/test_no_top_level_test_invocations.py
Normal file
36
tests/local_testing/test_no_top_level_test_invocations.py
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
import ast
|
||||
from pathlib import Path
|
||||
|
||||
LOCAL_TESTING_DIR = Path(__file__).parent
|
||||
|
||||
|
||||
def _top_level_test_invocations(tree):
|
||||
invocations = []
|
||||
for node in tree.body:
|
||||
if not isinstance(node, ast.Expr) or not isinstance(node.value, ast.Call):
|
||||
continue
|
||||
func = node.value.func
|
||||
name = getattr(func, "id", None) or getattr(func, "attr", None)
|
||||
if name and name.startswith("test_"):
|
||||
invocations.append((name, node.lineno))
|
||||
return invocations
|
||||
|
||||
|
||||
def test_no_module_level_test_invocations():
|
||||
offenders = []
|
||||
for path in sorted(LOCAL_TESTING_DIR.rglob("*.py")):
|
||||
try:
|
||||
tree = ast.parse(path.read_text(encoding="utf-8"), filename=str(path))
|
||||
except SyntaxError:
|
||||
continue
|
||||
for name, lineno in _top_level_test_invocations(tree):
|
||||
offenders.append(
|
||||
f"{path.relative_to(LOCAL_TESTING_DIR)}:{lineno} calls {name}()"
|
||||
)
|
||||
|
||||
assert not offenders, (
|
||||
"Test functions are invoked at module scope, so they run during pytest "
|
||||
"collection (making network calls and erroring collection for every job "
|
||||
"that globs this directory). Remove these calls; pytest collects test "
|
||||
"functions automatically:\n" + "\n".join(offenders)
|
||||
)
|
||||
|
|
@ -60,6 +60,3 @@ def test_update_model_cost_via_completion():
|
|||
assert litellm.model_cost["gpt-3.5-turbo"]["output_cost_per_token"] == 0.4
|
||||
except Exception as e:
|
||||
pytest.fail(f"An error occurred: {e}")
|
||||
|
||||
|
||||
test_update_model_cost_via_completion()
|
||||
|
|
|
|||
|
|
@ -51,9 +51,6 @@ def test_wandb_logging_async():
|
|||
pass
|
||||
|
||||
|
||||
test_wandb_logging_async()
|
||||
|
||||
|
||||
def test_wandb_logging():
|
||||
try:
|
||||
response = completion(
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue