mirror of
https://github.com/deepfakes/faceswap
synced 2025-06-09 04:36:50 -04:00
- Fix getting free Vram on Nvidia - Don't halt sysinfo on GPU stats error - lib.sysinfo unit test
438 lines
16 KiB
Python
438 lines
16 KiB
Python
#!/usr/bin python3
|
|
""" Pytest unit tests for :mod:`lib.sysinfo` """
|
|
|
|
import locale
|
|
import os
|
|
import platform
|
|
import sys
|
|
|
|
from collections import namedtuple
|
|
from io import StringIO
|
|
from typing import cast
|
|
from unittest.mock import MagicMock
|
|
|
|
import pytest
|
|
import pytest_mock
|
|
|
|
from lib.gpu_stats import GPUInfo
|
|
from lib.sysinfo import _Configs, _State, _SysInfo, CudaCheck, get_sysinfo
|
|
|
|
# pylint:disable=protected-access
|
|
|
|
|
|
# _SysInfo
|
|
@pytest.fixture(name="sys_info_instance")
|
|
def sys_info_fixture() -> _SysInfo:
|
|
""" Single :class:~`lib.utils._SysInfo` object for tests
|
|
|
|
Returns
|
|
-------
|
|
:class:`~lib.utils.sysinfo._SysInfo`
|
|
The class instance for testing
|
|
"""
|
|
return _SysInfo()
|
|
|
|
|
|
def test_init(sys_info_instance: _SysInfo) -> None:
|
|
""" Test :class:`~lib.utils.sysinfo._SysInfo` __init__ and attributes
|
|
|
|
Parameters
|
|
----------
|
|
sys_info_instance: :class:`~lib.utils.sysinfo._SysInfo`
|
|
The class instance to test
|
|
"""
|
|
assert isinstance(sys_info_instance, _SysInfo)
|
|
|
|
assert hasattr(sys_info_instance, "_state_file")
|
|
assert isinstance(sys_info_instance._state_file, str)
|
|
|
|
assert hasattr(sys_info_instance, "_configs")
|
|
assert isinstance(sys_info_instance._configs, str)
|
|
|
|
assert hasattr(sys_info_instance, "_system")
|
|
assert isinstance(sys_info_instance._system, dict)
|
|
assert sys_info_instance._system == dict(platform=platform.platform(),
|
|
system=platform.system().lower(),
|
|
machine=platform.machine(),
|
|
release=platform.release(),
|
|
processor=platform.processor(),
|
|
cpu_count=os.cpu_count())
|
|
|
|
assert hasattr(sys_info_instance, "_python")
|
|
assert isinstance(sys_info_instance._python, dict)
|
|
assert sys_info_instance._python == dict(implementation=platform.python_implementation(),
|
|
version=platform.python_version())
|
|
|
|
assert hasattr(sys_info_instance, "_gpu")
|
|
assert isinstance(sys_info_instance._gpu, GPUInfo)
|
|
|
|
assert hasattr(sys_info_instance, "_cuda_check")
|
|
assert isinstance(sys_info_instance._cuda_check, CudaCheck)
|
|
|
|
|
|
def test_properties(sys_info_instance: _SysInfo) -> None:
|
|
""" Test :class:`~lib.utils.sysinfo._SysInfo` properties
|
|
|
|
Parameters
|
|
----------
|
|
sys_info_instance: :class:`~lib.utils.sysinfo._SysInfo`
|
|
The class instance to test
|
|
"""
|
|
assert hasattr(sys_info_instance, "_encoding")
|
|
assert isinstance(sys_info_instance._encoding, str)
|
|
assert sys_info_instance._encoding == locale.getpreferredencoding()
|
|
|
|
assert hasattr(sys_info_instance, "_is_conda")
|
|
assert isinstance(sys_info_instance._is_conda, bool)
|
|
assert sys_info_instance._is_conda == ("conda" in sys.version.lower() or
|
|
os.path.exists(os.path.join(sys.prefix, "conda-meta")))
|
|
|
|
assert hasattr(sys_info_instance, "_is_linux")
|
|
assert isinstance(sys_info_instance._is_linux, bool)
|
|
if platform.system().lower() == "linux":
|
|
assert sys_info_instance._is_linux and sys_info_instance._system["system"] == "linux"
|
|
assert not sys_info_instance._is_macos
|
|
assert not sys_info_instance._is_windows
|
|
|
|
assert hasattr(sys_info_instance, "_is_macos")
|
|
assert isinstance(sys_info_instance._is_macos, bool)
|
|
if platform.system().lower() == "darwin":
|
|
assert sys_info_instance._is_macos and sys_info_instance._system["system"] == "darwin"
|
|
assert not sys_info_instance._is_linux
|
|
assert not sys_info_instance._is_windows
|
|
|
|
assert hasattr(sys_info_instance, "_is_windows")
|
|
assert isinstance(sys_info_instance._is_windows, bool)
|
|
if platform.system().lower() == "windows":
|
|
assert sys_info_instance._is_windows and sys_info_instance._system["system"] == "windows"
|
|
assert not sys_info_instance._is_linux
|
|
assert not sys_info_instance._is_macos
|
|
|
|
assert hasattr(sys_info_instance, "_is_virtual_env")
|
|
assert isinstance(sys_info_instance._is_virtual_env, bool)
|
|
|
|
assert hasattr(sys_info_instance, "_ram_free")
|
|
assert isinstance(sys_info_instance._ram_free, int)
|
|
|
|
assert hasattr(sys_info_instance, "_ram_total")
|
|
assert isinstance(sys_info_instance._ram_total, int)
|
|
|
|
assert hasattr(sys_info_instance, "_ram_available")
|
|
assert isinstance(sys_info_instance._ram_available, int)
|
|
|
|
assert hasattr(sys_info_instance, "_ram_used")
|
|
assert isinstance(sys_info_instance._ram_used, int)
|
|
|
|
assert hasattr(sys_info_instance, "_fs_command")
|
|
assert isinstance(sys_info_instance._fs_command, str)
|
|
|
|
assert hasattr(sys_info_instance, "_installed_pip")
|
|
assert isinstance(sys_info_instance._installed_pip, str)
|
|
|
|
assert hasattr(sys_info_instance, "_installed_conda")
|
|
assert isinstance(sys_info_instance._installed_conda, str)
|
|
|
|
assert hasattr(sys_info_instance, "_conda_version")
|
|
assert isinstance(sys_info_instance._conda_version, str)
|
|
|
|
|
|
def test_full_info(sys_info_instance: _SysInfo) -> None:
|
|
""" Test the sys_info method of :class:`~lib.utils.sysinfo._SysInfo` returns as expected
|
|
|
|
Parameters
|
|
----------
|
|
sys_info_instance: :class:`~lib.utils.sysinfo._SysInfo`
|
|
The class instance to test
|
|
"""
|
|
assert hasattr(sys_info_instance, "full_info")
|
|
sys_info = sys_info_instance.full_info()
|
|
assert isinstance(sys_info, str)
|
|
assert "backend:" in sys_info
|
|
assert "os_platform:" in sys_info
|
|
assert "os_machine:" in sys_info
|
|
assert "os_release:" in sys_info
|
|
assert "py_conda_version:" in sys_info
|
|
assert "py_implementation:" in sys_info
|
|
assert "py_version:" in sys_info
|
|
assert "py_command:" in sys_info
|
|
assert "py_virtual_env:" in sys_info
|
|
assert "sys_cores:" in sys_info
|
|
assert "sys_processor:" in sys_info
|
|
assert "sys_ram:" in sys_info
|
|
assert "encoding:" in sys_info
|
|
assert "git_branch:" in sys_info
|
|
assert "git_commits:" in sys_info
|
|
assert "gpu_cuda:" in sys_info
|
|
assert "gpu_cudnn:" in sys_info
|
|
assert "gpu_driver:" in sys_info
|
|
assert "gpu_devices:" in sys_info
|
|
assert "gpu_vram:" in sys_info
|
|
assert "gpu_devices_active:" in sys_info
|
|
|
|
|
|
def test__format_ram(sys_info_instance: _SysInfo, monkeypatch: pytest.MonkeyPatch) -> None:
|
|
""" Test the _format_ram method of :class:`~lib.utils.sysinfo._SysInfo` returns as expected
|
|
|
|
Parameters
|
|
----------
|
|
sys_info_instance: :class:`~lib.utils.sysinfo._SysInfo`
|
|
The class instance to test
|
|
monkeypatch: :class:`pytest.MonkeyPatch`
|
|
Monkey patching psutil.virtual_memory to be consistent
|
|
"""
|
|
assert hasattr(sys_info_instance, "_format_ram")
|
|
svmem = namedtuple("svmem", ["available", "free", "total", "used"])
|
|
data = svmem(12345678, 1234567, 123456789, 123456)
|
|
monkeypatch.setattr("psutil.virtual_memory", lambda *args, **kwargs: data)
|
|
ram_info = sys_info_instance._format_ram()
|
|
|
|
assert isinstance(ram_info, str)
|
|
assert ram_info == "Total: 117MB, Available: 11MB, Used: 0MB, Free: 1MB"
|
|
|
|
|
|
# get_sys_info
|
|
def test_get_sys_info(mocker: pytest_mock.MockerFixture) -> None:
|
|
""" Thest that the :func:`~lib.utils.sysinfo.get_sysinfo` function executes correctly
|
|
|
|
Parameters
|
|
----------
|
|
mocker: :class:`pytest_mock.MockerFixture`
|
|
Mocker for checking full_info called from _SysInfo
|
|
"""
|
|
sys_info = get_sysinfo()
|
|
assert isinstance(sys_info, str)
|
|
full_info = mocker.patch("lib.sysinfo._SysInfo.full_info")
|
|
get_sysinfo()
|
|
assert full_info.called
|
|
|
|
|
|
# _Configs
|
|
@pytest.fixture(name="configs_instance")
|
|
def configs_fixture():
|
|
""" Pytest fixture for :class:`~lib.utils.sysinfo._Configs`
|
|
|
|
Returns
|
|
-------
|
|
:class:`~lib.utils.sysinfo._Configs`
|
|
The class instance for testing
|
|
"""
|
|
return _Configs()
|
|
|
|
|
|
def test__configs__init__(configs_instance: _Configs) -> None:
|
|
""" Test __init__ and attributes for :class:`~lib.utils.sysinfo._Configs`
|
|
|
|
Parameters
|
|
----------
|
|
configs_instance: :class:`~lib.utils.sysinfo._Configs`
|
|
The class instance to test
|
|
"""
|
|
assert hasattr(configs_instance, "config_dir")
|
|
assert isinstance(configs_instance.config_dir, str)
|
|
assert hasattr(configs_instance, "configs")
|
|
assert isinstance(configs_instance.configs, str)
|
|
|
|
|
|
def test__configs__get_configs(configs_instance: _Configs) -> None:
|
|
""" Test __init__ and attributes for :class:`~lib.utils.sysinfo._Configs`
|
|
|
|
Parameters
|
|
----------
|
|
configs_instance: :class:`~lib.utils.sysinfo._Configs`
|
|
The class instance to test
|
|
"""
|
|
assert hasattr(configs_instance, "_get_configs")
|
|
assert isinstance(configs_instance._get_configs(), str)
|
|
|
|
|
|
def test__configs__parse_configs(configs_instance: _Configs,
|
|
mocker: pytest_mock.MockerFixture) -> None:
|
|
""" Test _parse_configs function for :class:`~lib.utils.sysinfo._Configs`
|
|
|
|
Parameters
|
|
----------
|
|
configs_instance: :class:`~lib.utils.sysinfo._Configs`
|
|
The class instance to test
|
|
mocker: :class:`pytest_mock.MockerFixture`
|
|
Mocker for dummying in function calls
|
|
"""
|
|
assert hasattr(configs_instance, "_parse_configs")
|
|
assert isinstance(configs_instance._parse_configs([]), str)
|
|
configs_instance._parse_ini = cast(MagicMock, mocker.MagicMock()) # type:ignore
|
|
configs_instance._parse_json = cast(MagicMock, mocker.MagicMock()) # type:ignore
|
|
configs_instance._parse_configs(config_files=["test.ini", ".faceswap"])
|
|
assert configs_instance._parse_ini.called
|
|
assert configs_instance._parse_json.called
|
|
|
|
|
|
def test__configs__parse_ini(configs_instance: _Configs,
|
|
monkeypatch: pytest.MonkeyPatch) -> None:
|
|
""" Test _parse_ini function for :class:`~lib.utils.sysinfo._Configs`
|
|
|
|
Parameters
|
|
----------
|
|
configs_instance: :class:`~lib.utils.sysinfo._Configs`
|
|
The class instance to test
|
|
monkeypatch: :class:`pytest.MonkeyPatch`
|
|
Monkey patching :func:`builtins.open` to dummy in ini file
|
|
"""
|
|
assert hasattr(configs_instance, "_parse_ini")
|
|
|
|
file = ("[test.ini_header]\n"
|
|
"# Test Header\n\n"
|
|
"param = value")
|
|
monkeypatch.setattr("builtins.open", lambda *args, **kwargs: StringIO(file))
|
|
|
|
converted = configs_instance._parse_ini("test.ini")
|
|
assert isinstance(converted, str)
|
|
assert converted == ("\n[test.ini_header]\n"
|
|
"param: value\n")
|
|
|
|
|
|
def test__configs__parse_json(configs_instance: _Configs,
|
|
monkeypatch: pytest.MonkeyPatch) -> None:
|
|
""" Test _parse_json function for :class:`~lib.utils.sysinfo._Configs`
|
|
|
|
Parameters
|
|
----------
|
|
configs_instance: :class:`~lib.utils.sysinfo._Configs`
|
|
The class instance to test
|
|
monkeypatch: :class:`pytest.MonkeyPatch`
|
|
Monkey patching :func:`builtins.open` to dummy in json file
|
|
|
|
"""
|
|
assert hasattr(configs_instance, "_parse_json")
|
|
file = ('{"test": "param"}')
|
|
monkeypatch.setattr("builtins.open", lambda *args, **kwargs: StringIO(file))
|
|
|
|
converted = configs_instance._parse_json(".file")
|
|
assert isinstance(converted, str)
|
|
assert converted == ("test: param\n")
|
|
|
|
|
|
def test__configs__format_text(configs_instance: _Configs) -> None:
|
|
""" Test _format_text function for :class:`~lib.utils.sysinfo._Configs`
|
|
|
|
Parameters
|
|
----------
|
|
configs_instance: :class:`~lib.utils.sysinfo._Configs`
|
|
The class instance to test
|
|
"""
|
|
assert hasattr(configs_instance, "_format_text")
|
|
key, val = " test_key ", "test_val "
|
|
formatted = configs_instance._format_text(key, val)
|
|
assert isinstance(formatted, str)
|
|
assert formatted == "test_key: test_val\n"
|
|
|
|
|
|
# _State
|
|
@pytest.fixture(name="state_instance")
|
|
def state_fixture():
|
|
""" Pytest fixture for :class:`~lib.utils.sysinfo._State`
|
|
|
|
Returns
|
|
-------
|
|
:class:`~lib.utils.sysinfo._State`
|
|
The class instance for testing
|
|
"""
|
|
return _State()
|
|
|
|
|
|
def test__state__init__(state_instance: _State) -> None:
|
|
""" Test __init__ and attributes for :class:`~lib.utils.sysinfo._State`
|
|
|
|
Parameters
|
|
----------
|
|
state_instance: :class:`~lib.utils.sysinfo._State`
|
|
The class instance to test
|
|
"""
|
|
assert hasattr(state_instance, '_model_dir')
|
|
assert state_instance._model_dir is None
|
|
assert hasattr(state_instance, '_trainer')
|
|
assert state_instance._trainer is None
|
|
assert hasattr(state_instance, 'state_file')
|
|
assert isinstance(state_instance.state_file, str)
|
|
|
|
|
|
def test__state__is_training(state_instance: _State,
|
|
monkeypatch: pytest.MonkeyPatch) -> None:
|
|
""" Test _is_training function for :class:`~lib.utils.sysinfo._State`
|
|
|
|
Parameters
|
|
----------
|
|
state_instance: :class:`~lib.utils.sysinfo._State`
|
|
The class instance to test
|
|
monkeypatch: :class:`pytest.MonkeyPatch`
|
|
Monkey patching :func:`sys.argv` to dummy in commandline args
|
|
|
|
"""
|
|
assert hasattr(state_instance, '_is_training')
|
|
assert isinstance(state_instance._is_training, bool)
|
|
assert not state_instance._is_training
|
|
monkeypatch.setattr("sys.argv", ["faceswap.py", "train"])
|
|
assert state_instance._is_training
|
|
monkeypatch.setattr("sys.argv", ["faceswap.py", "extract"])
|
|
assert not state_instance._is_training
|
|
|
|
|
|
def test__state__get_arg(state_instance: _State,
|
|
monkeypatch: pytest.MonkeyPatch) -> None:
|
|
""" Test _get_arg function for :class:`~lib.utils.sysinfo._State`
|
|
|
|
Parameters
|
|
----------
|
|
state_instance: :class:`~lib.utils.sysinfo._State`
|
|
The class instance to test
|
|
monkeypatch: :class:`pytest.MonkeyPatch`
|
|
Monkey patching :func:`sys.argv` to dummy in commandline args
|
|
:func:`builtins.input`
|
|
"""
|
|
assert hasattr(state_instance, '_get_arg')
|
|
assert state_instance._get_arg("-t", "--test_arg") is None
|
|
monkeypatch.setattr("sys.argv", ["test", "command", "-t", "test_option"])
|
|
assert state_instance._get_arg("-t", "--test_arg") == "test_option"
|
|
|
|
|
|
def test__state__get_state_file(state_instance: _State,
|
|
mocker: pytest_mock.MockerFixture,
|
|
monkeypatch: pytest.MonkeyPatch) -> None:
|
|
""" Test _get_state_file function for :class:`~lib.utils.sysinfo._State`
|
|
|
|
Parameters
|
|
----------
|
|
state_instance: :class:`~lib.utils.sysinfo._State`
|
|
The class instance to test
|
|
mocker: :class:`pytest_mock.MockerFixture`
|
|
Mocker for dummying in function calls
|
|
monkeypatch: :class:`pytest.MonkeyPatch`
|
|
Monkey patching :func:`sys.argv` to dummy in commandline args
|
|
:func:`builtins.input`
|
|
` """
|
|
assert hasattr(state_instance, '_get_state_file')
|
|
assert isinstance(state_instance._get_state_file(), str)
|
|
|
|
mock_is_training = mocker.patch("lib.sysinfo._State._is_training")
|
|
|
|
# Not training or missing training arguments
|
|
mock_is_training.return_value = False
|
|
assert state_instance._get_state_file() == ""
|
|
mock_is_training.return_value = False
|
|
|
|
monkeypatch.setattr(state_instance, "_model_dir", None)
|
|
assert state_instance._get_state_file() == ""
|
|
monkeypatch.setattr(state_instance, "_model_dir", "test_dir")
|
|
|
|
monkeypatch.setattr(state_instance, "_trainer", None)
|
|
assert state_instance._get_state_file() == ""
|
|
monkeypatch.setattr(state_instance, "_trainer", "test_trainer")
|
|
|
|
# Training but file not found
|
|
assert state_instance._get_state_file() == ""
|
|
|
|
# State file is just a json dump
|
|
file = ('{\n'
|
|
' "test": "json",\n'
|
|
'}')
|
|
monkeypatch.setattr("os.path.isfile", lambda *args, **kwargs: True)
|
|
monkeypatch.setattr("builtins.open", lambda *args, **kwargs: StringIO(file))
|
|
assert state_instance._get_state_file().endswith(file)
|