diff --git a/tests/test_litellm/integrations/gcs_bucket/test_gcs_bucket_base.py b/tests/test_litellm/integrations/gcs_bucket/test_gcs_bucket_base.py index a458752bed0..fb53994089b 100644 --- a/tests/test_litellm/integrations/gcs_bucket/test_gcs_bucket_base.py +++ b/tests/test_litellm/integrations/gcs_bucket/test_gcs_bucket_base.py @@ -131,6 +131,13 @@ class TestGCSBucketBase: class TestGCSBucketLoggerBucketName: + @pytest.mark.asyncio + async def test_constructor_rejects_non_premium_user(self, monkeypatch): + monkeypatch.setattr("litellm.proxy.proxy_server.premium_user", False) + + with pytest.raises(ValueError, match="GCS Bucket logging is a premium feature"): + GCSBucketLogger(bucket_name="config-bucket") + @pytest.mark.asyncio async def test_the_bucket_name_it_is_constructed_with_survives(self, monkeypatch): """Reading config.yaml out of a GCS bucket asks for that bucket, not the logging one (LIT-6982).""" @@ -145,3 +152,11 @@ class TestGCSBucketLoggerBucketName: monkeypatch.setattr("litellm.proxy.proxy_server.premium_user", True) assert GCSBucketLogger().BUCKET_NAME == "logging-bucket" + + @pytest.mark.asyncio + async def test_async_logging_rejects_non_premium_user(self, monkeypatch): + monkeypatch.setattr("litellm.proxy.proxy_server.premium_user", False) + logger = object.__new__(GCSBucketLogger) + + with pytest.raises(ValueError, match="GCS Bucket logging is a premium feature"): + await logger.async_log_success_event({}, None, None, None) diff --git a/tests/test_litellm/integrations/test_custom_guardrail.py b/tests/test_litellm/integrations/test_custom_guardrail.py index b47aee79efc..6ffbd4e3f1f 100644 --- a/tests/test_litellm/integrations/test_custom_guardrail.py +++ b/tests/test_litellm/integrations/test_custom_guardrail.py @@ -1754,6 +1754,20 @@ class TestCustomGuardrailSpendLogMatchRedaction: class TestGuardrailInterventionClassification: """A routing decision is a deliberate guardrail intervention, not a failure.""" + def test_http_exception_classification_returns_false_without_fastapi(self, monkeypatch): + import builtins + + real_import = builtins.__import__ + + def import_without_fastapi(name, *args, **kwargs): + if name == "fastapi.exceptions": + raise ImportError("fastapi is unavailable") + return real_import(name, *args, **kwargs) + + monkeypatch.setattr(builtins, "__import__", import_without_fastapi) + + assert CustomGuardrail._is_guardrail_intervention(Exception("not an intervention")) is False + def test_sensitive_data_route_exception_is_intervention(self): from litellm.exceptions import SensitiveDataRouteException diff --git a/tests/test_litellm/litellm_core_utils/test_token_counter.py b/tests/test_litellm/litellm_core_utils/test_token_counter.py index 3f8144e95e3..ba3a6be609f 100644 --- a/tests/test_litellm/litellm_core_utils/test_token_counter.py +++ b/tests/test_litellm/litellm_core_utils/test_token_counter.py @@ -102,7 +102,7 @@ def test_token_counter_default_encoding_matches_cl100k(): encoding: Final = tiktoken.get_encoding("cl100k_base") expected: Final = len(encoding.encode("hello world", disallowed_special=())) - assert token_counter_new(model="", text="hello world") == expected + assert token_counter_new(model=None, text="hello world") == expected def test_token_counter_text_over_chunk_boundary_stays_close_to_tiktoken():