From 060140d6540d045530ceefda6e639f39588e7dab Mon Sep 17 00:00:00 2001 From: Devaev Maxim Date: Thu, 11 Apr 2019 04:18:02 +0300 Subject: better auth tests, refactoring --- tests/apps/__init__.py | 20 +++++ tests/apps/test_cleanup.py | 71 +++++++++++++++ tests/apps/test_htpasswd.py | 151 ++++++++++++++++++++++++++++++++ tests/auth/__init__.py | 43 +++++++++ tests/auth/test_service_htpasswd.py | 52 +++++++++++ tests/auth/test_service_http.py | 60 +++++++++++++ tests/test_app_cleanup.py | 71 --------------- tests/test_app_htpasswd.py | 151 -------------------------------- tests/test_auth_service_htpasswd.py | 55 ------------ tests/test_auth_service_http.py | 69 --------------- tests/test_validators_auth.py | 130 --------------------------- tests/test_validators_basic.py | 144 ------------------------------ tests/test_validators_hw.py | 72 --------------- tests/test_validators_kvm.py | 169 ------------------------------------ tests/test_validators_net.py | 122 -------------------------- tests/test_validators_os.py | 118 ------------------------- tests/validators/__init__.py | 20 +++++ tests/validators/test_auth.py | 130 +++++++++++++++++++++++++++ tests/validators/test_basic.py | 144 ++++++++++++++++++++++++++++++ tests/validators/test_hw.py | 72 +++++++++++++++ tests/validators/test_kvm.py | 169 ++++++++++++++++++++++++++++++++++++ tests/validators/test_net.py | 122 ++++++++++++++++++++++++++ tests/validators/test_os.py | 118 +++++++++++++++++++++++++ 23 files changed, 1172 insertions(+), 1101 deletions(-) create mode 100644 tests/apps/__init__.py create mode 100644 tests/apps/test_cleanup.py create mode 100644 tests/apps/test_htpasswd.py create mode 100644 tests/auth/__init__.py create mode 100644 tests/auth/test_service_htpasswd.py create mode 100644 tests/auth/test_service_http.py delete mode 100644 tests/test_app_cleanup.py delete mode 100644 tests/test_app_htpasswd.py delete mode 100644 tests/test_auth_service_htpasswd.py delete mode 100644 tests/test_auth_service_http.py delete mode 100644 tests/test_validators_auth.py delete mode 100644 tests/test_validators_basic.py delete mode 100644 tests/test_validators_hw.py delete mode 100644 tests/test_validators_kvm.py delete mode 100644 tests/test_validators_net.py delete mode 100644 tests/test_validators_os.py create mode 100644 tests/validators/__init__.py create mode 100644 tests/validators/test_auth.py create mode 100644 tests/validators/test_basic.py create mode 100644 tests/validators/test_hw.py create mode 100644 tests/validators/test_kvm.py create mode 100644 tests/validators/test_net.py create mode 100644 tests/validators/test_os.py (limited to 'tests') diff --git a/tests/apps/__init__.py b/tests/apps/__init__.py new file mode 100644 index 00000000..1e91f7fa --- /dev/null +++ b/tests/apps/__init__.py @@ -0,0 +1,20 @@ +# ========================================================================== # +# # +# KVMD - The main Pi-KVM daemon. # +# # +# Copyright (C) 2018 Maxim Devaev # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +# ========================================================================== # diff --git a/tests/apps/test_cleanup.py b/tests/apps/test_cleanup.py new file mode 100644 index 00000000..3e2e4c72 --- /dev/null +++ b/tests/apps/test_cleanup.py @@ -0,0 +1,71 @@ +# ========================================================================== # +# # +# KVMD - The main Pi-KVM daemon. # +# # +# Copyright (C) 2018 Maxim Devaev # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +# ========================================================================== # + + +import os +import secrets +import multiprocessing +import multiprocessing.queues +import time + +import setproctitle + +from kvmd.apps.cleanup import main + + +# ===== +def test_ok(tmpdir) -> None: # type: ignore + queue: multiprocessing.queues.Queue = multiprocessing.Queue() + + ustreamer_tmp_path = os.path.abspath(str(tmpdir.join("ustr-" + secrets.token_hex(3)))) + os.symlink("/usr/bin/ustreamer", ustreamer_tmp_path) + + ustreamer_sock_path = os.path.abspath(str(tmpdir.join("ustreamer-fake.sock"))) + open(ustreamer_sock_path, "w").close() + kvmd_sock_path = os.path.abspath(str(tmpdir.join("kvmd-fake.sock"))) + open(kvmd_sock_path, "w").close() + + def ustreamer_fake() -> None: + setproctitle.setproctitle(os.path.basename(ustreamer_tmp_path)) + queue.put(True) + while True: + time.sleep(1) + + proc = multiprocessing.Process(target=ustreamer_fake, daemon=True) + proc.start() + assert queue.get(timeout=5) + + assert proc.is_alive() + main([ + "kvmd-cleanup", + "--set-options", + "kvmd/server/port=0", + "kvmd/server/unix=" + kvmd_sock_path, + "kvmd/streamer/port=0", + "kvmd/streamer/unix=" + ustreamer_sock_path, + "kvmd/streamer/cmd=" + ustreamer_tmp_path, + ]) + + assert not os.path.exists(ustreamer_sock_path) + assert not os.path.exists(kvmd_sock_path) + + assert not proc.is_alive() + proc.join() diff --git a/tests/apps/test_htpasswd.py b/tests/apps/test_htpasswd.py new file mode 100644 index 00000000..11895c85 --- /dev/null +++ b/tests/apps/test_htpasswd.py @@ -0,0 +1,151 @@ +# ========================================================================== # +# # +# KVMD - The main Pi-KVM daemon. # +# # +# Copyright (C) 2018 Maxim Devaev # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +# ========================================================================== # + + +import os +import hashlib +import tempfile +import builtins +import getpass + +from typing import List +from typing import Generator +from typing import Any + +import passlib.apache + +import pytest + +from kvmd.apps.htpasswd import main + + +# ===== +def _make_passwd(user: str) -> str: + return hashlib.md5(user.encode()).hexdigest() + + +@pytest.fixture(name="htpasswd", params=[[], ["admin"], ["admin", "user"]]) +def _htpasswd_fixture(request) -> Generator[passlib.apache.HtpasswdFile, None, None]: # type: ignore + (fd, path) = tempfile.mkstemp() + os.close(fd) + htpasswd = passlib.apache.HtpasswdFile(path) + for user in request.param: + htpasswd.set_password(user, _make_passwd(user)) + htpasswd.save() + yield htpasswd + os.remove(path) + + +def _run_htpasswd(htpasswd: passlib.apache.HtpasswdFile, cmd: List[str]) -> None: + main([ + "kvmd-htpasswd", + *cmd, + "--set-options", + "kvmd/auth/internal/file=" + htpasswd.path, + ]) + + +# ===== +def test_ok__list(htpasswd: passlib.apache.HtpasswdFile, capsys) -> None: # type: ignore + _run_htpasswd(htpasswd, ["list"]) + (out, err) = capsys.readouterr() + assert len(err) == 0 + assert sorted(filter(None, out.split("\n"))) == sorted(htpasswd.users()) == sorted(set(htpasswd.users())) + + +# ===== +def test_ok__set_change_stdin(htpasswd: passlib.apache.HtpasswdFile, mocker) -> None: # type: ignore + old_users = set(htpasswd.users()) + if old_users: + assert htpasswd.check_password("admin", _make_passwd("admin")) + + mocker.patch.object(builtins, "input", (lambda: " test ")) + _run_htpasswd(htpasswd, ["set", "admin", "--read-stdin"]) + + htpasswd.load(force=True) + assert htpasswd.check_password("admin", " test ") + assert old_users == set(htpasswd.users()) + + +def test_ok__set_add_stdin(htpasswd: passlib.apache.HtpasswdFile, mocker) -> None: # type: ignore + old_users = set(htpasswd.users()) + if old_users: + mocker.patch.object(builtins, "input", (lambda: " test ")) + _run_htpasswd(htpasswd, ["set", "new", "--read-stdin"]) + + htpasswd.load(force=True) + assert htpasswd.check_password("new", " test ") + assert old_users.union(["new"]) == set(htpasswd.users()) + + +# ===== +def test_ok__set_change_getpass(htpasswd: passlib.apache.HtpasswdFile, mocker) -> None: # type: ignore + old_users = set(htpasswd.users()) + if old_users: + assert htpasswd.check_password("admin", _make_passwd("admin")) + + mocker.patch.object(getpass, "getpass", (lambda *_, **__: " test ")) + _run_htpasswd(htpasswd, ["set", "admin"]) + + htpasswd.load(force=True) + assert htpasswd.check_password("admin", " test ") + assert old_users == set(htpasswd.users()) + + +def test_fail__set_change_getpass(htpasswd: passlib.apache.HtpasswdFile, mocker) -> None: # type: ignore + old_users = set(htpasswd.users()) + if old_users: + assert htpasswd.check_password("admin", _make_passwd("admin")) + + count = 0 + + def fake_getpass(*_: Any, **__: Any) -> str: + nonlocal count + assert count <= 1 + if count == 0: + passwd = " test " + else: + passwd = "test " + count += 1 + return passwd + + mocker.patch.object(getpass, "getpass", fake_getpass) + with pytest.raises(SystemExit, match="Sorry, passwords do not match"): + _run_htpasswd(htpasswd, ["set", "admin"]) + assert count == 2 + + htpasswd.load(force=True) + assert htpasswd.check_password("admin", _make_passwd("admin")) + assert old_users == set(htpasswd.users()) + + +# ===== +def test_ok__del(htpasswd: passlib.apache.HtpasswdFile) -> None: + old_users = set(htpasswd.users()) + + if old_users: + assert htpasswd.check_password("admin", _make_passwd("admin")) + + _run_htpasswd(htpasswd, ["del", "admin"]) + + htpasswd.load(force=True) + assert not htpasswd.check_password("admin", _make_passwd("admin")) + assert old_users.difference(["admin"]) == set(htpasswd.users()) diff --git a/tests/auth/__init__.py b/tests/auth/__init__.py new file mode 100644 index 00000000..cdaa6cfb --- /dev/null +++ b/tests/auth/__init__.py @@ -0,0 +1,43 @@ +# ========================================================================== # +# # +# KVMD - The main Pi-KVM daemon. # +# # +# Copyright (C) 2018 Maxim Devaev # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +# ========================================================================== # + + +import contextlib + +from typing import AsyncGenerator +from typing import Any + +from kvmd.yamlconf import make_config + +from kvmd.plugins.auth import BaseAuthService +from kvmd.plugins.auth import get_auth_service_class + + +# ===== +@contextlib.asynccontextmanager +async def get_configured_auth_service(name: str, **kwargs: Any) -> AsyncGenerator[BaseAuthService, None]: + service_class = get_auth_service_class(name) + config = make_config(kwargs, service_class.get_options()) + service = service_class(**config._unpack()) # pylint: disable=protected-access + try: + yield service + finally: + await service.cleanup() diff --git a/tests/auth/test_service_htpasswd.py b/tests/auth/test_service_htpasswd.py new file mode 100644 index 00000000..9a24378e --- /dev/null +++ b/tests/auth/test_service_htpasswd.py @@ -0,0 +1,52 @@ +# ========================================================================== # +# # +# KVMD - The main Pi-KVM daemon. # +# # +# Copyright (C) 2018 Maxim Devaev # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +# ========================================================================== # + + +import os + +import passlib.apache + +import pytest + +from . import get_configured_auth_service + + +# ===== +@pytest.mark.asyncio +async def test_ok__htpasswd_service(tmpdir) -> None: # type: ignore + path = os.path.abspath(str(tmpdir.join("htpasswd"))) + + htpasswd = passlib.apache.HtpasswdFile(path, new=True) + htpasswd.set_password("admin", "foo") + htpasswd.save() + + async with get_configured_auth_service("htpasswd", file=path) as service: + assert (await service.login("admin", "foo")) + assert not (await service.login("user", "foo")) + + htpasswd.set_password("admin", "bar") + htpasswd.set_password("user", "bar") + htpasswd.save() + + assert (await service.login("admin", "bar")) + assert (await service.login("user", "bar")) + assert not (await service.login("admin", "foo")) + assert not (await service.login("user", "foo")) diff --git a/tests/auth/test_service_http.py b/tests/auth/test_service_http.py new file mode 100644 index 00000000..6390f368 --- /dev/null +++ b/tests/auth/test_service_http.py @@ -0,0 +1,60 @@ +# ========================================================================== # +# # +# KVMD - The main Pi-KVM daemon. # +# # +# Copyright (C) 2018 Maxim Devaev # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +# ========================================================================== # + + +from typing import AsyncGenerator + +import aiohttp.web + +import pytest + +from . import get_configured_auth_service + + +# ===== +async def _handle_auth_post(request: aiohttp.web.BaseRequest) -> aiohttp.web.Response: + status = 400 + if request.method == "POST": + credentials = (await request.json()) + if credentials["user"] == "admin" and credentials["passwd"] == "foobar": + status = 200 + return aiohttp.web.Response(text=str(status), status=status) + + +@pytest.fixture(name="auth_server_port") +async def _auth_server_port_fixture(aiohttp_server) -> AsyncGenerator[int, None]: # type: ignore + app = aiohttp.web.Application() + app.router.add_post("/auth_post", _handle_auth_post) + server = await aiohttp_server(app) + try: + yield server.port + finally: + await server.close() + + +# ===== +@pytest.mark.asyncio +async def test_ok__http_service(auth_server_port: int) -> None: + url = "http://localhost:%d/auth_post" % (auth_server_port) + async with get_configured_auth_service("http", url=url) as service: + assert not (await service.login("admin", "foo")) + assert not (await service.login("user", "foo")) + assert (await service.login("admin", "foobar")) diff --git a/tests/test_app_cleanup.py b/tests/test_app_cleanup.py deleted file mode 100644 index 3e2e4c72..00000000 --- a/tests/test_app_cleanup.py +++ /dev/null @@ -1,71 +0,0 @@ -# ========================================================================== # -# # -# KVMD - The main Pi-KVM daemon. # -# # -# Copyright (C) 2018 Maxim Devaev # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see . # -# # -# ========================================================================== # - - -import os -import secrets -import multiprocessing -import multiprocessing.queues -import time - -import setproctitle - -from kvmd.apps.cleanup import main - - -# ===== -def test_ok(tmpdir) -> None: # type: ignore - queue: multiprocessing.queues.Queue = multiprocessing.Queue() - - ustreamer_tmp_path = os.path.abspath(str(tmpdir.join("ustr-" + secrets.token_hex(3)))) - os.symlink("/usr/bin/ustreamer", ustreamer_tmp_path) - - ustreamer_sock_path = os.path.abspath(str(tmpdir.join("ustreamer-fake.sock"))) - open(ustreamer_sock_path, "w").close() - kvmd_sock_path = os.path.abspath(str(tmpdir.join("kvmd-fake.sock"))) - open(kvmd_sock_path, "w").close() - - def ustreamer_fake() -> None: - setproctitle.setproctitle(os.path.basename(ustreamer_tmp_path)) - queue.put(True) - while True: - time.sleep(1) - - proc = multiprocessing.Process(target=ustreamer_fake, daemon=True) - proc.start() - assert queue.get(timeout=5) - - assert proc.is_alive() - main([ - "kvmd-cleanup", - "--set-options", - "kvmd/server/port=0", - "kvmd/server/unix=" + kvmd_sock_path, - "kvmd/streamer/port=0", - "kvmd/streamer/unix=" + ustreamer_sock_path, - "kvmd/streamer/cmd=" + ustreamer_tmp_path, - ]) - - assert not os.path.exists(ustreamer_sock_path) - assert not os.path.exists(kvmd_sock_path) - - assert not proc.is_alive() - proc.join() diff --git a/tests/test_app_htpasswd.py b/tests/test_app_htpasswd.py deleted file mode 100644 index 11895c85..00000000 --- a/tests/test_app_htpasswd.py +++ /dev/null @@ -1,151 +0,0 @@ -# ========================================================================== # -# # -# KVMD - The main Pi-KVM daemon. # -# # -# Copyright (C) 2018 Maxim Devaev # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see . # -# # -# ========================================================================== # - - -import os -import hashlib -import tempfile -import builtins -import getpass - -from typing import List -from typing import Generator -from typing import Any - -import passlib.apache - -import pytest - -from kvmd.apps.htpasswd import main - - -# ===== -def _make_passwd(user: str) -> str: - return hashlib.md5(user.encode()).hexdigest() - - -@pytest.fixture(name="htpasswd", params=[[], ["admin"], ["admin", "user"]]) -def _htpasswd_fixture(request) -> Generator[passlib.apache.HtpasswdFile, None, None]: # type: ignore - (fd, path) = tempfile.mkstemp() - os.close(fd) - htpasswd = passlib.apache.HtpasswdFile(path) - for user in request.param: - htpasswd.set_password(user, _make_passwd(user)) - htpasswd.save() - yield htpasswd - os.remove(path) - - -def _run_htpasswd(htpasswd: passlib.apache.HtpasswdFile, cmd: List[str]) -> None: - main([ - "kvmd-htpasswd", - *cmd, - "--set-options", - "kvmd/auth/internal/file=" + htpasswd.path, - ]) - - -# ===== -def test_ok__list(htpasswd: passlib.apache.HtpasswdFile, capsys) -> None: # type: ignore - _run_htpasswd(htpasswd, ["list"]) - (out, err) = capsys.readouterr() - assert len(err) == 0 - assert sorted(filter(None, out.split("\n"))) == sorted(htpasswd.users()) == sorted(set(htpasswd.users())) - - -# ===== -def test_ok__set_change_stdin(htpasswd: passlib.apache.HtpasswdFile, mocker) -> None: # type: ignore - old_users = set(htpasswd.users()) - if old_users: - assert htpasswd.check_password("admin", _make_passwd("admin")) - - mocker.patch.object(builtins, "input", (lambda: " test ")) - _run_htpasswd(htpasswd, ["set", "admin", "--read-stdin"]) - - htpasswd.load(force=True) - assert htpasswd.check_password("admin", " test ") - assert old_users == set(htpasswd.users()) - - -def test_ok__set_add_stdin(htpasswd: passlib.apache.HtpasswdFile, mocker) -> None: # type: ignore - old_users = set(htpasswd.users()) - if old_users: - mocker.patch.object(builtins, "input", (lambda: " test ")) - _run_htpasswd(htpasswd, ["set", "new", "--read-stdin"]) - - htpasswd.load(force=True) - assert htpasswd.check_password("new", " test ") - assert old_users.union(["new"]) == set(htpasswd.users()) - - -# ===== -def test_ok__set_change_getpass(htpasswd: passlib.apache.HtpasswdFile, mocker) -> None: # type: ignore - old_users = set(htpasswd.users()) - if old_users: - assert htpasswd.check_password("admin", _make_passwd("admin")) - - mocker.patch.object(getpass, "getpass", (lambda *_, **__: " test ")) - _run_htpasswd(htpasswd, ["set", "admin"]) - - htpasswd.load(force=True) - assert htpasswd.check_password("admin", " test ") - assert old_users == set(htpasswd.users()) - - -def test_fail__set_change_getpass(htpasswd: passlib.apache.HtpasswdFile, mocker) -> None: # type: ignore - old_users = set(htpasswd.users()) - if old_users: - assert htpasswd.check_password("admin", _make_passwd("admin")) - - count = 0 - - def fake_getpass(*_: Any, **__: Any) -> str: - nonlocal count - assert count <= 1 - if count == 0: - passwd = " test " - else: - passwd = "test " - count += 1 - return passwd - - mocker.patch.object(getpass, "getpass", fake_getpass) - with pytest.raises(SystemExit, match="Sorry, passwords do not match"): - _run_htpasswd(htpasswd, ["set", "admin"]) - assert count == 2 - - htpasswd.load(force=True) - assert htpasswd.check_password("admin", _make_passwd("admin")) - assert old_users == set(htpasswd.users()) - - -# ===== -def test_ok__del(htpasswd: passlib.apache.HtpasswdFile) -> None: - old_users = set(htpasswd.users()) - - if old_users: - assert htpasswd.check_password("admin", _make_passwd("admin")) - - _run_htpasswd(htpasswd, ["del", "admin"]) - - htpasswd.load(force=True) - assert not htpasswd.check_password("admin", _make_passwd("admin")) - assert old_users.difference(["admin"]) == set(htpasswd.users()) diff --git a/tests/test_auth_service_htpasswd.py b/tests/test_auth_service_htpasswd.py deleted file mode 100644 index 2bca4988..00000000 --- a/tests/test_auth_service_htpasswd.py +++ /dev/null @@ -1,55 +0,0 @@ -# ========================================================================== # -# # -# KVMD - The main Pi-KVM daemon. # -# # -# Copyright (C) 2018 Maxim Devaev # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see . # -# # -# ========================================================================== # - - -import os - -import passlib.apache - -import pytest - -from kvmd.plugins.auth import get_auth_service_class - - -# ===== -@pytest.mark.asyncio -async def test_ok__htpasswd_service(tmpdir) -> None: # type: ignore - path = os.path.abspath(str(tmpdir.join("htpasswd"))) - - htpasswd = passlib.apache.HtpasswdFile(path, new=True) - htpasswd.set_password("admin", "foo") - htpasswd.save() - - service = get_auth_service_class("htpasswd")(path=path) - - assert (await service.login("admin", "foo")) - assert not (await service.login("user", "foo")) - - htpasswd.set_password("admin", "bar") - htpasswd.set_password("user", "bar") - htpasswd.save() - - assert (await service.login("admin", "bar")) - assert (await service.login("user", "bar")) - assert not (await service.login("admin", "foo")) - assert not (await service.login("user", "foo")) - - await service.cleanup() diff --git a/tests/test_auth_service_http.py b/tests/test_auth_service_http.py deleted file mode 100644 index 6ec9527b..00000000 --- a/tests/test_auth_service_http.py +++ /dev/null @@ -1,69 +0,0 @@ -# ========================================================================== # -# # -# KVMD - The main Pi-KVM daemon. # -# # -# Copyright (C) 2018 Maxim Devaev # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see . # -# # -# ========================================================================== # - - -from typing import AsyncGenerator - -import aiohttp.web - -import pytest - -from kvmd.plugins.auth import get_auth_service_class - - -# ===== -async def _handle_auth_post(request: aiohttp.web.BaseRequest) -> aiohttp.web.Response: - status = 400 - if request.method == "POST": - credentials = (await request.json()) - if credentials["user"] == "admin" and credentials["passwd"] == "foobar": - status = 200 - return aiohttp.web.Response(text=str(status), status=status) - - -@pytest.fixture(name="auth_server_port") -async def _auth_server_port_fixture(aiohttp_server) -> AsyncGenerator[int, None]: # type: ignore - app = aiohttp.web.Application() - app.router.add_post("/auth_post", _handle_auth_post) - server = await aiohttp_server(app) - try: - yield server.port - finally: - await server.close() - - -# ===== -@pytest.mark.asyncio -async def test_ok__http_service(auth_server_port: int) -> None: - service = get_auth_service_class("http")( - url="http://localhost:%d/auth_post" % (auth_server_port), - verify=False, - post=True, - user="", - passwd="", - timeout=5.0, - ) - - assert not (await service.login("admin", "foo")) - assert not (await service.login("user", "foo")) - assert (await service.login("admin", "foobar")) - - await service.cleanup() diff --git a/tests/test_validators_auth.py b/tests/test_validators_auth.py deleted file mode 100644 index f3cdf939..00000000 --- a/tests/test_validators_auth.py +++ /dev/null @@ -1,130 +0,0 @@ -# ========================================================================== # -# # -# KVMD - The main Pi-KVM daemon. # -# # -# Copyright (C) 2018 Maxim Devaev # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see . # -# # -# ========================================================================== # - - -from typing import List -from typing import Any - -import pytest - -from kvmd.validators import ValidatorError -from kvmd.validators.auth import valid_user -from kvmd.validators.auth import valid_users_list -from kvmd.validators.auth import valid_passwd -from kvmd.validators.auth import valid_auth_token - - -# ===== -@pytest.mark.parametrize("arg", [ - "test-", - "glados", - "test", - "_", - "_foo_bar_", - " aix", -]) -def test_ok__valid_user(arg: Any) -> None: - assert valid_user(arg) == arg.strip() - - -@pytest.mark.parametrize("arg", [ - "тест", - "-molestia", - "te~st", - "-", - "-foo_bar", - " ", - "", - None, -]) -def test_fail__valid_user(arg: Any) -> None: - with pytest.raises(ValidatorError): - print(valid_user(arg)) - - -# ===== -@pytest.mark.parametrize("arg, retval", [ - ("foo, bar, ", ["foo", "bar"]), - ("foo bar", ["foo", "bar"]), - (["foo", "bar"], ["foo", "bar"]), - ("", []), - (" ", []), - (", ", []), - (", foo, ", ["foo"]), - ([], []), -]) -def test_ok__valid_users_list(arg: Any, retval: List) -> None: - assert valid_users_list(arg) == retval - - -@pytest.mark.parametrize("arg", [None, [None], [""], [" "], ["user,"]]) -def test_fail__valid_users_list(arg: Any) -> None: # pylint: disable=invalid-name - with pytest.raises(ValidatorError): - print(valid_users_list(arg)) - - -# ===== -@pytest.mark.parametrize("arg", [ - "glados", - "test", - "_", - "_foo_bar_", - " aix", - " ", - "", - " O(*#&@)FD*S)D(F ", -]) -def test_ok__valid_passwd(arg: Any) -> None: - assert valid_passwd(arg) == arg - - -@pytest.mark.parametrize("arg", [ - "тест", - "\n", - " \n", - "\n\n", - "\r", - None, -]) -def test_fail__valid_passwd(arg: Any) -> None: - with pytest.raises(ValidatorError): - print(valid_passwd(arg)) - - -# ===== -@pytest.mark.parametrize("arg", [ - ("0" * 64) + " ", - ("f" * 64) + " ", -]) -def test_ok__valid_auth_token(arg: Any) -> None: - assert valid_auth_token(arg) == arg.strip() - - -@pytest.mark.parametrize("arg", [ - ("F" * 64), - "0" * 63, - "0" * 65, - "", - None, -]) -def test_fail__valid_auth_token(arg: Any) -> None: - with pytest.raises(ValidatorError): - print(valid_auth_token(arg)) diff --git a/tests/test_validators_basic.py b/tests/test_validators_basic.py deleted file mode 100644 index 96feb666..00000000 --- a/tests/test_validators_basic.py +++ /dev/null @@ -1,144 +0,0 @@ -# ========================================================================== # -# # -# KVMD - The main Pi-KVM daemon. # -# # -# Copyright (C) 2018 Maxim Devaev # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see . # -# # -# ========================================================================== # - - -from typing import List -from typing import Any - -import pytest - -from kvmd.validators import ValidatorError -from kvmd.validators.basic import valid_bool -from kvmd.validators.basic import valid_number -from kvmd.validators.basic import valid_int_f1 -from kvmd.validators.basic import valid_float_f01 -from kvmd.validators.basic import valid_string_list - - -# ===== -@pytest.mark.parametrize("arg, retval", [ - ("1", True), - ("true", True), - ("TRUE", True), - ("yes ", True), - (1, True), - (True, True), - ("0", False), - ("false", False), - ("FALSE", False), - ("no ", False), - (0, False), - (False, False), -]) -def test_ok__valid_bool(arg: Any, retval: bool) -> None: - assert valid_bool(arg) == retval - - -@pytest.mark.parametrize("arg", ["test", "", None, -1, "x"]) -def test_fail__valid_bool(arg: Any) -> None: - with pytest.raises(ValidatorError): - print(valid_bool(arg)) - - -# ===== -@pytest.mark.parametrize("arg", ["1 ", "-1", 1, -1, 0, 100500]) -def test_ok__valid_number(arg: Any) -> None: - assert valid_number(arg) == int(str(arg).strip()) - - -@pytest.mark.parametrize("arg", ["test", "", None, "1x", 100500.0]) -def test_fail__valid_number(arg: Any) -> None: - with pytest.raises(ValidatorError): - print(valid_number(arg)) - - -@pytest.mark.parametrize("arg", [-5, 0, 5, "-5 ", "0 ", "5 "]) -def test_ok__valid_number__min_max(arg: Any) -> None: - assert valid_number(arg, -5, 5) == int(str(arg).strip()) - - -@pytest.mark.parametrize("arg", ["test", "", None, -6, 6, "-6 ", "6 "]) -def test_fail__valid_number__min_max(arg: Any) -> None: # pylint: disable=invalid-name - with pytest.raises(ValidatorError): - print(valid_number(arg, -5, 5)) - - -# ===== -@pytest.mark.parametrize("arg", [1, 5, "5 "]) -def test_ok__valid_int_f1(arg: Any) -> None: - value = valid_int_f1(arg) - assert type(value) == int # pylint: disable=unidiomatic-typecheck - assert value == int(str(arg).strip()) - - -@pytest.mark.parametrize("arg", ["test", "", None, -6, "-6 ", 0, "0 ", "5.0"]) -def test_fail__valid_int_f1(arg: Any) -> None: - with pytest.raises(ValidatorError): - print(valid_int_f1(arg)) - - -# ===== -@pytest.mark.parametrize("arg", [0.1, 1, 5, "5 ", "5.0 "]) -def test_ok__valid_float_f01(arg: Any) -> None: - value = valid_float_f01(arg) - assert type(value) == float # pylint: disable=unidiomatic-typecheck - assert value == float(str(arg).strip()) - - -@pytest.mark.parametrize("arg", ["test", "", None, 0.0, "0.0", -6, "-6", 0, "0"]) -def test_fail__valid_float_f01(arg: Any) -> None: - with pytest.raises(ValidatorError): - print(valid_float_f01(arg)) - - -# ===== -@pytest.mark.parametrize("arg, retval", [ - ("a, b, c", ["a", "b", "c"]), - ("a b c", ["a", "b", "c"]), - (["a", "b", "c"], ["a", "b", "c"]), - ("", []), - (" ", []), - (", ", []), - (", a, ", ["a"]), - ([], []), -]) -def test_ok__valid_string_list(arg: Any, retval: List) -> None: - assert valid_string_list(arg) == retval - - -@pytest.mark.parametrize("arg, retval", [ - ("1, 2, 3", [1, 2, 3]), - ("1 2 3", [1, 2, 3]), - ([1, 2, 3], [1, 2, 3]), - ("", []), - (" ", []), - (", ", []), - (", 1, ", [1]), - ([], []), -]) -def test_ok__valid_string_list__subval(arg: Any, retval: List) -> None: # pylint: disable=invalid-name - assert valid_string_list(arg, subval=int) == retval - - -@pytest.mark.parametrize("arg", [None, [None]]) -def test_fail__valid_string_list(arg: Any) -> None: # pylint: disable=invalid-name - with pytest.raises(ValidatorError): - print(valid_string_list(arg)) diff --git a/tests/test_validators_hw.py b/tests/test_validators_hw.py deleted file mode 100644 index 2c93d3eb..00000000 --- a/tests/test_validators_hw.py +++ /dev/null @@ -1,72 +0,0 @@ -# ========================================================================== # -# # -# KVMD - The main Pi-KVM daemon. # -# # -# Copyright (C) 2018 Maxim Devaev # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see . # -# # -# ========================================================================== # - - -from typing import Any - -import pytest - -from kvmd.validators import ValidatorError -from kvmd.validators.hw import valid_tty_speed -from kvmd.validators.hw import valid_gpio_pin -from kvmd.validators.hw import valid_gpio_pin_optional - - -# ===== -@pytest.mark.parametrize("arg", ["1200 ", 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200]) -def test_ok__valid_tty_speed(arg: Any) -> None: - value = valid_tty_speed(arg) - assert type(value) == int # pylint: disable=unidiomatic-typecheck - assert value == int(str(arg).strip()) - - -@pytest.mark.parametrize("arg", ["test", "", None, 0, 1200.1]) -def test_fail__valid_tty_speed(arg: Any) -> None: - with pytest.raises(ValidatorError): - print(valid_tty_speed(arg)) - - -# ===== -@pytest.mark.parametrize("arg", ["0 ", 0, 1, 13]) -def test_ok__valid_gpio_pin(arg: Any) -> None: - value = valid_gpio_pin(arg) - assert type(value) == int # pylint: disable=unidiomatic-typecheck - assert value == int(str(arg).strip()) - - -@pytest.mark.parametrize("arg", ["test", "", None, -1, -13, 1.1]) -def test_fail__valid_gpio_pin(arg: Any) -> None: - with pytest.raises(ValidatorError): - print(valid_gpio_pin(arg)) - - -# ===== -@pytest.mark.parametrize("arg", ["0 ", -1, 0, 1, 13]) -def test_ok__valid_gpio_pin_optional(arg: Any) -> None: - value = valid_gpio_pin_optional(arg) - assert type(value) == int # pylint: disable=unidiomatic-typecheck - assert value == int(str(arg).strip()) - - -@pytest.mark.parametrize("arg", ["test", "", None, -2, -13, 1.1]) -def test_fail__valid_gpio_pin_optional(arg: Any) -> None: - with pytest.raises(ValidatorError): - print(valid_gpio_pin_optional(arg)) diff --git a/tests/test_validators_kvm.py b/tests/test_validators_kvm.py deleted file mode 100644 index f1050b36..00000000 --- a/tests/test_validators_kvm.py +++ /dev/null @@ -1,169 +0,0 @@ -# ========================================================================== # -# # -# KVMD - The main Pi-KVM daemon. # -# # -# Copyright (C) 2018 Maxim Devaev # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see . # -# # -# ========================================================================== # - - -from typing import Any - -import pytest - -from kvmd.keymap import KEYMAP - -from kvmd.validators import ValidatorError -from kvmd.validators.kvm import valid_atx_button -from kvmd.validators.kvm import valid_kvm_target -from kvmd.validators.kvm import valid_log_seek -from kvmd.validators.kvm import valid_stream_quality -from kvmd.validators.kvm import valid_stream_fps -from kvmd.validators.kvm import valid_hid_key -from kvmd.validators.kvm import valid_hid_mouse_move -from kvmd.validators.kvm import valid_hid_mouse_button -from kvmd.validators.kvm import valid_hid_mouse_wheel - - -# ===== -@pytest.mark.parametrize("arg", ["POWER ", "POWER_LONG ", "RESET "]) -def test_ok__valid_atx_button(arg: Any) -> None: - assert valid_atx_button(arg) == arg.strip().lower() - - -@pytest.mark.parametrize("arg", ["test", "", None]) -def test_fail__valid_atx_button(arg: Any) -> None: - with pytest.raises(ValidatorError): - print(valid_atx_button(arg)) - - -# ===== -@pytest.mark.parametrize("arg", ["KVM ", "SERVER "]) -def test_ok__valid_kvm_target(arg: Any) -> None: - assert valid_kvm_target(arg) == arg.strip().lower() - - -@pytest.mark.parametrize("arg", ["test", "", None]) -def test_fail__valid_kvm_target(arg: Any) -> None: - with pytest.raises(ValidatorError): - print(valid_kvm_target(arg)) - - -# ===== -@pytest.mark.parametrize("arg", ["0 ", 0, 1, 13]) -def test_ok__valid_log_seek(arg: Any) -> None: - value = valid_log_seek(arg) - assert type(value) == int # pylint: disable=unidiomatic-typecheck - assert value == int(str(arg).strip()) - - -@pytest.mark.parametrize("arg", ["test", "", None, -1, -13, 1.1]) -def test_fail__valid_log_seek(arg: Any) -> None: - with pytest.raises(ValidatorError): - print(valid_log_seek(arg)) - - -# ===== -@pytest.mark.parametrize("arg", ["1 ", 20, 100]) -def test_ok__valid_stream_quality(arg: Any) -> None: - value = valid_stream_quality(arg) - assert type(value) == int # pylint: disable=unidiomatic-typecheck - assert value == int(str(arg).strip()) - - -@pytest.mark.parametrize("arg", ["test", "", None, 0, 101, 1.1]) -def test_fail__valid_stream_quality(arg: Any) -> None: - with pytest.raises(ValidatorError): - print(valid_stream_quality(arg)) - - -# ===== -@pytest.mark.parametrize("arg", ["1 ", 30]) -def test_ok__valid_stream_fps(arg: Any) -> None: - value = valid_stream_fps(arg) - assert type(value) == int # pylint: disable=unidiomatic-typecheck - assert value == int(str(arg).strip()) - - -@pytest.mark.parametrize("arg", ["test", "", None, 31, 1.1]) -def test_fail__valid_stream_fps(arg: Any) -> None: - with pytest.raises(ValidatorError): - print(valid_stream_fps(arg)) - - -# ===== -def test_ok__valid_hid_key() -> None: - for key in KEYMAP: - print(valid_hid_key(key)) - print(valid_hid_key(key + " ")) - - -@pytest.mark.parametrize("arg", ["test", "", None, "keya"]) -def test_fail__valid_hid_key(arg: Any) -> None: - with pytest.raises(ValidatorError): - print(valid_hid_key(arg)) - - -# ===== -@pytest.mark.parametrize("arg", [-20000, "1 ", "-1", 1, -1, 0, "20000 "]) -def test_ok__valid_hid_mouse_move(arg: Any) -> None: - assert valid_hid_mouse_move(arg) == int(str(arg).strip()) - - -def test_ok__valid_hid_mouse_move__m50000() -> None: - assert valid_hid_mouse_move(-50000) == -32768 - - -def test_ok__valid_hid_mouse_move__p50000() -> None: - assert valid_hid_mouse_move(50000) == 32767 - - -@pytest.mark.parametrize("arg", ["test", "", None, 1.1]) -def test_fail__valid_hid_mouse_move(arg: Any) -> None: - with pytest.raises(ValidatorError): - print(valid_hid_mouse_move(arg)) - - -# ===== -@pytest.mark.parametrize("arg", ["LEFT ", "RIGHT "]) -def test_ok__valid_hid_mouse_button(arg: Any) -> None: - assert valid_hid_mouse_button(arg) == arg.strip().lower() - - -@pytest.mark.parametrize("arg", ["test", "", None]) -def test_fail__valid_hid_mouse_button(arg: Any) -> None: - with pytest.raises(ValidatorError): - print(valid_hid_mouse_button(arg)) - - -# ===== -@pytest.mark.parametrize("arg", [-100, "1 ", "-1", 1, -1, 0, "100 "]) -def test_ok__valid_hid_mouse_wheel(arg: Any) -> None: - assert valid_hid_mouse_wheel(arg) == int(str(arg).strip()) - - -def test_ok__valid_hid_mouse_wheel__m200() -> None: - assert valid_hid_mouse_wheel(-200) == -128 - - -def test_ok__valid_hid_mouse_wheel__p200() -> None: - assert valid_hid_mouse_wheel(200) == 127 - - -@pytest.mark.parametrize("arg", ["test", "", None, 1.1]) -def test_fail__valid_hid_mouse_wheel(arg: Any) -> None: - with pytest.raises(ValidatorError): - print(valid_hid_mouse_wheel(arg)) diff --git a/tests/test_validators_net.py b/tests/test_validators_net.py deleted file mode 100644 index eab67c9a..00000000 --- a/tests/test_validators_net.py +++ /dev/null @@ -1,122 +0,0 @@ -# ========================================================================== # -# # -# KVMD - The main Pi-KVM daemon. # -# # -# Copyright (C) 2018 Maxim Devaev # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see . # -# # -# ========================================================================== # - - -from typing import Any - -import pytest - -from kvmd.validators import ValidatorError -from kvmd.validators.net import valid_ip_or_host -from kvmd.validators.net import valid_ip -from kvmd.validators.net import valid_rfc_host -from kvmd.validators.net import valid_port - - -# ===== -@pytest.mark.parametrize("arg", [ - "yandex.ru ", - "foobar", - "foo-bar.ru", - "127.0.0.1", - "8.8.8.8", - "::", - "::1", - "2001:500:2f::f", -]) -def test_ok__valid_ip_or_host(arg: Any) -> None: - assert valid_ip_or_host(arg) == arg.strip() - - -@pytest.mark.parametrize("arg", [ - "foo_bar.ru", - "1.1.1.", - ":", - "", - None, -]) -def test_fail__valid_ip_or_host(arg: Any) -> None: - with pytest.raises(ValidatorError): - print(valid_ip_or_host(arg)) - - -# ===== -@pytest.mark.parametrize("arg", [ - "127.0.0.1 ", - "8.8.8.8", - "::", - "::1", - "2001:500:2f::f", -]) -def test_ok__valid_ip(arg: Any) -> None: - assert valid_ip(arg) == arg.strip() - - -@pytest.mark.parametrize("arg", [ - "ya.ru", - "1", - "1.1.1", - "1.1.1.", - ":", - "", - None, -]) -def test_fail__valid_ip(arg: Any) -> None: - with pytest.raises(ValidatorError): - print(valid_ip(arg)) - - -# ===== -@pytest.mark.parametrize("arg", [ - "yandex.ru ", - "foobar", - "foo-bar.ru", - "z0r.de", - "11.ru", - "127.0.0.1", -]) -def test_ok__valid_rfc_host(arg: Any) -> None: - assert valid_rfc_host(arg) == arg.strip() - - -@pytest.mark.parametrize("arg", [ - "foobar.ru.", - "foo_bar.ru", - "", - None, -]) -def test_fail__valid_rfc_host(arg: Any) -> None: - with pytest.raises(ValidatorError): - print(valid_rfc_host(arg)) - - -# ===== -@pytest.mark.parametrize("arg", ["0 ", 0, "22", 443, 65535]) -def test_ok__valid_port(arg: Any) -> None: - value = valid_port(arg) - assert type(value) == int # pylint: disable=unidiomatic-typecheck - assert value == int(str(arg).strip()) - - -@pytest.mark.parametrize("arg", ["test", "", None, 1.1]) -def test_fail__valid_port(arg: Any) -> None: - with pytest.raises(ValidatorError): - print(valid_port(arg)) diff --git a/tests/test_validators_os.py b/tests/test_validators_os.py deleted file mode 100644 index b280b4b3..00000000 --- a/tests/test_validators_os.py +++ /dev/null @@ -1,118 +0,0 @@ -# ========================================================================== # -# # -# KVMD - The main Pi-KVM daemon. # -# # -# Copyright (C) 2018 Maxim Devaev # -# # -# This program is free software: you can redistribute it and/or modify # -# it under the terms of the GNU General Public License as published by # -# the Free Software Foundation, either version 3 of the License, or # -# (at your option) any later version. # -# # -# This program is distributed in the hope that it will be useful, # -# but WITHOUT ANY WARRANTY; without even the implied warranty of # -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # -# GNU General Public License for more details. # -# # -# You should have received a copy of the GNU General Public License # -# along with this program. If not, see . # -# # -# ========================================================================== # - - -import os - -from typing import List -from typing import Any - -import pytest - -from kvmd.validators import ValidatorError -from kvmd.validators.os import valid_abs_path -from kvmd.validators.os import valid_abs_path_exists -from kvmd.validators.os import valid_unix_mode -from kvmd.validators.os import valid_command - - -# ===== -@pytest.mark.parametrize("arg, retval", [ - ("/..", "/"), - ("/root/..", "/"), - ("/root", "/root"), - ("/f/o/o/b/a/r", "/f/o/o/b/a/r"), - ("~", os.path.abspath(".") + "/~"), - ("/foo~", "/foo~"), - ("/foo/~", "/foo/~"), - (".", os.path.abspath(".")), -]) -def test_ok__valid_abs_path(arg: Any, retval: str) -> None: - assert valid_abs_path(arg) == retval - - -@pytest.mark.parametrize("arg", ["", " ", None]) -def test_fail__valid_abs_path(arg: Any) -> None: - with pytest.raises(ValidatorError): - print(valid_abs_path(arg)) - - -# ===== -@pytest.mark.parametrize("arg, retval", [ - ("/..", "/"), - ("/root/..", "/"), - ("/root", "/root"), - (".", os.path.abspath(".")), -]) -def test_ok__valid_abs_path_exists(arg: Any, retval: str) -> None: - assert valid_abs_path_exists(arg) == retval - - -@pytest.mark.parametrize("arg", [ - "/f/o/o/b/a/r", - "~", - "/foo~", - "/foo/~", - "", - None, -]) -def test_fail__valid_abs_path_exists(arg: Any) -> None: - with pytest.raises(ValidatorError): - print(valid_abs_path_exists(arg)) - - -# ===== -@pytest.mark.parametrize("arg", [0, 5, "1000"]) -def test_ok__valid_unix_mode(arg: Any) -> None: - value = valid_unix_mode(arg) - assert type(value) == int # pylint: disable=unidiomatic-typecheck - assert value == int(str(value).strip()) - - -@pytest.mark.parametrize("arg", ["test", "", None, -6, "-6", "5.0"]) -def test_fail__valid_unix_mode(arg: Any) -> None: - with pytest.raises(ValidatorError): - print(valid_unix_mode(arg)) - - -# ===== -@pytest.mark.parametrize("arg, retval", [ - (["/bin/true"], ["/bin/true"]), - (["/bin/true", 1, 2, 3], ["/bin/true", "1", "2", "3"]), - ("/bin/true, 1, 2, 3,", ["/bin/true", "1", "2", "3"]), - ("/bin/true", ["/bin/true"]), -]) -def test_ok__valid_command(arg: Any, retval: List[str]) -> None: - assert valid_command(arg) == retval - - -@pytest.mark.parametrize("arg", [ - ["/bin/blahblahblah"], - ["/bin/blahblahblah", 1, 2, 3], - [" "], - [], - "/bin/blahblahblah, 1, 2, 3,", - "/bin/blahblahblah", - " ", -]) -def test_fail__valid_command(arg: Any) -> None: - with pytest.raises(ValidatorError): - print(valid_command(arg)) diff --git a/tests/validators/__init__.py b/tests/validators/__init__.py new file mode 100644 index 00000000..1e91f7fa --- /dev/null +++ b/tests/validators/__init__.py @@ -0,0 +1,20 @@ +# ========================================================================== # +# # +# KVMD - The main Pi-KVM daemon. # +# # +# Copyright (C) 2018 Maxim Devaev # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +# ========================================================================== # diff --git a/tests/validators/test_auth.py b/tests/validators/test_auth.py new file mode 100644 index 00000000..f3cdf939 --- /dev/null +++ b/tests/validators/test_auth.py @@ -0,0 +1,130 @@ +# ========================================================================== # +# # +# KVMD - The main Pi-KVM daemon. # +# # +# Copyright (C) 2018 Maxim Devaev # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +# ========================================================================== # + + +from typing import List +from typing import Any + +import pytest + +from kvmd.validators import ValidatorError +from kvmd.validators.auth import valid_user +from kvmd.validators.auth import valid_users_list +from kvmd.validators.auth import valid_passwd +from kvmd.validators.auth import valid_auth_token + + +# ===== +@pytest.mark.parametrize("arg", [ + "test-", + "glados", + "test", + "_", + "_foo_bar_", + " aix", +]) +def test_ok__valid_user(arg: Any) -> None: + assert valid_user(arg) == arg.strip() + + +@pytest.mark.parametrize("arg", [ + "тест", + "-molestia", + "te~st", + "-", + "-foo_bar", + " ", + "", + None, +]) +def test_fail__valid_user(arg: Any) -> None: + with pytest.raises(ValidatorError): + print(valid_user(arg)) + + +# ===== +@pytest.mark.parametrize("arg, retval", [ + ("foo, bar, ", ["foo", "bar"]), + ("foo bar", ["foo", "bar"]), + (["foo", "bar"], ["foo", "bar"]), + ("", []), + (" ", []), + (", ", []), + (", foo, ", ["foo"]), + ([], []), +]) +def test_ok__valid_users_list(arg: Any, retval: List) -> None: + assert valid_users_list(arg) == retval + + +@pytest.mark.parametrize("arg", [None, [None], [""], [" "], ["user,"]]) +def test_fail__valid_users_list(arg: Any) -> None: # pylint: disable=invalid-name + with pytest.raises(ValidatorError): + print(valid_users_list(arg)) + + +# ===== +@pytest.mark.parametrize("arg", [ + "glados", + "test", + "_", + "_foo_bar_", + " aix", + " ", + "", + " O(*#&@)FD*S)D(F ", +]) +def test_ok__valid_passwd(arg: Any) -> None: + assert valid_passwd(arg) == arg + + +@pytest.mark.parametrize("arg", [ + "тест", + "\n", + " \n", + "\n\n", + "\r", + None, +]) +def test_fail__valid_passwd(arg: Any) -> None: + with pytest.raises(ValidatorError): + print(valid_passwd(arg)) + + +# ===== +@pytest.mark.parametrize("arg", [ + ("0" * 64) + " ", + ("f" * 64) + " ", +]) +def test_ok__valid_auth_token(arg: Any) -> None: + assert valid_auth_token(arg) == arg.strip() + + +@pytest.mark.parametrize("arg", [ + ("F" * 64), + "0" * 63, + "0" * 65, + "", + None, +]) +def test_fail__valid_auth_token(arg: Any) -> None: + with pytest.raises(ValidatorError): + print(valid_auth_token(arg)) diff --git a/tests/validators/test_basic.py b/tests/validators/test_basic.py new file mode 100644 index 00000000..96feb666 --- /dev/null +++ b/tests/validators/test_basic.py @@ -0,0 +1,144 @@ +# ========================================================================== # +# # +# KVMD - The main Pi-KVM daemon. # +# # +# Copyright (C) 2018 Maxim Devaev # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +# ========================================================================== # + + +from typing import List +from typing import Any + +import pytest + +from kvmd.validators import ValidatorError +from kvmd.validators.basic import valid_bool +from kvmd.validators.basic import valid_number +from kvmd.validators.basic import valid_int_f1 +from kvmd.validators.basic import valid_float_f01 +from kvmd.validators.basic import valid_string_list + + +# ===== +@pytest.mark.parametrize("arg, retval", [ + ("1", True), + ("true", True), + ("TRUE", True), + ("yes ", True), + (1, True), + (True, True), + ("0", False), + ("false", False), + ("FALSE", False), + ("no ", False), + (0, False), + (False, False), +]) +def test_ok__valid_bool(arg: Any, retval: bool) -> None: + assert valid_bool(arg) == retval + + +@pytest.mark.parametrize("arg", ["test", "", None, -1, "x"]) +def test_fail__valid_bool(arg: Any) -> None: + with pytest.raises(ValidatorError): + print(valid_bool(arg)) + + +# ===== +@pytest.mark.parametrize("arg", ["1 ", "-1", 1, -1, 0, 100500]) +def test_ok__valid_number(arg: Any) -> None: + assert valid_number(arg) == int(str(arg).strip()) + + +@pytest.mark.parametrize("arg", ["test", "", None, "1x", 100500.0]) +def test_fail__valid_number(arg: Any) -> None: + with pytest.raises(ValidatorError): + print(valid_number(arg)) + + +@pytest.mark.parametrize("arg", [-5, 0, 5, "-5 ", "0 ", "5 "]) +def test_ok__valid_number__min_max(arg: Any) -> None: + assert valid_number(arg, -5, 5) == int(str(arg).strip()) + + +@pytest.mark.parametrize("arg", ["test", "", None, -6, 6, "-6 ", "6 "]) +def test_fail__valid_number__min_max(arg: Any) -> None: # pylint: disable=invalid-name + with pytest.raises(ValidatorError): + print(valid_number(arg, -5, 5)) + + +# ===== +@pytest.mark.parametrize("arg", [1, 5, "5 "]) +def test_ok__valid_int_f1(arg: Any) -> None: + value = valid_int_f1(arg) + assert type(value) == int # pylint: disable=unidiomatic-typecheck + assert value == int(str(arg).strip()) + + +@pytest.mark.parametrize("arg", ["test", "", None, -6, "-6 ", 0, "0 ", "5.0"]) +def test_fail__valid_int_f1(arg: Any) -> None: + with pytest.raises(ValidatorError): + print(valid_int_f1(arg)) + + +# ===== +@pytest.mark.parametrize("arg", [0.1, 1, 5, "5 ", "5.0 "]) +def test_ok__valid_float_f01(arg: Any) -> None: + value = valid_float_f01(arg) + assert type(value) == float # pylint: disable=unidiomatic-typecheck + assert value == float(str(arg).strip()) + + +@pytest.mark.parametrize("arg", ["test", "", None, 0.0, "0.0", -6, "-6", 0, "0"]) +def test_fail__valid_float_f01(arg: Any) -> None: + with pytest.raises(ValidatorError): + print(valid_float_f01(arg)) + + +# ===== +@pytest.mark.parametrize("arg, retval", [ + ("a, b, c", ["a", "b", "c"]), + ("a b c", ["a", "b", "c"]), + (["a", "b", "c"], ["a", "b", "c"]), + ("", []), + (" ", []), + (", ", []), + (", a, ", ["a"]), + ([], []), +]) +def test_ok__valid_string_list(arg: Any, retval: List) -> None: + assert valid_string_list(arg) == retval + + +@pytest.mark.parametrize("arg, retval", [ + ("1, 2, 3", [1, 2, 3]), + ("1 2 3", [1, 2, 3]), + ([1, 2, 3], [1, 2, 3]), + ("", []), + (" ", []), + (", ", []), + (", 1, ", [1]), + ([], []), +]) +def test_ok__valid_string_list__subval(arg: Any, retval: List) -> None: # pylint: disable=invalid-name + assert valid_string_list(arg, subval=int) == retval + + +@pytest.mark.parametrize("arg", [None, [None]]) +def test_fail__valid_string_list(arg: Any) -> None: # pylint: disable=invalid-name + with pytest.raises(ValidatorError): + print(valid_string_list(arg)) diff --git a/tests/validators/test_hw.py b/tests/validators/test_hw.py new file mode 100644 index 00000000..2c93d3eb --- /dev/null +++ b/tests/validators/test_hw.py @@ -0,0 +1,72 @@ +# ========================================================================== # +# # +# KVMD - The main Pi-KVM daemon. # +# # +# Copyright (C) 2018 Maxim Devaev # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +# ========================================================================== # + + +from typing import Any + +import pytest + +from kvmd.validators import ValidatorError +from kvmd.validators.hw import valid_tty_speed +from kvmd.validators.hw import valid_gpio_pin +from kvmd.validators.hw import valid_gpio_pin_optional + + +# ===== +@pytest.mark.parametrize("arg", ["1200 ", 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200]) +def test_ok__valid_tty_speed(arg: Any) -> None: + value = valid_tty_speed(arg) + assert type(value) == int # pylint: disable=unidiomatic-typecheck + assert value == int(str(arg).strip()) + + +@pytest.mark.parametrize("arg", ["test", "", None, 0, 1200.1]) +def test_fail__valid_tty_speed(arg: Any) -> None: + with pytest.raises(ValidatorError): + print(valid_tty_speed(arg)) + + +# ===== +@pytest.mark.parametrize("arg", ["0 ", 0, 1, 13]) +def test_ok__valid_gpio_pin(arg: Any) -> None: + value = valid_gpio_pin(arg) + assert type(value) == int # pylint: disable=unidiomatic-typecheck + assert value == int(str(arg).strip()) + + +@pytest.mark.parametrize("arg", ["test", "", None, -1, -13, 1.1]) +def test_fail__valid_gpio_pin(arg: Any) -> None: + with pytest.raises(ValidatorError): + print(valid_gpio_pin(arg)) + + +# ===== +@pytest.mark.parametrize("arg", ["0 ", -1, 0, 1, 13]) +def test_ok__valid_gpio_pin_optional(arg: Any) -> None: + value = valid_gpio_pin_optional(arg) + assert type(value) == int # pylint: disable=unidiomatic-typecheck + assert value == int(str(arg).strip()) + + +@pytest.mark.parametrize("arg", ["test", "", None, -2, -13, 1.1]) +def test_fail__valid_gpio_pin_optional(arg: Any) -> None: + with pytest.raises(ValidatorError): + print(valid_gpio_pin_optional(arg)) diff --git a/tests/validators/test_kvm.py b/tests/validators/test_kvm.py new file mode 100644 index 00000000..f1050b36 --- /dev/null +++ b/tests/validators/test_kvm.py @@ -0,0 +1,169 @@ +# ========================================================================== # +# # +# KVMD - The main Pi-KVM daemon. # +# # +# Copyright (C) 2018 Maxim Devaev # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +# ========================================================================== # + + +from typing import Any + +import pytest + +from kvmd.keymap import KEYMAP + +from kvmd.validators import ValidatorError +from kvmd.validators.kvm import valid_atx_button +from kvmd.validators.kvm import valid_kvm_target +from kvmd.validators.kvm import valid_log_seek +from kvmd.validators.kvm import valid_stream_quality +from kvmd.validators.kvm import valid_stream_fps +from kvmd.validators.kvm import valid_hid_key +from kvmd.validators.kvm import valid_hid_mouse_move +from kvmd.validators.kvm import valid_hid_mouse_button +from kvmd.validators.kvm import valid_hid_mouse_wheel + + +# ===== +@pytest.mark.parametrize("arg", ["POWER ", "POWER_LONG ", "RESET "]) +def test_ok__valid_atx_button(arg: Any) -> None: + assert valid_atx_button(arg) == arg.strip().lower() + + +@pytest.mark.parametrize("arg", ["test", "", None]) +def test_fail__valid_atx_button(arg: Any) -> None: + with pytest.raises(ValidatorError): + print(valid_atx_button(arg)) + + +# ===== +@pytest.mark.parametrize("arg", ["KVM ", "SERVER "]) +def test_ok__valid_kvm_target(arg: Any) -> None: + assert valid_kvm_target(arg) == arg.strip().lower() + + +@pytest.mark.parametrize("arg", ["test", "", None]) +def test_fail__valid_kvm_target(arg: Any) -> None: + with pytest.raises(ValidatorError): + print(valid_kvm_target(arg)) + + +# ===== +@pytest.mark.parametrize("arg", ["0 ", 0, 1, 13]) +def test_ok__valid_log_seek(arg: Any) -> None: + value = valid_log_seek(arg) + assert type(value) == int # pylint: disable=unidiomatic-typecheck + assert value == int(str(arg).strip()) + + +@pytest.mark.parametrize("arg", ["test", "", None, -1, -13, 1.1]) +def test_fail__valid_log_seek(arg: Any) -> None: + with pytest.raises(ValidatorError): + print(valid_log_seek(arg)) + + +# ===== +@pytest.mark.parametrize("arg", ["1 ", 20, 100]) +def test_ok__valid_stream_quality(arg: Any) -> None: + value = valid_stream_quality(arg) + assert type(value) == int # pylint: disable=unidiomatic-typecheck + assert value == int(str(arg).strip()) + + +@pytest.mark.parametrize("arg", ["test", "", None, 0, 101, 1.1]) +def test_fail__valid_stream_quality(arg: Any) -> None: + with pytest.raises(ValidatorError): + print(valid_stream_quality(arg)) + + +# ===== +@pytest.mark.parametrize("arg", ["1 ", 30]) +def test_ok__valid_stream_fps(arg: Any) -> None: + value = valid_stream_fps(arg) + assert type(value) == int # pylint: disable=unidiomatic-typecheck + assert value == int(str(arg).strip()) + + +@pytest.mark.parametrize("arg", ["test", "", None, 31, 1.1]) +def test_fail__valid_stream_fps(arg: Any) -> None: + with pytest.raises(ValidatorError): + print(valid_stream_fps(arg)) + + +# ===== +def test_ok__valid_hid_key() -> None: + for key in KEYMAP: + print(valid_hid_key(key)) + print(valid_hid_key(key + " ")) + + +@pytest.mark.parametrize("arg", ["test", "", None, "keya"]) +def test_fail__valid_hid_key(arg: Any) -> None: + with pytest.raises(ValidatorError): + print(valid_hid_key(arg)) + + +# ===== +@pytest.mark.parametrize("arg", [-20000, "1 ", "-1", 1, -1, 0, "20000 "]) +def test_ok__valid_hid_mouse_move(arg: Any) -> None: + assert valid_hid_mouse_move(arg) == int(str(arg).strip()) + + +def test_ok__valid_hid_mouse_move__m50000() -> None: + assert valid_hid_mouse_move(-50000) == -32768 + + +def test_ok__valid_hid_mouse_move__p50000() -> None: + assert valid_hid_mouse_move(50000) == 32767 + + +@pytest.mark.parametrize("arg", ["test", "", None, 1.1]) +def test_fail__valid_hid_mouse_move(arg: Any) -> None: + with pytest.raises(ValidatorError): + print(valid_hid_mouse_move(arg)) + + +# ===== +@pytest.mark.parametrize("arg", ["LEFT ", "RIGHT "]) +def test_ok__valid_hid_mouse_button(arg: Any) -> None: + assert valid_hid_mouse_button(arg) == arg.strip().lower() + + +@pytest.mark.parametrize("arg", ["test", "", None]) +def test_fail__valid_hid_mouse_button(arg: Any) -> None: + with pytest.raises(ValidatorError): + print(valid_hid_mouse_button(arg)) + + +# ===== +@pytest.mark.parametrize("arg", [-100, "1 ", "-1", 1, -1, 0, "100 "]) +def test_ok__valid_hid_mouse_wheel(arg: Any) -> None: + assert valid_hid_mouse_wheel(arg) == int(str(arg).strip()) + + +def test_ok__valid_hid_mouse_wheel__m200() -> None: + assert valid_hid_mouse_wheel(-200) == -128 + + +def test_ok__valid_hid_mouse_wheel__p200() -> None: + assert valid_hid_mouse_wheel(200) == 127 + + +@pytest.mark.parametrize("arg", ["test", "", None, 1.1]) +def test_fail__valid_hid_mouse_wheel(arg: Any) -> None: + with pytest.raises(ValidatorError): + print(valid_hid_mouse_wheel(arg)) diff --git a/tests/validators/test_net.py b/tests/validators/test_net.py new file mode 100644 index 00000000..eab67c9a --- /dev/null +++ b/tests/validators/test_net.py @@ -0,0 +1,122 @@ +# ========================================================================== # +# # +# KVMD - The main Pi-KVM daemon. # +# # +# Copyright (C) 2018 Maxim Devaev # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +# ========================================================================== # + + +from typing import Any + +import pytest + +from kvmd.validators import ValidatorError +from kvmd.validators.net import valid_ip_or_host +from kvmd.validators.net import valid_ip +from kvmd.validators.net import valid_rfc_host +from kvmd.validators.net import valid_port + + +# ===== +@pytest.mark.parametrize("arg", [ + "yandex.ru ", + "foobar", + "foo-bar.ru", + "127.0.0.1", + "8.8.8.8", + "::", + "::1", + "2001:500:2f::f", +]) +def test_ok__valid_ip_or_host(arg: Any) -> None: + assert valid_ip_or_host(arg) == arg.strip() + + +@pytest.mark.parametrize("arg", [ + "foo_bar.ru", + "1.1.1.", + ":", + "", + None, +]) +def test_fail__valid_ip_or_host(arg: Any) -> None: + with pytest.raises(ValidatorError): + print(valid_ip_or_host(arg)) + + +# ===== +@pytest.mark.parametrize("arg", [ + "127.0.0.1 ", + "8.8.8.8", + "::", + "::1", + "2001:500:2f::f", +]) +def test_ok__valid_ip(arg: Any) -> None: + assert valid_ip(arg) == arg.strip() + + +@pytest.mark.parametrize("arg", [ + "ya.ru", + "1", + "1.1.1", + "1.1.1.", + ":", + "", + None, +]) +def test_fail__valid_ip(arg: Any) -> None: + with pytest.raises(ValidatorError): + print(valid_ip(arg)) + + +# ===== +@pytest.mark.parametrize("arg", [ + "yandex.ru ", + "foobar", + "foo-bar.ru", + "z0r.de", + "11.ru", + "127.0.0.1", +]) +def test_ok__valid_rfc_host(arg: Any) -> None: + assert valid_rfc_host(arg) == arg.strip() + + +@pytest.mark.parametrize("arg", [ + "foobar.ru.", + "foo_bar.ru", + "", + None, +]) +def test_fail__valid_rfc_host(arg: Any) -> None: + with pytest.raises(ValidatorError): + print(valid_rfc_host(arg)) + + +# ===== +@pytest.mark.parametrize("arg", ["0 ", 0, "22", 443, 65535]) +def test_ok__valid_port(arg: Any) -> None: + value = valid_port(arg) + assert type(value) == int # pylint: disable=unidiomatic-typecheck + assert value == int(str(arg).strip()) + + +@pytest.mark.parametrize("arg", ["test", "", None, 1.1]) +def test_fail__valid_port(arg: Any) -> None: + with pytest.raises(ValidatorError): + print(valid_port(arg)) diff --git a/tests/validators/test_os.py b/tests/validators/test_os.py new file mode 100644 index 00000000..b280b4b3 --- /dev/null +++ b/tests/validators/test_os.py @@ -0,0 +1,118 @@ +# ========================================================================== # +# # +# KVMD - The main Pi-KVM daemon. # +# # +# Copyright (C) 2018 Maxim Devaev # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +# ========================================================================== # + + +import os + +from typing import List +from typing import Any + +import pytest + +from kvmd.validators import ValidatorError +from kvmd.validators.os import valid_abs_path +from kvmd.validators.os import valid_abs_path_exists +from kvmd.validators.os import valid_unix_mode +from kvmd.validators.os import valid_command + + +# ===== +@pytest.mark.parametrize("arg, retval", [ + ("/..", "/"), + ("/root/..", "/"), + ("/root", "/root"), + ("/f/o/o/b/a/r", "/f/o/o/b/a/r"), + ("~", os.path.abspath(".") + "/~"), + ("/foo~", "/foo~"), + ("/foo/~", "/foo/~"), + (".", os.path.abspath(".")), +]) +def test_ok__valid_abs_path(arg: Any, retval: str) -> None: + assert valid_abs_path(arg) == retval + + +@pytest.mark.parametrize("arg", ["", " ", None]) +def test_fail__valid_abs_path(arg: Any) -> None: + with pytest.raises(ValidatorError): + print(valid_abs_path(arg)) + + +# ===== +@pytest.mark.parametrize("arg, retval", [ + ("/..", "/"), + ("/root/..", "/"), + ("/root", "/root"), + (".", os.path.abspath(".")), +]) +def test_ok__valid_abs_path_exists(arg: Any, retval: str) -> None: + assert valid_abs_path_exists(arg) == retval + + +@pytest.mark.parametrize("arg", [ + "/f/o/o/b/a/r", + "~", + "/foo~", + "/foo/~", + "", + None, +]) +def test_fail__valid_abs_path_exists(arg: Any) -> None: + with pytest.raises(ValidatorError): + print(valid_abs_path_exists(arg)) + + +# ===== +@pytest.mark.parametrize("arg", [0, 5, "1000"]) +def test_ok__valid_unix_mode(arg: Any) -> None: + value = valid_unix_mode(arg) + assert type(value) == int # pylint: disable=unidiomatic-typecheck + assert value == int(str(value).strip()) + + +@pytest.mark.parametrize("arg", ["test", "", None, -6, "-6", "5.0"]) +def test_fail__valid_unix_mode(arg: Any) -> None: + with pytest.raises(ValidatorError): + print(valid_unix_mode(arg)) + + +# ===== +@pytest.mark.parametrize("arg, retval", [ + (["/bin/true"], ["/bin/true"]), + (["/bin/true", 1, 2, 3], ["/bin/true", "1", "2", "3"]), + ("/bin/true, 1, 2, 3,", ["/bin/true", "1", "2", "3"]), + ("/bin/true", ["/bin/true"]), +]) +def test_ok__valid_command(arg: Any, retval: List[str]) -> None: + assert valid_command(arg) == retval + + +@pytest.mark.parametrize("arg", [ + ["/bin/blahblahblah"], + ["/bin/blahblahblah", 1, 2, 3], + [" "], + [], + "/bin/blahblahblah, 1, 2, 3,", + "/bin/blahblahblah", + " ", +]) +def test_fail__valid_command(arg: Any) -> None: + with pytest.raises(ValidatorError): + print(valid_command(arg)) -- cgit v1.2.3