ba29572e93
- scripts/build-push.sh: replica job CI in locale (8 image, cache buildx, tag :latest + :sha-X) - scripts/deploy-noclone.sh: deploy VPS senza clone (curl raw config + image pull) - rimossa .gitea/workflows/ci.yml - README + DEPLOYMENT aggiornati: laptop -> registry -> VPS, paths /docker/cerbero_mcp - ruff fix su 3 test (I001, SIM117, UP037, F821) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
190 lines
6.1 KiB
Python
190 lines
6.1 KiB
Python
from __future__ import annotations
|
|
|
|
import pytest
|
|
from mcp_common.environment import (
|
|
EnvironmentInfo,
|
|
EnvironmentMismatchError,
|
|
consistency_check,
|
|
resolve_environment,
|
|
)
|
|
|
|
|
|
def test_env_var_overrides_secret(monkeypatch):
|
|
monkeypatch.setenv("DERIBIT_TESTNET", "false")
|
|
creds = {"testnet": True, "base_url_live": "L", "base_url_testnet": "T"}
|
|
info = resolve_environment(
|
|
creds,
|
|
env_var="DERIBIT_TESTNET",
|
|
flag_key="testnet",
|
|
exchange="deribit",
|
|
)
|
|
assert info.environment == "mainnet"
|
|
assert info.source == "env"
|
|
assert info.env_value == "false"
|
|
assert info.base_url == "L"
|
|
|
|
|
|
def test_secret_used_when_env_missing(monkeypatch):
|
|
monkeypatch.delenv("DERIBIT_TESTNET", raising=False)
|
|
creds = {"testnet": True, "base_url_live": "L", "base_url_testnet": "T"}
|
|
info = resolve_environment(
|
|
creds,
|
|
env_var="DERIBIT_TESTNET",
|
|
flag_key="testnet",
|
|
exchange="deribit",
|
|
)
|
|
assert info.environment == "testnet"
|
|
assert info.source == "credentials"
|
|
assert info.env_value is None
|
|
assert info.base_url == "T"
|
|
|
|
|
|
def test_default_when_both_missing(monkeypatch):
|
|
monkeypatch.delenv("FOO_TESTNET", raising=False)
|
|
creds = {"base_url_live": "L", "base_url_testnet": "T"}
|
|
info = resolve_environment(
|
|
creds,
|
|
env_var="FOO_TESTNET",
|
|
flag_key="testnet",
|
|
exchange="foo",
|
|
)
|
|
assert info.environment == "testnet"
|
|
assert info.source == "default"
|
|
assert info.env_value is None
|
|
|
|
|
|
@pytest.mark.parametrize("raw,expected", [
|
|
("1", "testnet"),
|
|
("true", "testnet"),
|
|
("yes", "testnet"),
|
|
("on", "testnet"),
|
|
("TRUE", "testnet"),
|
|
("0", "mainnet"),
|
|
("false", "mainnet"),
|
|
("no", "mainnet"),
|
|
("off", "mainnet"),
|
|
("garbage", "mainnet"),
|
|
])
|
|
def test_env_value_truthy_parsing(monkeypatch, raw, expected):
|
|
monkeypatch.setenv("X_TESTNET", raw)
|
|
info = resolve_environment(
|
|
{"base_url_live": "L", "base_url_testnet": "T"},
|
|
env_var="X_TESTNET",
|
|
flag_key="testnet",
|
|
exchange="x",
|
|
)
|
|
assert info.environment == expected
|
|
|
|
|
|
def test_default_base_urls_applied_when_creds_missing(monkeypatch):
|
|
monkeypatch.delenv("X_TESTNET", raising=False)
|
|
creds: dict = {}
|
|
info = resolve_environment(
|
|
creds,
|
|
env_var="X_TESTNET",
|
|
flag_key="testnet",
|
|
exchange="x",
|
|
default_base_url_live="https://live.example",
|
|
default_base_url_testnet="https://test.example",
|
|
)
|
|
assert info.base_url == "https://test.example"
|
|
assert creds["base_url_live"] == "https://live.example"
|
|
assert creds["base_url_testnet"] == "https://test.example"
|
|
|
|
|
|
def test_creds_base_urls_override_defaults(monkeypatch):
|
|
monkeypatch.delenv("X_TESTNET", raising=False)
|
|
creds = {"base_url_live": "L", "base_url_testnet": "T"}
|
|
info = resolve_environment(
|
|
creds,
|
|
env_var="X_TESTNET",
|
|
flag_key="testnet",
|
|
exchange="x",
|
|
default_base_url_live="https://live.example",
|
|
default_base_url_testnet="https://test.example",
|
|
)
|
|
assert info.base_url == "T"
|
|
assert creds["base_url_live"] == "L"
|
|
|
|
|
|
def test_alpaca_paper_flag_key(monkeypatch):
|
|
"""Alpaca usa 'paper' invece di 'testnet' nel secret."""
|
|
monkeypatch.delenv("ALPACA_PAPER", raising=False)
|
|
creds = {"paper": False, "base_url_live": "L", "base_url_testnet": "T"}
|
|
info = resolve_environment(
|
|
creds,
|
|
env_var="ALPACA_PAPER",
|
|
flag_key="paper",
|
|
exchange="alpaca",
|
|
)
|
|
assert info.environment == "mainnet"
|
|
assert info.source == "credentials"
|
|
|
|
|
|
# ───────── consistency_check ─────────
|
|
|
|
|
|
def _info(env: str, exchange: str = "deribit") -> EnvironmentInfo:
|
|
"""Helper costruisce EnvironmentInfo per test."""
|
|
return EnvironmentInfo(
|
|
exchange=exchange,
|
|
environment=env,
|
|
source="env",
|
|
env_value="false" if env == "mainnet" else "true",
|
|
base_url=f"https://api.{exchange}.com" if env == "mainnet" else f"https://test.{exchange}.com",
|
|
)
|
|
|
|
|
|
def test_consistency_check_testnet_no_confirmation_ok():
|
|
"""Testnet senza conferma esplicita → ok, ritorna []. Default safe."""
|
|
info = _info("testnet")
|
|
creds = {"api_key": "k", "api_secret": "s"}
|
|
warnings = consistency_check(info, creds)
|
|
assert warnings == []
|
|
|
|
|
|
def test_consistency_check_mainnet_no_confirmation_raises():
|
|
"""Mainnet senza creds['environment']='mainnet' esplicito → fail-fast."""
|
|
info = _info("mainnet")
|
|
creds = {"api_key": "k", "api_secret": "s"}
|
|
with pytest.raises(EnvironmentMismatchError, match="mainnet.*explicit confirmation"):
|
|
consistency_check(info, creds)
|
|
|
|
|
|
def test_consistency_check_mainnet_with_confirmation_ok():
|
|
info = _info("mainnet")
|
|
creds = {"api_key": "k", "api_secret": "s", "environment": "mainnet"}
|
|
warnings = consistency_check(info, creds)
|
|
assert warnings == []
|
|
|
|
|
|
def test_consistency_check_explicit_mismatch_raises():
|
|
"""Secret dichiara mainnet ma resolver risolve testnet → fail-fast."""
|
|
info = _info("testnet")
|
|
creds = {"environment": "mainnet"}
|
|
with pytest.raises(EnvironmentMismatchError, match="declared.*resolved"):
|
|
consistency_check(info, creds)
|
|
|
|
|
|
def test_consistency_check_strict_mainnet_disabled():
|
|
"""Con strict_mainnet=False mainnet senza conferma logga warning ma non raise."""
|
|
info = _info("mainnet")
|
|
creds = {"api_key": "k", "api_secret": "s"}
|
|
warnings = consistency_check(info, creds, strict_mainnet=False)
|
|
assert any("mainnet" in w for w in warnings)
|
|
|
|
|
|
def test_consistency_check_url_does_not_match_environment_warns():
|
|
"""Base URL contiene 'test' ma environment='mainnet' → warning."""
|
|
from mcp_common.environment import EnvironmentInfo
|
|
info = EnvironmentInfo(
|
|
exchange="bybit",
|
|
environment="mainnet",
|
|
source="env",
|
|
env_value="false",
|
|
base_url="https://api-testnet.bybit.com", # url DICE testnet ma resolver MAINNET
|
|
)
|
|
creds = {"environment": "mainnet"}
|
|
warnings = consistency_check(info, creds)
|
|
assert any("base_url" in w.lower() for w in warnings)
|