test_gateway_plugins.py 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. import pytest
  2. from unittest.mock import MagicMock
  3. from gpustack.gateway.plugins import (
  4. HigressPlugin,
  5. get_plugin_url_prefix,
  6. get_plugin_url_with_name_and_version,
  7. supported_plugins,
  8. http_path_prefix,
  9. )
  10. def make_cfg(plugin_server_url: str):
  11. cfg = MagicMock()
  12. cfg.gateway_plugin_server_url = plugin_server_url
  13. return cfg
  14. class TestGetPluginUrlPrefix:
  15. def test_no_cfg_returns_localhost(self):
  16. assert get_plugin_url_prefix() == f"http://127.0.0.1/{http_path_prefix}"
  17. def test_cfg_none_returns_localhost(self):
  18. assert get_plugin_url_prefix(None) == f"http://127.0.0.1/{http_path_prefix}"
  19. def test_cfg_with_url(self):
  20. cfg = make_cfg("http://192.168.1.1:8080")
  21. assert (
  22. get_plugin_url_prefix(cfg) == f"http://192.168.1.1:8080/{http_path_prefix}"
  23. )
  24. def test_cfg_with_https_url(self):
  25. cfg = make_cfg("https://example.com")
  26. assert get_plugin_url_prefix(cfg) == f"https://example.com/{http_path_prefix}"
  27. class TestHigressPluginGetPath:
  28. def test_path_without_cfg(self):
  29. plugin = HigressPlugin(name="ai-proxy", version="2.0.0")
  30. assert (
  31. plugin.get_path()
  32. == f"http://127.0.0.1/{http_path_prefix}/ai-proxy/2.0.0/plugin.wasm"
  33. )
  34. def test_path_with_cfg(self):
  35. plugin = HigressPlugin(name="ai-proxy", version="2.0.0")
  36. cfg = make_cfg("http://10.0.0.1:9000")
  37. assert (
  38. plugin.get_path(cfg)
  39. == f"http://10.0.0.1:9000/{http_path_prefix}/ai-proxy/2.0.0/plugin.wasm"
  40. )
  41. def test_path_uses_forward_slash(self):
  42. plugin = HigressPlugin(name="model-router", version="2.0.0")
  43. path = plugin.get_path()
  44. assert "\\" not in path
  45. def test_name_with_special_chars_is_encoded(self):
  46. plugin = HigressPlugin(name="plugin name", version="1.0.0")
  47. path = plugin.get_path()
  48. assert "plugin%20name" in path
  49. assert " " not in path
  50. def test_version_with_special_chars_is_encoded(self):
  51. plugin = HigressPlugin(name="my-plugin", version="1.0.0+build")
  52. path = plugin.get_path()
  53. assert "1.0.0%2Bbuild" in path
  54. class TestGetPluginUrlWithNameAndVersion:
  55. def test_known_plugin(self):
  56. cfg = make_cfg("http://127.0.0.1:8080")
  57. url = get_plugin_url_with_name_and_version("ai-proxy", "2.0.0", cfg)
  58. assert (
  59. url
  60. == f"http://127.0.0.1:8080/{http_path_prefix}/ai-proxy/2.0.0/plugin.wasm"
  61. )
  62. def test_unknown_plugin_raises(self):
  63. with pytest.raises(ValueError, match="not supported"):
  64. get_plugin_url_with_name_and_version("nonexistent-plugin", "1.0.0")
  65. def test_wrong_version_raises(self):
  66. with pytest.raises(ValueError, match="not supported"):
  67. get_plugin_url_with_name_and_version("ai-proxy", "9.9.9")
  68. class TestSupportedPlugins:
  69. def test_plugins_loaded(self):
  70. assert len(supported_plugins) > 0
  71. def test_all_plugins_have_name_and_version(self):
  72. for plugin in supported_plugins:
  73. assert plugin.name
  74. assert plugin.version
  75. def test_known_plugins_present(self):
  76. names = {p.name for p in supported_plugins}
  77. for expected in [
  78. "ai-proxy",
  79. "ai-statistics",
  80. "ext-auth",
  81. "model-router",
  82. "model-mapper",
  83. "transformer",
  84. "gpustack-token-usage",
  85. "gpustack-set-header-pre-route",
  86. ]:
  87. assert expected in names, f"{expected} not found in supported_plugins"