litellm/tests/test_litellm/llms/crusoe/test_crusoe.py
yuneng-jiang 693797420d
test: unwind environment writes in tests/test_litellm with monkeypatch (#37806)
* test: use monkeypatch.setenv for env writes in tests/test_litellm

`os.environ["X"] = v` inside a test leaks the value into every test that runs
after it in the same worker, so ordering decides the result. 262 of those
writes across 40 files now go through pytest's `monkeypatch` fixture, which
restores the previous value at teardown.

The rewrite skips any test that a mock.patch-family decorator wraps, any test
with defaulted positional parameters, any test whose own name is called
directly elsewhere, and rebinds nothing inside nested defs, because in each of
those cases appending a fixture parameter changes what pytest or mock binds.

Ratchets the TQ004 ceiling from 768 to 506.

* fix(test): delete the key through monkeypatch instead of popping it first

Five tests popped a key straight out of `os.environ`, ran, then restored it with
`monkeypatch.setenv`. By the time monkeypatch saw the name it was already gone,
so it recorded "absent" as the value to go back to and deleted the key at
teardown. On a worker that inherited a real `RESEND_API_KEY`, `SENDGRID_API_KEY`,
`UI_PASSWORD`, `LITELLM_SALT_KEY` or `OPENAI_API_KEY`, every test after the first
one ran without it.

`monkeypatch.delenv(..., raising=False)` removes the key and restores whatever
was there, so the try/finally the manual restore needed goes with it.

* chore(test): leave the two cost-calc files to the PR that rewrites them fully

Both files are also in #37815, which converts the module-global writes as well
as the env writes and folds them into one fixture. Two PRs rewriting the same
lines differently is a conflict nobody benefits from resolving, so this one
drops back to staging on those two and keeps the other 39.

TQ004 clears 200 here instead of 275; the rest moves with #37815.
2026-08-21 20:28:37 -07:00

135 lines
5.2 KiB
Python

import os
from unittest.mock import patch
CRUSOE_API_BASE = "https://managed-inference-api-proxy.crusoecloud.com/v1"
def test_crusoe_json_registry():
"""Test Crusoe is registered in the JSON provider registry"""
from litellm.llms.openai_like.json_loader import JSONProviderRegistry
assert JSONProviderRegistry.exists("crusoe")
config = JSONProviderRegistry.get("crusoe")
assert config is not None
assert config.base_url == CRUSOE_API_BASE
assert config.api_key_env == "CRUSOE_API_KEY"
assert config.api_base_env == "CRUSOE_API_BASE"
def test_crusoe_dynamic_config_defaults():
"""Test dynamic config returns correct default API base"""
from litellm.llms.openai_like.dynamic_config import create_config_class
from litellm.llms.openai_like.json_loader import JSONProviderRegistry
config = create_config_class(JSONProviderRegistry.get("crusoe"))()
with patch.dict(os.environ, {}, clear=True):
api_base, api_key = config._get_openai_compatible_provider_info(None, None)
assert api_base == CRUSOE_API_BASE
assert api_key is None
def test_crusoe_dynamic_config_env_vars():
"""Test dynamic config reads CRUSOE_API_KEY and CRUSOE_API_BASE from env"""
from litellm.llms.openai_like.dynamic_config import create_config_class
from litellm.llms.openai_like.json_loader import JSONProviderRegistry
config = create_config_class(JSONProviderRegistry.get("crusoe"))()
with patch.dict(
os.environ,
{"CRUSOE_API_KEY": "test-key", "CRUSOE_API_BASE": "https://custom.crusoe.com/v1"},
):
api_base, api_key = config._get_openai_compatible_provider_info(None, None)
assert api_base == "https://custom.crusoe.com/v1"
assert api_key == "test-key"
def test_crusoe_dynamic_config_explicit_params():
"""Test explicit params override env vars"""
from litellm.llms.openai_like.dynamic_config import create_config_class
from litellm.llms.openai_like.json_loader import JSONProviderRegistry
config = create_config_class(JSONProviderRegistry.get("crusoe"))()
with patch.dict(os.environ, {"CRUSOE_API_KEY": "env-key"}):
api_base, api_key = config._get_openai_compatible_provider_info(
"https://override.crusoe.com/v1", "override-key"
)
assert api_base == "https://override.crusoe.com/v1"
assert api_key == "override-key"
def test_crusoe_supported_params():
"""Test dynamic config returns standard OpenAI params"""
from litellm.llms.openai_like.dynamic_config import create_config_class
from litellm.llms.openai_like.json_loader import JSONProviderRegistry
config = create_config_class(JSONProviderRegistry.get("crusoe"))()
params = config.get_supported_openai_params(model="meta-llama/Llama-3.3-70B-Instruct")
assert isinstance(params, list)
assert len(params) > 0
assert "temperature" in params
assert "max_tokens" in params
assert "stream" in params
def test_crusoe_param_mapping_max_completion_tokens():
"""Test max_completion_tokens is mapped to max_tokens for Crusoe"""
from litellm.llms.openai_like.dynamic_config import create_config_class
from litellm.llms.openai_like.json_loader import JSONProviderRegistry
config = create_config_class(JSONProviderRegistry.get("crusoe"))()
optional_params = config.map_openai_params(
non_default_params={"max_completion_tokens": 1024},
optional_params={},
model="meta-llama/Llama-3.3-70B-Instruct",
drop_params=False,
)
assert "max_tokens" in optional_params, "max_completion_tokens should be mapped to max_tokens"
assert optional_params["max_tokens"] == 1024
assert "max_completion_tokens" not in optional_params
def test_crusoe_provider_detection_by_prefix():
"""Test crusoe/model prefix is correctly routed"""
from litellm.litellm_core_utils.get_llm_provider_logic import get_llm_provider
model, provider, _, _ = get_llm_provider("crusoe/meta-llama/Llama-3.3-70B-Instruct")
assert provider == "crusoe"
assert model == "meta-llama/Llama-3.3-70B-Instruct"
def test_crusoe_model_list_populated(monkeypatch):
"""Test Crusoe models are present in model_prices_and_context_window.json"""
import litellm
original_model_cost = litellm.model_cost
original_env = os.environ.get("LITELLM_LOCAL_MODEL_COST_MAP")
try:
monkeypatch.setenv("LITELLM_LOCAL_MODEL_COST_MAP", "True")
litellm.model_cost = litellm.get_model_cost_map(url="")
expected = [
"crusoe/meta-llama/Llama-3.3-70B-Instruct",
"crusoe/deepseek-ai/DeepSeek-R1-0528",
"crusoe/deepseek-ai/DeepSeek-V3-0324",
"crusoe/Qwen/Qwen3-235B-A22B-Instruct-2507",
"crusoe/moonshotai/Kimi-K2-Thinking",
"crusoe/openai/gpt-oss-120b",
"crusoe/google/gemma-3-12b-it",
]
for model in expected:
assert model in litellm.model_cost, f"{model} not found in model_cost"
assert litellm.model_cost[model].get("litellm_provider") == "crusoe"
finally:
litellm.model_cost = original_model_cost
if original_env is None:
os.environ.pop("LITELLM_LOCAL_MODEL_COST_MAP", None)
else:
monkeypatch.setenv("LITELLM_LOCAL_MODEL_COST_MAP", original_env)