salt/tests/pytests/unit/utils/test_thin.py
bdrx312 66caa58346 Fix issues with requisites and aggregate
add install of networkx
fix aggregate to properly work with requisites
fix requisite checking to not be exponential
fix pkg aggregate to work when multiple states specify the same package
add some type hints to state.py to make the code easier to follow
fix case of pkg aggregate duplicate package.
2024-10-10 01:53:52 -07:00

127 lines
3.9 KiB
Python

import importlib
import os
import sys
import pytest
import saltfactories.utils.saltext
import salt.exceptions
import salt.utils.stringutils
import salt.utils.thin
from tests.support.mock import MagicMock, patch
from tests.support.pytest.helpers import FakeSaltExtension
def _mock_popen(return_value=None, side_effect=None, returncode=0):
proc = MagicMock()
proc.communicate = MagicMock(return_value=return_value, side_effect=side_effect)
proc.returncode = returncode
popen = MagicMock(return_value=proc)
return popen
@pytest.mark.parametrize("version", [[2, 7], [3, 0], [3, 7]])
def test_get_tops_python(version):
"""
Tests 'distro' is only included when targeting
python 3 in get_tops_python
"""
python3 = False
if tuple(version) >= (3, 0):
python3 = True
mods = ["jinja2"]
if python3:
mods.append("distro")
popen_ret = tuple(salt.utils.stringutils.to_bytes(x) for x in ("", ""))
mock_popen = _mock_popen(return_value=popen_ret)
patch_proc = patch("salt.utils.thin.subprocess.Popen", mock_popen)
patch_which = patch("salt.utils.path.which", return_value=True)
with patch_proc, patch_which:
salt.utils.thin.get_tops_python("python2", ext_py_ver=version)
cmds = [x[0][0] for x in mock_popen.call_args_list]
assert [x for x in cmds if "jinja2" in x[2]]
if python3:
assert [x for x in cmds if "distro" in x[2]]
else:
assert not [x for x in cmds if "distro" in x[2]]
@pytest.mark.parametrize("version", [[2, 7], [3, 0], [3, 7]])
def test_get_ext_tops(version):
"""
Tests 'distro' is only included when targeting
python 3 in get_ext_tops
"""
python3 = False
if tuple(version) >= (3, 0):
python3 = True
cfg = {
"namespace": {
"path": "/foo",
"py-version": version,
"dependencies": {
"jinja2": "/jinja/foo.py",
"yaml": "/yaml/",
"tornado": "/tornado/tornado.py",
"msgpack": "msgpack.py",
"networkx": "/networkx/networkx.py",
},
}
}
with patch("salt.utils.thin.os.path.isfile", MagicMock(return_value=True)):
if python3:
with pytest.raises(salt.exceptions.SaltSystemExit) as err:
salt.utils.thin.get_ext_tops(cfg)
else:
ret = salt.utils.thin.get_ext_tops(cfg)
if python3:
assert "distro" in err.value.code
else:
assert not [x for x in ret["namespace"]["dependencies"] if "distro" in x]
assert [x for x in ret["namespace"]["dependencies"] if "msgpack" in x]
def test_get_package_root_mod():
res = salt.utils.thin._get_package_root_mod(saltfactories.utils.saltext)
assert res[0] is saltfactories
assert res[1] == ()
@pytest.fixture
def namespaced_saltext(tmp_path_factory):
with FakeSaltExtension(
tmp_path_factory=tmp_path_factory,
name="saltext.wut",
) as extension:
try:
sys.path.insert(0, str(extension.srcdir / "src"))
yield extension
finally:
sys.path.pop(0)
def test_get_namespaced_package_root_mod(namespaced_saltext):
saltext = importlib.import_module(namespaced_saltext.name)
res = salt.utils.thin._get_package_root_mod(saltext)
assert res[0].__name__ == namespaced_saltext.name
assert res[1] == ("saltext",)
def test_discover_saltexts():
"""
pytest-salt-factories provides a saltext, which can be discovered here.
"""
mods, dists = salt.utils.thin._discover_saltexts()
assert mods
assert any(mod.endswith(f"{os.sep}saltfactories") and not ns for mod, ns in mods)
assert dists
dist = "pytest-salt-factories"
assert dist in dists
assert "entrypoints" in dists[dist]
assert "name" in dists[dist]
assert dists[dist]["name"].startswith("pytest_salt_factories")
assert dists[dist]["name"].endswith(".dist-info")