@@ -2580,3 +2580,134 @@ def test_get_prompt_spec_for_db_prompt_with_versions():
25802580 prompt_spec_v2 = proxy_config ._get_prompt_spec_for_db_prompt (db_prompt = mock_prompt_v2 )
25812581 assert prompt_spec_v2 .prompt_id == "chat_prompt.v2"
25822582
2583+
2584+ def test_get_image_non_root_uses_tmp_assets_dir (monkeypatch ):
2585+ """
2586+ Test that get_image uses /tmp/litellm_assets when LITELLM_NON_ROOT is true.
2587+ """
2588+ from unittest .mock import patch
2589+
2590+ from litellm .proxy .proxy_server import get_image
2591+
2592+ # Set LITELLM_NON_ROOT to true
2593+ monkeypatch .setenv ("LITELLM_NON_ROOT" , "true" )
2594+ monkeypatch .delenv ("UI_LOGO_PATH" , raising = False )
2595+
2596+ # Mock os.path operations
2597+ with patch ("litellm.proxy.proxy_server.os.makedirs" ) as mock_makedirs , \
2598+ patch ("litellm.proxy.proxy_server.os.path.exists" , return_value = True ), \
2599+ patch ("litellm.proxy.proxy_server.os.getenv" ) as mock_getenv , \
2600+ patch ("litellm.proxy.proxy_server.FileResponse" ) as mock_file_response :
2601+
2602+ # Setup mock_getenv to return empty string for UI_LOGO_PATH
2603+ def getenv_side_effect (key , default = "" ):
2604+ if key == "UI_LOGO_PATH" :
2605+ return ""
2606+ elif key == "LITELLM_NON_ROOT" :
2607+ return "true"
2608+ return default
2609+
2610+ mock_getenv .side_effect = getenv_side_effect
2611+
2612+ # Call the function
2613+ get_image ()
2614+
2615+ # Verify makedirs was called with /tmp/litellm_assets
2616+ mock_makedirs .assert_called_once_with ("/tmp/litellm_assets" , exist_ok = True )
2617+
2618+
2619+ def test_get_image_non_root_fallback_to_default_logo (monkeypatch ):
2620+ """
2621+ Test that get_image falls back to default_site_logo when logo doesn't exist
2622+ in /tmp/litellm_assets for non-root case.
2623+ """
2624+ from unittest .mock import patch
2625+
2626+ from litellm .proxy .proxy_server import get_image
2627+
2628+ # Set LITELLM_NON_ROOT to true
2629+ monkeypatch .setenv ("LITELLM_NON_ROOT" , "true" )
2630+ monkeypatch .delenv ("UI_LOGO_PATH" , raising = False )
2631+
2632+ # Track path.exists calls to verify it checks /tmp/litellm_assets/logo.jpg
2633+ exists_calls = []
2634+
2635+ def exists_side_effect (path ):
2636+ exists_calls .append (path )
2637+ # Return False for /tmp/litellm_assets/logo.jpg to trigger fallback
2638+ if "/tmp/litellm_assets/logo.jpg" in path :
2639+ return False
2640+ return True
2641+
2642+ # Mock os.path operations
2643+ with patch ("litellm.proxy.proxy_server.os.makedirs" ) as mock_makedirs , \
2644+ patch ("litellm.proxy.proxy_server.os.path.exists" , side_effect = exists_side_effect ), \
2645+ patch ("litellm.proxy.proxy_server.os.getenv" ) as mock_getenv , \
2646+ patch ("litellm.proxy.proxy_server.FileResponse" ) as mock_file_response :
2647+
2648+ # Setup mock_getenv
2649+ def getenv_side_effect (key , default = "" ):
2650+ if key == "UI_LOGO_PATH" :
2651+ return ""
2652+ elif key == "LITELLM_NON_ROOT" :
2653+ return "true"
2654+ return default
2655+
2656+ mock_getenv .side_effect = getenv_side_effect
2657+
2658+ # Call the function
2659+ get_image ()
2660+
2661+ # Verify makedirs was called with /tmp/litellm_assets
2662+ mock_makedirs .assert_called_once_with ("/tmp/litellm_assets" , exist_ok = True )
2663+
2664+ # Verify that exists was called to check /tmp/litellm_assets/logo.jpg
2665+ tmp_logo_path = "/tmp/litellm_assets/logo.jpg"
2666+ assert any (tmp_logo_path in str (call ) for call in exists_calls ), \
2667+ f"Should check if { tmp_logo_path } exists"
2668+
2669+ # Verify FileResponse was called (with fallback logo)
2670+ assert mock_file_response .called , "FileResponse should be called"
2671+
2672+
2673+ def test_get_image_root_case_uses_current_dir (monkeypatch ):
2674+ """
2675+ Test that get_image uses current_dir when LITELLM_NON_ROOT is not true.
2676+ """
2677+ from unittest .mock import patch
2678+
2679+ from litellm .proxy .proxy_server import get_image
2680+
2681+ # Don't set LITELLM_NON_ROOT (or set it to false)
2682+ monkeypatch .delenv ("LITELLM_NON_ROOT" , raising = False )
2683+ monkeypatch .delenv ("UI_LOGO_PATH" , raising = False )
2684+
2685+ # Mock os.path operations
2686+ with patch ("litellm.proxy.proxy_server.os.makedirs" ) as mock_makedirs , \
2687+ patch ("litellm.proxy.proxy_server.os.path.exists" , return_value = True ), \
2688+ patch ("litellm.proxy.proxy_server.os.getenv" ) as mock_getenv , \
2689+ patch ("litellm.proxy.proxy_server.FileResponse" ) as mock_file_response :
2690+
2691+ # Setup mock_getenv
2692+ def getenv_side_effect (key , default = "" ):
2693+ if key == "UI_LOGO_PATH" :
2694+ return ""
2695+ elif key == "LITELLM_NON_ROOT" :
2696+ return "" # Not set or empty
2697+ return default
2698+
2699+ mock_getenv .side_effect = getenv_side_effect
2700+
2701+ # Call the function
2702+ get_image ()
2703+
2704+ # Verify makedirs was NOT called with /tmp/litellm_assets (should not create it for root case)
2705+ tmp_assets_calls = [
2706+ call for call in mock_makedirs .call_args_list
2707+ if "/tmp/litellm_assets" in str (call )
2708+ ]
2709+ assert len (tmp_assets_calls ) == 0 , "Should not create /tmp/litellm_assets for root case"
2710+
2711+ # Verify FileResponse was called
2712+ assert mock_file_response .called , "FileResponse should be called"
2713+
0 commit comments