mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-09 04:06:42 +00:00
Merge branch 'feature/designer' into feature/store-i18n
This commit is contained in:
34 files changed
+597
-186
No files matched your search
@@ -56,6 +56,48 @@ class TestApplicationsCarrierActionPlugin(unittest.TestCase):
|
||||
self.assertEqual(variables, {"applications": {}})
|
||||
self.assertTrue(kwargs["carrier"])
|
||||
|
||||
def test_revalidates_the_tokens_file_before_rendering(self):
|
||||
order = []
|
||||
lookup = _FakeLookup({"key": ["roles", []], "applications": {}})
|
||||
lookup.run = lambda *args, **kwargs: order.append("render") or [{}]
|
||||
action = _make_action(_FakeTask())
|
||||
with (
|
||||
patch(
|
||||
"plugins.action.applications_carrier.ActionBase.run",
|
||||
autospec=True,
|
||||
return_value={},
|
||||
),
|
||||
patch(
|
||||
"plugins.action.applications_carrier.lookup_loader.get",
|
||||
return_value=lookup,
|
||||
),
|
||||
patch(
|
||||
"plugins.action.applications_carrier.revalidate_tokens_file",
|
||||
side_effect=lambda variables: order.append(("revalidate", variables)),
|
||||
),
|
||||
):
|
||||
action.run(task_vars={"FILE_TOKENS": "/x/tokens.yml"})
|
||||
|
||||
self.assertEqual(
|
||||
order, [("revalidate", {"FILE_TOKENS": "/x/tokens.yml"}), "render"]
|
||||
)
|
||||
|
||||
def test_clear_does_not_revalidate(self):
|
||||
action = _make_action(_FakeTask(args={"clear": True}))
|
||||
with (
|
||||
patch(
|
||||
"plugins.action.applications_carrier.ActionBase.run",
|
||||
autospec=True,
|
||||
return_value={},
|
||||
),
|
||||
patch(
|
||||
"plugins.action.applications_carrier.revalidate_tokens_file"
|
||||
) as revalidate,
|
||||
):
|
||||
action.run(task_vars={})
|
||||
|
||||
revalidate.assert_not_called()
|
||||
|
||||
def test_rejects_arguments(self):
|
||||
action = _make_action(_FakeTask(args={"foo": 1}))
|
||||
with (
|
||||
|
||||
@@ -74,6 +74,7 @@ def render(
|
||||
remote_models=REMOTE_MODELS,
|
||||
router_alias="",
|
||||
measured_speed=None,
|
||||
logo_url="",
|
||||
):
|
||||
"""The rendered config as a parsed mapping.
|
||||
|
||||
@@ -86,6 +87,7 @@ def render(
|
||||
is what every case that predates the router expects.
|
||||
measured_speed: alias -> tokens per second from the last deploy's
|
||||
measurement; empty means nothing has been measured yet.
|
||||
logo_url: LITELLM_UI_LOGO_URL; empty while the admin UI shows no corporate logo.
|
||||
"""
|
||||
env = Environment(
|
||||
undefined=StrictUndefined,
|
||||
@@ -108,6 +110,7 @@ def render(
|
||||
+ [MOCK["provider"]],
|
||||
LITELLM_ROUTER_ALIAS=router_alias,
|
||||
LITELLM_MEASURED_SPEED=measured_speed or {},
|
||||
LITELLM_UI_LOGO_URL=logo_url,
|
||||
)
|
||||
return yaml.safe_load(
|
||||
rendered
|
||||
@@ -183,6 +186,17 @@ class TestBothBackends(unittest.TestCase):
|
||||
)
|
||||
|
||||
|
||||
class TestUiTheme(unittest.TestCase):
|
||||
def test_a_logo_url_reaches_the_ui_theme_config(self) -> None:
|
||||
url = "https://cdn.example/roles/web-app-litellm/latest/img/design/logo.svg"
|
||||
settings = render(logo_url=url)["litellm_settings"]
|
||||
self.assertEqual(settings["ui_theme_config"], {"logo_url": url})
|
||||
self.assertTrue(settings["drop_params"])
|
||||
|
||||
def test_without_a_logo_url_the_ui_theme_config_is_absent(self) -> None:
|
||||
self.assertNotIn("ui_theme_config", render()["litellm_settings"])
|
||||
|
||||
|
||||
class TestNoBackend(unittest.TestCase):
|
||||
def test_the_model_list_is_empty(self) -> None:
|
||||
self.assertEqual(render()["model_list"], [])
|
||||
|
||||
+39
-4
@@ -10,9 +10,11 @@ files; this file pins the contract of base itself.
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import tempfile
|
||||
import textwrap
|
||||
import unittest
|
||||
import unittest.mock as mock
|
||||
from pathlib import Path
|
||||
|
||||
from utils.cache import _reset_cache_for_tests, base
|
||||
@@ -153,11 +155,13 @@ class TestStableVariablesSignature(unittest.TestCase):
|
||||
|
||||
|
||||
class TestTokensFileSignature(unittest.TestCase):
|
||||
def test_missing_file_returns_zeroed_signature(self):
|
||||
def setUp(self):
|
||||
base._reset()
|
||||
|
||||
def test_missing_file_returns_an_empty_digest(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
sig = base._tokens_file_signature(Path(tmp) / "absent.yml")
|
||||
self.assertEqual(sig[1], 0)
|
||||
self.assertEqual(sig[2], 0)
|
||||
path = Path(tmp) / "absent.yml"
|
||||
self.assertEqual(base._tokens_file_signature(path), (str(path), ""))
|
||||
|
||||
def test_signature_changes_when_file_changes(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
@@ -168,6 +172,37 @@ class TestTokensFileSignature(unittest.TestCase):
|
||||
sig_after = base._tokens_file_signature(path)
|
||||
self.assertNotEqual(sig_before, sig_after)
|
||||
|
||||
def test_a_touch_keeps_the_signature(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
path = Path(tmp) / "tokens.yml"
|
||||
path.write_text("a: 1\n", encoding="utf-8")
|
||||
sig_before = base._tokens_file_signature(path)
|
||||
later = path.stat().st_mtime_ns + 5_000_000_000
|
||||
os.utime(path, ns=(later, later))
|
||||
self.assertEqual(base._tokens_file_signature(path), sig_before)
|
||||
|
||||
def test_an_unchanged_stat_serves_the_digest_without_reading(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
path = Path(tmp) / "tokens.yml"
|
||||
path.write_text("a: 1\n", encoding="utf-8")
|
||||
sig_before = base._tokens_file_signature(path)
|
||||
with mock.patch.object(Path, "open", side_effect=AssertionError):
|
||||
self.assertEqual(base._tokens_file_signature(path), sig_before)
|
||||
|
||||
|
||||
class TestRevalidateTokensFile(unittest.TestCase):
|
||||
def test_opens_the_file(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
path = Path(tmp) / "tokens.yml"
|
||||
path.write_text("a: 1\n", encoding="utf-8")
|
||||
with mock.patch.object(Path, "open", wraps=path.open) as opened:
|
||||
base._revalidate_tokens_file(path)
|
||||
opened.assert_called_once_with("rb")
|
||||
|
||||
def test_a_missing_file_is_ignored(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
base._revalidate_tokens_file(Path(tmp) / "absent.yml")
|
||||
|
||||
|
||||
class TestRenderWithTemplar(unittest.TestCase):
|
||||
"""`_render_with_templar` is the single ansible-coupled symbol in
|
||||
|
||||
Reference in new issue
Block a user