Files
litellm/tests/test_litellm/proxy/common_utils/test_timezone_utils.py
T
LeeJuOh 50f36d9ca6 fix(budget): fix timezone config lookup and replace hardcoded timezone map with ZoneInfo (#21754)
* fix(budget): fix timezone config lookup and replace hardcoded timezone map with ZoneInfo

* fix(budget): update stale docstring on get_budget_reset_time
2026-02-21 19:35:06 -08:00

103 lines
3.1 KiB
Python

import os
import sys
from datetime import datetime, timezone
from zoneinfo import ZoneInfo
sys.path.insert(
0, os.path.abspath("../../..")
) # Adds the parent directory to the system path
import litellm
from litellm.proxy.common_utils.timezone_utils import (
get_budget_reset_time,
get_budget_reset_timezone,
)
def test_get_budget_reset_time():
"""
Test that the budget reset time is set to the first of the next month
"""
# Get the current date
now = datetime.now(timezone.utc)
# Calculate expected reset date (first of next month)
if now.month == 12:
expected_month = 1
expected_year = now.year + 1
else:
expected_month = now.month + 1
expected_year = now.year
expected_reset_at = datetime(expected_year, expected_month, 1, tzinfo=timezone.utc)
# Verify budget_reset_at is set to first of next month
assert get_budget_reset_time(budget_duration="1mo") == expected_reset_at
def test_get_budget_reset_timezone_reads_litellm_attr():
"""
Test that get_budget_reset_timezone reads from litellm.timezone attribute.
"""
original = getattr(litellm, "timezone", None)
try:
litellm.timezone = "Asia/Tokyo"
assert get_budget_reset_timezone() == "Asia/Tokyo"
finally:
if original is None:
if hasattr(litellm, "timezone"):
delattr(litellm, "timezone")
else:
litellm.timezone = original
def test_get_budget_reset_timezone_fallback_utc():
"""
Test that get_budget_reset_timezone falls back to UTC when litellm.timezone is not set.
"""
original = getattr(litellm, "timezone", None)
try:
if hasattr(litellm, "timezone"):
delattr(litellm, "timezone")
assert get_budget_reset_timezone() == "UTC"
finally:
if original is not None:
litellm.timezone = original
def test_get_budget_reset_timezone_fallback_on_none():
"""
Test that get_budget_reset_timezone falls back to UTC when litellm.timezone is None.
"""
original = getattr(litellm, "timezone", None)
try:
litellm.timezone = None
assert get_budget_reset_timezone() == "UTC"
finally:
if original is None:
if hasattr(litellm, "timezone"):
delattr(litellm, "timezone")
else:
litellm.timezone = original
def test_get_budget_reset_time_respects_timezone():
"""
Test that get_budget_reset_time uses the configured timezone for reset calculation.
A daily reset should align to midnight in the configured timezone.
"""
original = getattr(litellm, "timezone", None)
try:
litellm.timezone = "Asia/Tokyo"
reset_at = get_budget_reset_time(budget_duration="1d")
# The reset time should be midnight in Asia/Tokyo
tokyo_reset = reset_at.astimezone(ZoneInfo("Asia/Tokyo"))
assert tokyo_reset.hour == 0
assert tokyo_reset.minute == 0
assert tokyo_reset.second == 0
finally:
if original is None:
if hasattr(litellm, "timezone"):
delattr(litellm, "timezone")
else:
litellm.timezone = original