120 lines
4.0 KiB
Python
120 lines
4.0 KiB
Python
"""The environment is untyped text; everything derived from it is checked."""
|
|||
|
|
|
||
|
|
import pytest
|
||
|
|
|
||
|
|
import start
|
||
|
|
from dsc.config import env_bool, env_int, env_str
|
||
|
|
from dsc.errors import ConfigError
|
||
|
|
|
||
|
|
|
||
|
|
@pytest.fixture
|
||
|
|
def env(monkeypatch):
|
||
|
|
def set_env(**values):
|
||
|
|
for name, value in values.items():
|
||
|
|
if value is None:
|
||
|
|
monkeypatch.delenv(name, raising=False)
|
||
|
|
else:
|
||
|
|
monkeypatch.setenv(name, value)
|
||
|
|
return set_env
|
||
|
|
|
||
|
|
|
||
|
|
@pytest.mark.parametrize("raw, expected", [
|
||
|
|
(None, 7), # unset keeps the documented default
|
||
|
|
("", 7), # an empty variable is the same as unset
|
||
|
|
("0", 0), # zero is a real value, not "missing"
|
||
|
|
("1", 1),
|
||
|
|
("4096", 4096),
|
||
|
|
(" 42 ", 42),
|
||
|
|
# int() accepts any Unicode decimal digit and normalises it; the value
|
||
|
|
# leaves as an ASCII integer, so this is harmless rather than rejected.
|
||
|
|
("\u0663", 3),
|
||
|
|
])
|
||
|
|
def test_env_int_accepts(env, raw, expected):
|
||
|
|
env(LIMIT=raw)
|
||
|
|
assert env_int("LIMIT", 7) == expected
|
||
|
|
|
||
|
|
|
||
|
|
@pytest.mark.parametrize("raw", ["-1", "-0.5", "abc", "1.5", "1e3", "0x10", "1 2", "٣ x"])
|
||
|
|
def test_env_int_rejects(env, raw):
|
||
|
|
env(LIMIT=raw)
|
||
|
|
with pytest.raises(ConfigError) as err:
|
||
|
|
env_int("LIMIT", 7)
|
||
|
|
assert "LIMIT" in str(err.value)
|
||
|
|
assert raw.strip() in str(err.value)
|
||
|
|
|
||
|
|
|
||
|
|
def test_env_int_allows_a_negative_value_when_permitted(env):
|
||
|
|
env(LIMIT="-1")
|
||
|
|
assert env_int("LIMIT", 7, minimum=-1) == -1
|
||
|
|
|
||
|
|
|
||
|
|
@pytest.mark.parametrize("raw, expected", [
|
||
|
|
(None, False),
|
||
|
|
("", False),
|
||
|
|
("true", True), ("True", True), ("TRUE", True),
|
||
|
|
("1", True), ("yes", True), ("on", True),
|
||
|
|
("false", False), ("False", False), ("0", False),
|
||
|
|
("no", False), ("off", False), (" true ", True),
|
||
|
|
])
|
||
|
|
def test_env_bool_accepts(env, raw, expected):
|
||
|
|
env(FLAG=raw)
|
||
|
|
assert env_bool("FLAG", False) is expected
|
||
|
|
|
||
|
|
|
||
|
|
@pytest.mark.parametrize("raw", ["maybe", "2", "-1", "y3s", "truthy"])
|
||
|
|
def test_env_bool_rejects(env, raw):
|
||
|
|
env(FLAG=raw)
|
||
|
|
with pytest.raises(ConfigError) as err:
|
||
|
|
env_bool("FLAG", False)
|
||
|
|
assert "FLAG" in str(err.value)
|
||
|
|
|
||
|
|
|
||
|
|
def test_env_bool_keeps_a_true_default_when_unset(env):
|
||
|
|
env(FLAG=None)
|
||
|
|
assert env_bool("FLAG", True) is True
|
||
|
|
|
||
|
|
|
||
|
|
@pytest.mark.parametrize("raw, expected", [
|
||
|
|
(None, None), ("", None), ("value", "value"), (" spaced ", " spaced "),
|
||
|
|
])
|
||
|
|
def test_env_str(env, raw, expected):
|
||
|
|
env(NAME=raw)
|
||
|
|
assert env_str("NAME") == expected
|
||
|
|
|
||
|
|
|
||
|
|
def test_a_default_container_gets_exactly_the_documented_defaults(monkeypatch):
|
||
|
|
"""The values the README promises when nothing optional is configured."""
|
||
|
|
for name in ("UPLOAD_LIMIT", "DOWNLOAD_LIMIT", "DELETE_CONFIRM_THRESHOLD",
|
||
|
|
"SEAFILE_UID", "SEAFILE_GID", "DISABLE_VERIFY_CERTIFICATE"):
|
||
|
|
monkeypatch.delenv(name, raising=False)
|
||
|
|
|
||
|
|
defaults = start.defaults_from_env()
|
||
|
|
|
||
|
|
assert defaults["upload_limit"] == 0
|
||
|
|
assert defaults["download_limit"] == 0
|
||
|
|
assert defaults["delete_confirm_threshold"] == 500
|
||
|
|
assert defaults["uid"] == 1000
|
||
|
|
assert defaults["gid"] == 1000
|
||
|
|
assert defaults["disable_verify_certificate"] is False
|
||
|
|
|
||
|
|
|
||
|
|
def test_no_default_is_none_where_a_value_is_documented(monkeypatch):
|
||
|
|
"""A None here reaches seaf-cli as the literal string "None"."""
|
||
|
|
for name in ("UPLOAD_LIMIT", "DOWNLOAD_LIMIT", "DELETE_CONFIRM_THRESHOLD",
|
||
|
|
"SEAFILE_UID", "SEAFILE_GID"):
|
||
|
|
monkeypatch.delenv(name, raising=False)
|
||
|
|
|
||
|
|
defaults = start.defaults_from_env()
|
||
|
|
for key in ("upload_limit", "download_limit", "delete_confirm_threshold",
|
||
|
|
"uid", "gid"):
|
||
|
|
assert defaults[key] is not None, f"{key} must never default to None"
|
||
|
|
|
||
|
|
|
||
|
|
def test_numeric_settings_are_integers_not_strings(monkeypatch):
|
||
|
|
"""A string UID never equals the integer it is compared against."""
|
||
|
|
monkeypatch.setenv("SEAFILE_UID", "1000")
|
||
|
|
monkeypatch.setenv("UPLOAD_LIMIT", "50")
|
||
|
|
|
||
|
|
defaults = start.defaults_from_env()
|
||
|
|
assert defaults["uid"] == 1000 and isinstance(defaults["uid"], int)
|
||
|
|
assert defaults["upload_limit"] == 50 and isinstance(defaults["upload_limit"], int)
|