Co-authored-by: Maxime Dolores <maxime.dolores@ext.mistral.ai> Co-authored-by: Michel Thomazo <51709227+michelTho@users.noreply.github.com> Co-authored-by: Peter Evers <peter.evers@mistral.ai> Co-authored-by: Pierre Rossinès <pierre.rossines@mistral.ai> Co-authored-by: Quentin <quentin.torroba@mistral.ai> Co-authored-by: Val <102326092+vdeva@users.noreply.github.com> Co-authored-by: Vincent G <10739306+VinceOPS@users.noreply.github.com> Co-authored-by: Mistral Vibe <vibe@mistral.ai>
134 lines
4.2 KiB
Python
134 lines
4.2 KiB
Python
from __future__ import annotations
|
|
|
|
import ssl
|
|
from unittest.mock import MagicMock, patch
|
|
|
|
import pytest
|
|
|
|
from vibe.core.utils.http import build_ssl_context, configure_ssl_context
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def _clear_ssl_cache():
|
|
configure_ssl_context(enable_system_trust_store=False)
|
|
build_ssl_context.cache_clear()
|
|
yield
|
|
configure_ssl_context(enable_system_trust_store=False)
|
|
build_ssl_context.cache_clear()
|
|
|
|
|
|
def test_build_ssl_context_returns_ssl_context():
|
|
ctx = build_ssl_context()
|
|
assert isinstance(ctx, ssl.SSLContext)
|
|
|
|
|
|
def test_build_ssl_context_uses_certifi_by_default(monkeypatch):
|
|
monkeypatch.delenv("SSL_CERT_FILE", raising=False)
|
|
monkeypatch.delenv("SSL_CERT_DIR", raising=False)
|
|
|
|
mock_ctx = MagicMock(spec=ssl.SSLContext)
|
|
with (
|
|
patch("vibe.core.utils.http.certifi.where", return_value="/certifi.pem"),
|
|
patch(
|
|
"vibe.core.utils.http.ssl.create_default_context", return_value=mock_ctx
|
|
) as create_default_context,
|
|
):
|
|
build_ssl_context()
|
|
|
|
create_default_context.assert_called_once_with(cafile="/certifi.pem")
|
|
|
|
|
|
def test_build_ssl_context_uses_system_trust_store_when_configured(monkeypatch):
|
|
monkeypatch.delenv("SSL_CERT_FILE", raising=False)
|
|
monkeypatch.delenv("SSL_CERT_DIR", raising=False)
|
|
configure_ssl_context(enable_system_trust_store=True)
|
|
|
|
mock_ctx = MagicMock(spec=ssl.SSLContext)
|
|
with (
|
|
patch(
|
|
"vibe.core.utils.http.truststore.SSLContext", return_value=mock_ctx
|
|
) as truststore_context,
|
|
patch(
|
|
"vibe.core.utils.http.ssl.create_default_context"
|
|
) as create_default_context,
|
|
):
|
|
build_ssl_context()
|
|
|
|
truststore_context.assert_called_once_with(ssl.PROTOCOL_TLS_CLIENT)
|
|
create_default_context.assert_not_called()
|
|
|
|
|
|
def test_build_ssl_context_loads_custom_cert_file(monkeypatch, tmp_path):
|
|
cert_file = tmp_path / "custom.pem"
|
|
cert_file.write_text("dummy")
|
|
monkeypatch.setenv("SSL_CERT_FILE", str(cert_file))
|
|
monkeypatch.delenv("SSL_CERT_DIR", raising=False)
|
|
|
|
mock_ctx = MagicMock(spec=ssl.SSLContext)
|
|
with patch(
|
|
"vibe.core.utils.http.ssl.create_default_context", return_value=mock_ctx
|
|
):
|
|
build_ssl_context()
|
|
|
|
mock_ctx.load_verify_locations.assert_called_once_with(
|
|
cafile=str(cert_file), capath=None
|
|
)
|
|
|
|
|
|
def test_build_ssl_context_loads_custom_cert_file_with_system_trust_store(
|
|
monkeypatch, tmp_path
|
|
):
|
|
cert_file = tmp_path / "custom.pem"
|
|
cert_file.write_text("dummy")
|
|
monkeypatch.setenv("SSL_CERT_FILE", str(cert_file))
|
|
monkeypatch.delenv("SSL_CERT_DIR", raising=False)
|
|
configure_ssl_context(enable_system_trust_store=True)
|
|
|
|
mock_ctx = MagicMock(spec=ssl.SSLContext)
|
|
with patch("vibe.core.utils.http.truststore.SSLContext", return_value=mock_ctx):
|
|
build_ssl_context()
|
|
|
|
mock_ctx.load_verify_locations.assert_called_once_with(
|
|
cafile=str(cert_file), capath=None
|
|
)
|
|
|
|
|
|
def test_build_ssl_context_loads_custom_cert_dir(monkeypatch, tmp_path):
|
|
cert_dir = tmp_path / "certs"
|
|
cert_dir.mkdir()
|
|
monkeypatch.delenv("SSL_CERT_FILE", raising=False)
|
|
monkeypatch.setenv("SSL_CERT_DIR", str(cert_dir))
|
|
|
|
mock_ctx = MagicMock(spec=ssl.SSLContext)
|
|
with patch(
|
|
"vibe.core.utils.http.ssl.create_default_context", return_value=mock_ctx
|
|
):
|
|
build_ssl_context()
|
|
|
|
mock_ctx.load_verify_locations.assert_called_once_with(
|
|
cafile=None, capath=str(cert_dir)
|
|
)
|
|
|
|
|
|
def test_build_ssl_context_warns_on_invalid_cert(monkeypatch, caplog):
|
|
monkeypatch.setenv("SSL_CERT_FILE", "/nonexistent/path/cert.pem")
|
|
monkeypatch.delenv("SSL_CERT_DIR", raising=False)
|
|
|
|
ctx = build_ssl_context()
|
|
assert isinstance(ctx, ssl.SSLContext)
|
|
assert any(
|
|
"Failed to load custom SSL certificates" in r.message for r in caplog.records
|
|
)
|
|
|
|
|
|
def test_build_ssl_context_no_custom_certs(monkeypatch):
|
|
monkeypatch.delenv("SSL_CERT_FILE", raising=False)
|
|
monkeypatch.delenv("SSL_CERT_DIR", raising=False)
|
|
|
|
mock_ctx = MagicMock(spec=ssl.SSLContext)
|
|
with patch(
|
|
"vibe.core.utils.http.ssl.create_default_context", return_value=mock_ctx
|
|
):
|
|
build_ssl_context()
|
|
|
|
mock_ctx.load_verify_locations.assert_not_called()
|