mirror of
https://github.com/saltstack/salt.git
synced 2025-04-17 10:10:20 +00:00
Merge remote-tracking branch 'saltstack/3006.x' into merge-forward
This commit is contained in:
commit
412178e48a
10 changed files with 1044 additions and 959 deletions
|
@ -163,13 +163,16 @@ def renderer(path=None, string=None, default_renderer="jinja|yaml", **kwargs):
|
|||
if not path and not string:
|
||||
raise salt.exceptions.SaltInvocationError("Must pass either path or string")
|
||||
|
||||
if path and string:
|
||||
raise salt.exceptions.SaltInvocationError("Must not pass both path and string")
|
||||
|
||||
renderers = salt.loader.render(__opts__, __salt__)
|
||||
|
||||
if path:
|
||||
path_or_string = __salt__["cp.get_url"](
|
||||
path, saltenv=kwargs.get("saltenv", "base")
|
||||
)
|
||||
elif string:
|
||||
if string:
|
||||
path_or_string = ":string:"
|
||||
kwargs["input_data"] = string
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ def test_publish_retry(salt_master, salt_minion_retry, salt_cli, salt_run_cli):
|
|||
@pytest.mark.slow_test
|
||||
def test_pillar_timeout(salt_master_factory):
|
||||
cmd = """
|
||||
python -c "import time; time.sleep(2.5); print('{\\"foo\\": \\"bar\\"}');\"
|
||||
python -c "import time; time.sleep(3.0); print('{\\"foo\\": \\"bar\\"}');\"
|
||||
""".strip()
|
||||
master_overrides = {
|
||||
"ext_pillar": [
|
||||
|
|
|
@ -256,6 +256,9 @@ def setup_redhat_family(
|
|||
):
|
||||
arch = os.environ.get("SALT_REPO_ARCH") or "x86_64"
|
||||
|
||||
if os_name == "photon":
|
||||
os_version = f"{os_version}.0"
|
||||
|
||||
if repo_subpath == "minor":
|
||||
repo_url_base = (
|
||||
f"{root_url}/{os_name}/{os_version}/{arch}/{repo_subpath}/{salt_release}"
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import asyncio
|
||||
import os
|
||||
|
||||
import pytest
|
||||
|
||||
|
@ -24,6 +25,7 @@ def minion_opts(tmp_path):
|
|||
dirpath.mkdir(parents=True)
|
||||
opts[name] = str(dirpath)
|
||||
opts["log_file"] = "logs/minion.log"
|
||||
opts["conf_file"] = os.path.join(opts["conf_dir"], "minion")
|
||||
return opts
|
||||
|
||||
|
||||
|
@ -41,6 +43,7 @@ def master_opts(tmp_path):
|
|||
dirpath.mkdir(parents=True)
|
||||
opts[name] = str(dirpath)
|
||||
opts["log_file"] = "logs/master.log"
|
||||
opts["conf_file"] = os.path.join(opts["conf_dir"], "master")
|
||||
return opts
|
||||
|
||||
|
||||
|
@ -59,6 +62,7 @@ def syndic_opts(tmp_path):
|
|||
dirpath.mkdir(parents=True)
|
||||
opts[name] = str(dirpath)
|
||||
opts["log_file"] = "logs/syndic.log"
|
||||
opts["conf_file"] = os.path.join(opts["conf_dir"], "syndic")
|
||||
return opts
|
||||
|
||||
|
||||
|
|
|
@ -1,18 +1,20 @@
|
|||
import logging
|
||||
from io import StringIO
|
||||
|
||||
import pytest
|
||||
|
||||
import salt.exceptions
|
||||
import salt.modules.slsutil as slsutil
|
||||
from tests.support.mock import MagicMock
|
||||
from tests.support.mock import MagicMock, patch
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def configure_loader_modules(master_dirs, master_files):
|
||||
def configure_loader_modules(master_dirs, master_files, minion_opts):
|
||||
return {
|
||||
slsutil: {
|
||||
"__opts__": minion_opts,
|
||||
"__salt__": {
|
||||
"cp.list_master": MagicMock(return_value=master_files),
|
||||
"cp.list_master_dirs": MagicMock(return_value=master_dirs),
|
||||
|
@ -47,6 +49,21 @@ def test_banner():
|
|||
check_banner(commentchar="//", borderchar="-")
|
||||
check_banner(title="title here", text="text here")
|
||||
check_banner(commentchar=" *")
|
||||
check_banner(commentchar=" *", newline=False)
|
||||
|
||||
# Test when width result in a raised exception
|
||||
with pytest.raises(salt.exceptions.ArgumentValueError):
|
||||
slsutil.banner(width=4)
|
||||
|
||||
ret = slsutil.banner(
|
||||
title="title here", text="text here", blockstart="/*", blockend="*/"
|
||||
)
|
||||
lines = ret.splitlines()
|
||||
# test blockstart
|
||||
assert lines[0] == "/*"
|
||||
|
||||
# test blockend
|
||||
assert lines[-1] == "*/"
|
||||
|
||||
|
||||
def check_banner(
|
||||
|
@ -125,3 +142,159 @@ def test_findup():
|
|||
|
||||
with pytest.raises(salt.exceptions.CommandExecutionError):
|
||||
slsutil.findup("red", "default.conf")
|
||||
|
||||
with pytest.raises(salt.exceptions.SaltInvocationError):
|
||||
with patch.object(slsutil, "path_exists", return_value=False):
|
||||
slsutil.findup("red", "default.conf")
|
||||
|
||||
with pytest.raises(salt.exceptions.SaltInvocationError):
|
||||
slsutil.findup("red", {"file": "default.conf"})
|
||||
|
||||
|
||||
def test_update():
|
||||
"""
|
||||
Test update function
|
||||
"""
|
||||
|
||||
ret = slsutil.update({"foo": "Foo"}, {"bar": "Bar"})
|
||||
assert ret == {"foo": "Foo", "bar": "Bar"}
|
||||
|
||||
ret = slsutil.update({"foo": "Foo"}, {"foo": "Bar"}, merge_lists=False)
|
||||
assert ret == {"foo": "Bar"}
|
||||
|
||||
|
||||
def test_merge():
|
||||
"""
|
||||
Test merge function
|
||||
"""
|
||||
|
||||
ret = slsutil.merge({"foo": "Foo"}, {"bar": "Bar"}, strategy="smart")
|
||||
assert ret == {"foo": "Foo", "bar": "Bar"}
|
||||
|
||||
ret = slsutil.merge({"foo": "Foo"}, {"foo": "Bar"}, strategy="aggregate")
|
||||
assert ret == {"foo": "Bar"}
|
||||
|
||||
ret = slsutil.merge({"foo": "Foo"}, {"foo": "Bar"}, strategy="list")
|
||||
assert ret == {"foo": ["Foo", "Bar"]}
|
||||
|
||||
ret = slsutil.merge({"foo": "Foo"}, {"foo": "Bar"}, strategy="overwrite")
|
||||
assert ret == {"foo": "Bar"}
|
||||
|
||||
ret = slsutil.merge(
|
||||
{"foo": {"Foo": "Bar"}}, {"foo": {"Foo": "Baz"}}, strategy="recurse"
|
||||
)
|
||||
assert ret == {"foo": {"Foo": "Baz"}}
|
||||
|
||||
|
||||
def test_merge_all():
|
||||
"""
|
||||
Test merge_all function
|
||||
"""
|
||||
|
||||
ret = slsutil.merge_all([{"foo": "Foo"}, {"bar": "Bar"}], strategy="smart")
|
||||
assert ret == {"foo": "Foo", "bar": "Bar"}
|
||||
|
||||
ret = slsutil.merge_all([{"foo": "Foo"}, {"foo": "Bar"}], strategy="aggregate")
|
||||
assert ret == {"foo": "Bar"}
|
||||
|
||||
ret = slsutil.merge_all([{"foo": "Foo"}, {"foo": "Bar"}], strategy="overwrite")
|
||||
assert ret == {"foo": "Bar"}
|
||||
|
||||
ret = slsutil.merge_all(
|
||||
[{"foo": {"Foo": "Bar"}}, {"foo": {"Foo": "Baz"}}], strategy="recurse"
|
||||
)
|
||||
assert ret == {"foo": {"Foo": "Baz"}}
|
||||
|
||||
|
||||
def test_renderer():
|
||||
"""
|
||||
Test renderer function
|
||||
"""
|
||||
with patch.dict(
|
||||
slsutil.__utils__, {"stringio.is_readable": MagicMock(return_value=False)}
|
||||
):
|
||||
ret = slsutil.renderer(string="Hello, {{ name }}.", name="world")
|
||||
assert ret == "Hello, world."
|
||||
|
||||
with pytest.raises(salt.exceptions.SaltInvocationError) as exc:
|
||||
slsutil.renderer()
|
||||
assert str(exc.value) == "Must pass path or string."
|
||||
|
||||
with pytest.raises(salt.exceptions.SaltInvocationError) as exc:
|
||||
slsutil.renderer(path="/path/to/file", string="Hello world")
|
||||
assert str(exc.value) == "Must not pass both path and string."
|
||||
|
||||
with patch.dict(
|
||||
slsutil.__salt__, {"cp.get_url": MagicMock(return_value="/path/to/file")}
|
||||
):
|
||||
with patch.dict(
|
||||
slsutil.__utils__, {"stringio.is_readable": MagicMock(return_value=True)}
|
||||
):
|
||||
rendered_file = "Hello, world."
|
||||
with patch(
|
||||
"salt.template.compile_template",
|
||||
MagicMock(return_value=StringIO(rendered_file)),
|
||||
):
|
||||
ret = slsutil.renderer(path="/path/to/file")
|
||||
assert ret == "Hello, world."
|
||||
|
||||
|
||||
def test_serialize():
|
||||
"""
|
||||
Test serialize function
|
||||
"""
|
||||
ret = slsutil.serialize("json", obj={"foo": "Foo!"})
|
||||
assert ret == '{"foo": "Foo!"}'
|
||||
|
||||
|
||||
def test_deserialize():
|
||||
"""
|
||||
Test serialize function
|
||||
"""
|
||||
ret = slsutil.deserialize("json", '{"foo": "Foo!"}')
|
||||
assert ret == {"foo": "Foo!"}
|
||||
|
||||
|
||||
def dummy_function(args=None, kwargs=None):
|
||||
return True
|
||||
|
||||
|
||||
def test__set_context():
|
||||
"""
|
||||
Test _set_context
|
||||
"""
|
||||
with patch.dict(slsutil.__context__, {}):
|
||||
|
||||
slsutil._set_context(
|
||||
["level_one", "level_two", "level_three"], dummy_function, force=True
|
||||
)
|
||||
assert slsutil.__context__ == {
|
||||
"level_one": {"level_two": {"level_three": True}}
|
||||
}
|
||||
|
||||
with patch.dict(slsutil.__context__, {}):
|
||||
|
||||
slsutil._set_context(
|
||||
["level_one", "level_two", "level_three"],
|
||||
dummy_function,
|
||||
fun_kwargs={"key_one": "arg_one"},
|
||||
force=True,
|
||||
)
|
||||
assert slsutil.__context__ == {
|
||||
"level_one": {"level_two": {"level_three": True}}
|
||||
}
|
||||
|
||||
|
||||
def test__get_serializer_fn():
|
||||
"""
|
||||
Test _set_context
|
||||
"""
|
||||
# Invalid serializer
|
||||
with pytest.raises(salt.exceptions.CommandExecutionError) as exc:
|
||||
slsutil._get_serialize_fn("bad_yaml", "badfunc")
|
||||
assert str(exc.value) == "Serializer 'bad_yaml' not found."
|
||||
|
||||
# Invalid serializer function
|
||||
with pytest.raises(salt.exceptions.CommandExecutionError) as exc:
|
||||
slsutil._get_serialize_fn("yaml", "foobar")
|
||||
assert str(exc.value) == "Serializer 'yaml' does not implement foobar."
|
||||
|
|
58
tests/pytests/unit/modules/test_tomcat.py
Normal file
58
tests/pytests/unit/modules/test_tomcat.py
Normal file
|
@ -0,0 +1,58 @@
|
|||
"""
|
||||
Tests cases for salt.modules.tomcat
|
||||
"""
|
||||
|
||||
|
||||
import io
|
||||
import urllib.request
|
||||
|
||||
import pytest
|
||||
|
||||
import salt.modules.tomcat as tomcat
|
||||
from tests.support.mock import MagicMock, patch
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def configure_loader_modules():
|
||||
return {tomcat: {}}
|
||||
|
||||
|
||||
def test_tomcat_wget_no_bytestring():
|
||||
responses = {
|
||||
"string": io.StringIO("Best response ever\r\nAnd you know it!"),
|
||||
"bytes": io.BytesIO(b"Best response ever\r\nAnd you know it!"),
|
||||
}
|
||||
|
||||
string_mock = MagicMock(return_value=responses["string"])
|
||||
bytes_mock = MagicMock(return_value=responses["bytes"])
|
||||
with patch(
|
||||
"salt.modules.tomcat._auth",
|
||||
MagicMock(
|
||||
return_value=urllib.request.build_opener(
|
||||
urllib.request.HTTPBasicAuthHandler(),
|
||||
urllib.request.HTTPDigestAuthHandler(),
|
||||
)
|
||||
),
|
||||
):
|
||||
with patch("urllib.request.urlopen", string_mock):
|
||||
response = tomcat._wget("tomcat.wait", url="http://localhost:8080/nofail")
|
||||
for line in response["msg"]:
|
||||
assert isinstance(line, str)
|
||||
|
||||
with patch("urllib.request.urlopen", bytes_mock):
|
||||
try:
|
||||
response = tomcat._wget(
|
||||
"tomcat.wait", url="http://localhost:8080/nofail"
|
||||
)
|
||||
except TypeError as type_error:
|
||||
if (
|
||||
type_error.args[0]
|
||||
== "startswith first arg must be bytes or a tuple of bytes,"
|
||||
" not str"
|
||||
):
|
||||
print("Got back a byte string, should've been a string")
|
||||
else:
|
||||
raise type_error
|
||||
|
||||
for line in response["msg"]:
|
||||
assert isinstance(line, str)
|
796
tests/pytests/unit/states/test_grains.py
Normal file
796
tests/pytests/unit/states/test_grains.py
Normal file
|
@ -0,0 +1,796 @@
|
|||
"""
|
||||
unit tests for the grains state
|
||||
"""
|
||||
import contextlib
|
||||
import os
|
||||
|
||||
import pytest
|
||||
|
||||
import salt.modules.grains as grainsmod
|
||||
import salt.states.grains as grains
|
||||
import salt.utils.files
|
||||
import salt.utils.stringutils
|
||||
import salt.utils.yaml
|
||||
from tests.support.mock import MagicMock, patch
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def configure_loader_modules(minion_opts):
|
||||
minion_opts["local"] = True
|
||||
minion_opts["test"] = False
|
||||
loader_globals = {
|
||||
"__opts__": minion_opts,
|
||||
"__salt__": {
|
||||
"cmd.run_all": MagicMock(
|
||||
return_value={"pid": 5, "retcode": 0, "stderr": "", "stdout": ""}
|
||||
),
|
||||
"grains.get": grainsmod.get,
|
||||
"grains.set": grainsmod.set,
|
||||
"grains.setval": grainsmod.setval,
|
||||
"grains.delval": grainsmod.delval,
|
||||
"grains.append": grainsmod.append,
|
||||
"grains.remove": grainsmod.remove,
|
||||
"saltutil.sync_grains": MagicMock(),
|
||||
},
|
||||
}
|
||||
return {grains: loader_globals, grainsmod: loader_globals}
|
||||
|
||||
|
||||
def assert_grain_file_content(grains_string):
|
||||
grains_file = os.path.join(grains.__opts__["conf_dir"], "grains")
|
||||
with salt.utils.files.fopen(grains_file, "r") as grf:
|
||||
grains_data = salt.utils.stringutils.to_unicode(grf.read())
|
||||
assert grains_string == grains_data
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def set_grains(grains_data):
|
||||
with patch.dict(grains.__grains__, grains_data):
|
||||
with patch.dict(grainsmod.__grains__, grains_data):
|
||||
grains_file = os.path.join(grains.__opts__["conf_dir"], "grains")
|
||||
with salt.utils.files.fopen(grains_file, "w+") as grf:
|
||||
salt.utils.yaml.safe_dump(grains_data, grf, default_flow_style=False)
|
||||
yield
|
||||
|
||||
|
||||
# 'exists' function tests: 2
|
||||
|
||||
|
||||
def test_exists_missing():
|
||||
with set_grains({"a": "aval"}):
|
||||
ret = grains.exists(name="foo")
|
||||
assert ret["result"] is False
|
||||
assert ret["comment"] == "Grain does not exist"
|
||||
assert ret["changes"] == {}
|
||||
|
||||
|
||||
def test_exists_found():
|
||||
with set_grains({"a": "aval", "foo": "bar"}):
|
||||
# Grain already set
|
||||
ret = grains.exists(name="foo")
|
||||
assert ret["result"] is True
|
||||
assert ret["comment"] == "Grain exists"
|
||||
assert ret["changes"] == {}
|
||||
|
||||
# 'make_hashable' function tests: 1
|
||||
|
||||
|
||||
def test_make_hashable():
|
||||
with set_grains({"cmplx_lst_grain": [{"a": "aval"}, {"foo": "bar"}]}):
|
||||
hashable_list = {"cmplx_lst_grain": [{"a": "aval"}, {"foo": "bar"}]}
|
||||
assert grains.make_hashable(grains.__grains__).issubset(
|
||||
grains.make_hashable(hashable_list)
|
||||
)
|
||||
|
||||
# 'present' function tests: 12
|
||||
|
||||
|
||||
def test_present_add():
|
||||
# Set a non existing grain
|
||||
with set_grains({"a": "aval"}):
|
||||
ret = grains.present(name="foo", value="bar")
|
||||
assert ret["result"] is True
|
||||
assert ret["changes"] == {"foo": "bar"}
|
||||
assert grains.__grains__ == {"a": "aval", "foo": "bar"}
|
||||
assert_grain_file_content("a: aval\nfoo: bar\n")
|
||||
|
||||
# Set a non existing nested grain
|
||||
with set_grains({"a": "aval"}):
|
||||
ret = grains.present(name="foo:is:nested", value="bar")
|
||||
assert ret["result"] is True
|
||||
assert ret["changes"] == {"foo": {"is": {"nested": "bar"}}}
|
||||
assert grains.__grains__ == {"a": "aval", "foo": {"is": {"nested": "bar"}}}
|
||||
assert_grain_file_content("a: aval\nfoo:\n is:\n nested: bar\n")
|
||||
|
||||
# Set a non existing nested dict grain
|
||||
with set_grains({"a": "aval"}):
|
||||
ret = grains.present(name="foo:is:nested", value={"bar": "is a dict"})
|
||||
assert ret["result"] is True
|
||||
assert ret["changes"] == {"foo": {"is": {"nested": {"bar": "is a dict"}}}}
|
||||
assert grains.__grains__ == {
|
||||
"a": "aval",
|
||||
"foo": {"is": {"nested": {"bar": "is a dict"}}},
|
||||
}
|
||||
assert_grain_file_content(
|
||||
"a: aval\nfoo:\n is:\n nested:\n bar: is a dict\n"
|
||||
)
|
||||
|
||||
|
||||
def test_present_add_key_to_existing():
|
||||
with set_grains({"a": "aval", "foo": {"k1": "v1"}}):
|
||||
# Fails setting a grain to a dict
|
||||
ret = grains.present(name="foo:k2", value="v2")
|
||||
assert ret["result"] is True
|
||||
assert ret["comment"] == "Set grain foo:k2 to v2"
|
||||
assert ret["changes"] == {"foo": {"k2": "v2", "k1": "v1"}}
|
||||
assert grains.__grains__ == {"a": "aval", "foo": {"k1": "v1", "k2": "v2"}}
|
||||
assert_grain_file_content("a: aval\nfoo:\n k1: v1\n k2: v2\n")
|
||||
|
||||
|
||||
def test_present_already_set():
|
||||
with set_grains({"a": "aval", "foo": "bar"}):
|
||||
# Grain already set
|
||||
ret = grains.present(name="foo", value="bar")
|
||||
assert ret["result"] is True
|
||||
assert ret["comment"] == "Grain is already set"
|
||||
assert ret["changes"] == {}
|
||||
assert grains.__grains__ == {"a": "aval", "foo": "bar"}
|
||||
|
||||
with set_grains({"a": "aval", "foo": {"is": {"nested": "bar"}}}):
|
||||
# Nested grain already set
|
||||
ret = grains.present(name="foo:is:nested", value="bar")
|
||||
assert ret["result"] is True
|
||||
assert ret["comment"] == "Grain is already set"
|
||||
assert ret["changes"] == {}
|
||||
assert grains.__grains__ == {"a": "aval", "foo": {"is": {"nested": "bar"}}}
|
||||
|
||||
with set_grains({"a": "aval", "foo": {"is": {"nested": "bar"}}}):
|
||||
# Nested dict grain already set
|
||||
ret = grains.present(name="foo:is", value={"nested": "bar"})
|
||||
assert ret["result"] is True
|
||||
assert ret["comment"] == "Grain is already set"
|
||||
assert ret["changes"] == {}
|
||||
assert grains.__grains__ == {"a": "aval", "foo": {"is": {"nested": "bar"}}}
|
||||
|
||||
|
||||
def test_present_overwrite():
|
||||
with set_grains({"a": "aval", "foo": "bar"}):
|
||||
# Overwrite an existing grain
|
||||
ret = grains.present(name="foo", value="newbar")
|
||||
assert ret["result"] is True
|
||||
assert ret["changes"] == {"foo": "newbar"}
|
||||
assert grains.__grains__ == {"a": "aval", "foo": "newbar"}
|
||||
assert_grain_file_content("a: aval\nfoo: newbar\n")
|
||||
|
||||
with set_grains({"a": "aval", "foo": "bar"}):
|
||||
# Clear a grain (set to None)
|
||||
ret = grains.present(name="foo", value=None)
|
||||
assert ret["result"] is True
|
||||
assert ret["changes"] == {"foo": None}
|
||||
assert grains.__grains__ == {"a": "aval", "foo": None}
|
||||
assert_grain_file_content("a: aval\nfoo: null\n")
|
||||
|
||||
with set_grains({"a": "aval", "foo": {"is": {"nested": "bar"}}}):
|
||||
# Overwrite an existing nested grain
|
||||
ret = grains.present(name="foo:is:nested", value="newbar")
|
||||
assert ret["result"] is True
|
||||
assert ret["changes"] == {"foo": {"is": {"nested": "newbar"}}}
|
||||
assert grains.__grains__ == {"a": "aval", "foo": {"is": {"nested": "newbar"}}}
|
||||
assert_grain_file_content("a: aval\nfoo:\n is:\n nested: newbar\n")
|
||||
|
||||
with set_grains({"a": "aval", "foo": {"is": {"nested": "bar"}}}):
|
||||
# Clear a nested grain (set to None)
|
||||
ret = grains.present(name="foo:is:nested", value=None)
|
||||
assert ret["result"] is True
|
||||
assert ret["changes"] == {"foo": {"is": {"nested": None}}}
|
||||
assert grains.__grains__ == {"a": "aval", "foo": {"is": {"nested": None}}}
|
||||
assert_grain_file_content("a: aval\nfoo:\n is:\n nested: null\n")
|
||||
|
||||
|
||||
def test_present_fail_overwrite():
|
||||
with set_grains({"a": "aval", "foo": {"is": {"nested": "val"}}}):
|
||||
# Overwrite an existing grain
|
||||
ret = grains.present(name="foo:is", value="newbar")
|
||||
assert ret["result"] is False
|
||||
assert ret["changes"] == {}
|
||||
assert (
|
||||
ret["comment"]
|
||||
== "The key 'foo:is' exists but is a dict or a list. Use 'force=True' to overwrite."
|
||||
)
|
||||
assert grains.__grains__ == {"a": "aval", "foo": {"is": {"nested": "val"}}}
|
||||
|
||||
with set_grains({"a": "aval", "foo": {"is": {"nested": "val"}}}):
|
||||
# Clear a grain (set to None)
|
||||
ret = grains.present(name="foo:is", value=None)
|
||||
assert ret["result"] is False
|
||||
assert ret["changes"] == {}
|
||||
assert (
|
||||
ret["comment"]
|
||||
== "The key 'foo:is' exists but is a dict or a list. Use 'force=True' to overwrite."
|
||||
)
|
||||
assert grains.__grains__ == {"a": "aval", "foo": {"is": {"nested": "val"}}}
|
||||
|
||||
|
||||
def test_present_fails_to_set_dict_or_list():
|
||||
with set_grains({"a": "aval", "foo": "bar"}):
|
||||
# Fails to overwrite a grain to a list
|
||||
ret = grains.present(name="foo", value=["l1", "l2"])
|
||||
assert ret["result"] is False
|
||||
assert (
|
||||
ret["comment"]
|
||||
== "The key 'foo' exists and the given value is a dict or a list. Use 'force=True' to overwrite."
|
||||
)
|
||||
assert ret["changes"] == {}
|
||||
assert grains.__grains__ == {"a": "aval", "foo": "bar"}
|
||||
|
||||
with set_grains({"a": "aval", "foo": "bar"}):
|
||||
# Fails setting a grain to a dict
|
||||
ret = grains.present(name="foo", value={"k1": "v1"})
|
||||
assert ret["result"] is False
|
||||
assert (
|
||||
ret["comment"]
|
||||
== "The key 'foo' exists and the given value is a dict or a list. Use 'force=True' to overwrite."
|
||||
)
|
||||
assert ret["changes"] == {}
|
||||
assert grains.__grains__ == {"a": "aval", "foo": "bar"}
|
||||
|
||||
with set_grains({"a": "aval", "foo": {"is": {"nested": "bar"}}}):
|
||||
# Fails to overwrite a nested grain to a list
|
||||
ret = grains.present(name="foo,is,nested", value=["l1", "l2"], delimiter=",")
|
||||
assert ret["result"] is False
|
||||
assert ret["changes"] == {}
|
||||
assert (
|
||||
ret["comment"]
|
||||
== "The key 'foo:is:nested' exists and the given value is a dict or a list. Use 'force=True' to overwrite."
|
||||
)
|
||||
assert grains.__grains__ == {"a": "aval", "foo": {"is": {"nested": "bar"}}}
|
||||
|
||||
with set_grains({"a": "aval", "foo": {"is": {"nested": "bar"}}}):
|
||||
# Fails setting a nested grain to a dict
|
||||
ret = grains.present(name="foo:is:nested", value={"k1": "v1"})
|
||||
assert ret["result"] is False
|
||||
assert (
|
||||
ret["comment"]
|
||||
== "The key 'foo:is:nested' exists and the given value is a dict or a list. Use 'force=True' to overwrite."
|
||||
)
|
||||
assert ret["changes"] == {}
|
||||
assert grains.__grains__ == {"a": "aval", "foo": {"is": {"nested": "bar"}}}
|
||||
|
||||
|
||||
def test_present_fail_merge_dict():
|
||||
with set_grains({"a": "aval", "foo": {"k1": "v1"}}):
|
||||
# Fails setting a grain to a dict
|
||||
ret = grains.present(name="foo", value={"k2": "v2"})
|
||||
assert ret["result"] is False
|
||||
assert (
|
||||
ret["comment"]
|
||||
== "The key 'foo' exists but is a dict or a list. Use 'force=True' to overwrite."
|
||||
)
|
||||
assert grains.__grains__ == {"a": "aval", "foo": {"k1": "v1"}}
|
||||
assert_grain_file_content("a: aval\nfoo:\n k1: v1\n")
|
||||
|
||||
|
||||
def test_present_force_to_set_dict_or_list():
|
||||
with set_grains({"a": "aval", "foo": "bar"}):
|
||||
# Force to overwrite a grain to a list
|
||||
ret = grains.present(name="foo", value=["l1", "l2"], force=True)
|
||||
assert ret["result"] is True
|
||||
assert ret["comment"] == "Set grain foo to ['l1', 'l2']"
|
||||
assert ret["changes"] == {"foo": ["l1", "l2"]}
|
||||
assert grains.__grains__ == {"a": "aval", "foo": ["l1", "l2"]}
|
||||
assert_grain_file_content("a: aval\nfoo:\n- l1\n- l2\n")
|
||||
|
||||
with set_grains({"a": "aval", "foo": "bar"}):
|
||||
# Force setting a grain to a dict
|
||||
ret = grains.present(name="foo", value={"k1": "v1"}, force=True)
|
||||
assert ret["result"] is True
|
||||
assert ret["comment"] == "Set grain foo to {'k1': 'v1'}"
|
||||
assert ret["changes"] == {"foo": {"k1": "v1"}}
|
||||
assert grains.__grains__ == {"a": "aval", "foo": {"k1": "v1"}}
|
||||
assert_grain_file_content("a: aval\nfoo:\n k1: v1\n")
|
||||
|
||||
with set_grains({"a": "aval", "foo": {"is": {"nested": "bar"}}}):
|
||||
# Force to overwrite a nested grain to a list
|
||||
ret = grains.present(
|
||||
name="foo,is,nested", value=["l1", "l2"], delimiter=",", force=True
|
||||
)
|
||||
assert ret["result"] is True
|
||||
assert ret["changes"] == {"foo": {"is": {"nested": ["l1", "l2"]}}}
|
||||
assert ret["comment"] == "Set grain foo:is:nested to ['l1', 'l2']"
|
||||
assert grains.__grains__ == {
|
||||
"a": "aval",
|
||||
"foo": {"is": {"nested": ["l1", "l2"]}},
|
||||
}
|
||||
assert_grain_file_content(
|
||||
"a: aval\nfoo:\n is:\n nested:\n - l1\n - l2\n"
|
||||
)
|
||||
|
||||
with set_grains({"a": "aval", "foo": {"is": {"nested": "bar"}, "and": "other"}}):
|
||||
# Force setting a nested grain to a dict
|
||||
ret = grains.present(name="foo:is:nested", value={"k1": "v1"}, force=True)
|
||||
assert ret["result"] is True
|
||||
assert ret["comment"] == "Set grain foo:is:nested to {'k1': 'v1'}"
|
||||
assert ret["changes"] == {
|
||||
"foo": {"is": {"nested": {"k1": "v1"}}, "and": "other"}
|
||||
}
|
||||
assert grains.__grains__ == {
|
||||
"a": "aval",
|
||||
"foo": {"is": {"nested": {"k1": "v1"}}, "and": "other"},
|
||||
}
|
||||
assert_grain_file_content(
|
||||
"a: aval\nfoo:\n and: other\n is:\n nested:\n k1: v1\n"
|
||||
)
|
||||
|
||||
|
||||
def test_present_fails_to_convert_value_to_key():
|
||||
with set_grains({"a": "aval", "foo": "bar"}):
|
||||
# Fails converting a value to a nested grain key
|
||||
ret = grains.present(name="foo:is:nested", value={"k1": "v1"})
|
||||
assert ret["result"] is False
|
||||
assert (
|
||||
ret["comment"]
|
||||
== "The key 'foo' value is 'bar', which is different from the provided key 'is'. Use 'force=True' to overwrite."
|
||||
)
|
||||
assert ret["changes"] == {}
|
||||
|
||||
|
||||
def test_present_overwrite_test():
|
||||
with patch.dict(grains.__opts__, {"test": True}):
|
||||
with set_grains({"a": "aval", "foo": "bar"}):
|
||||
# Overwrite an existing grain
|
||||
ret = grains.present(name="foo", value="newbar")
|
||||
assert ret["result"] is None
|
||||
assert ret["changes"] == {"changed": {"foo": "newbar"}}
|
||||
assert grains.__grains__ == {"a": "aval", "foo": "bar"}
|
||||
assert_grain_file_content("a: aval\nfoo: bar\n")
|
||||
|
||||
|
||||
def test_present_convert_value_to_key():
|
||||
with set_grains({"a": "aval", "foo": "is"}):
|
||||
# Converts a value to a nested grain key
|
||||
ret = grains.present(name="foo:is:nested", value={"k1": "v1"})
|
||||
assert ret["result"] is True
|
||||
assert ret["comment"] == "Set grain foo:is:nested to {'k1': 'v1'}"
|
||||
assert ret["changes"] == {"foo": {"is": {"nested": {"k1": "v1"}}}}
|
||||
assert grains.__grains__ == {
|
||||
"a": "aval",
|
||||
"foo": {"is": {"nested": {"k1": "v1"}}},
|
||||
}
|
||||
assert_grain_file_content("a: aval\nfoo:\n is:\n nested:\n k1: v1\n")
|
||||
|
||||
with set_grains({"a": "aval", "foo": ["one", "is", "correct"]}):
|
||||
# Converts a list element to a nested grain key
|
||||
ret = grains.present(name="foo:is:nested", value={"k1": "v1"})
|
||||
assert ret["result"] is True
|
||||
assert ret["comment"] == "Set grain foo:is:nested to {'k1': 'v1'}"
|
||||
assert ret["changes"] == {
|
||||
"foo": ["one", {"is": {"nested": {"k1": "v1"}}}, "correct"]
|
||||
}
|
||||
assert grains.__grains__ == {
|
||||
"a": "aval",
|
||||
"foo": ["one", {"is": {"nested": {"k1": "v1"}}}, "correct"],
|
||||
}
|
||||
assert_grain_file_content(
|
||||
"a: aval\nfoo:\n- one\n- is:\n nested:\n k1: v1\n- correct\n"
|
||||
)
|
||||
|
||||
|
||||
def test_present_unknown_failure():
|
||||
with patch("salt.modules.grains.setval") as mocked_setval:
|
||||
mocked_setval.return_value = "Failed to set grain foo"
|
||||
with set_grains({"a": "aval", "foo": "bar"}):
|
||||
# Unknown reason failure
|
||||
ret = grains.present(name="foo", value="baz")
|
||||
assert ret["result"] is False
|
||||
assert ret["comment"] == "Failed to set grain foo"
|
||||
assert ret["changes"] == {}
|
||||
assert grains.__grains__ == {"a": "aval", "foo": "bar"}
|
||||
assert_grain_file_content("a: aval\nfoo: bar\n")
|
||||
|
||||
|
||||
# 'absent' function tests: 6
|
||||
|
||||
|
||||
def test_absent_already():
|
||||
# Unset a non existent grain
|
||||
with set_grains({"a": "aval"}):
|
||||
ret = grains.absent(name="foo")
|
||||
assert ret["result"] is True
|
||||
assert ret["comment"] == "Grain foo does not exist"
|
||||
assert ret["changes"] == {}
|
||||
assert grains.__grains__ == {"a": "aval"}
|
||||
assert_grain_file_content("a: aval\n")
|
||||
|
||||
# Unset a non existent nested grain
|
||||
with set_grains({"a": "aval"}):
|
||||
ret = grains.absent(name="foo:is:nested")
|
||||
assert ret["result"] is True
|
||||
assert ret["comment"] == "Grain foo:is:nested does not exist"
|
||||
assert ret["changes"] == {}
|
||||
assert grains.__grains__ == {"a": "aval"}
|
||||
assert_grain_file_content("a: aval\n")
|
||||
|
||||
|
||||
def test_absent_unset():
|
||||
# Unset a grain
|
||||
with set_grains({"a": "aval", "foo": "bar"}):
|
||||
ret = grains.absent(name="foo")
|
||||
assert ret["result"] is True
|
||||
assert ret["comment"] == "Value for grain foo was set to None"
|
||||
assert ret["changes"] == {"grain": "foo", "value": None}
|
||||
assert grains.__grains__ == {"a": "aval", "foo": None}
|
||||
assert_grain_file_content("a: aval\nfoo: null\n")
|
||||
|
||||
# Unset grain when its value is False
|
||||
with set_grains({"a": "aval", "foo": False}):
|
||||
ret = grains.absent(name="foo")
|
||||
assert ret["result"] is True
|
||||
assert ret["comment"] == "Value for grain foo was set to None"
|
||||
assert ret["changes"] == {"grain": "foo", "value": None}
|
||||
assert grains.__grains__ == {"a": "aval", "foo": None}
|
||||
assert_grain_file_content("a: aval\nfoo: null\n")
|
||||
|
||||
# Unset a nested grain
|
||||
with set_grains(
|
||||
{"a": "aval", "foo": ["order", {"is": {"nested": "bar"}}, "correct"]}
|
||||
):
|
||||
ret = grains.absent(name="foo,is,nested", delimiter=",")
|
||||
assert ret["result"] is True
|
||||
assert ret["comment"] == "Value for grain foo:is:nested was set to None"
|
||||
assert ret["changes"] == {"grain": "foo:is:nested", "value": None}
|
||||
assert grains.__grains__ == {
|
||||
"a": "aval",
|
||||
"foo": ["order", {"is": {"nested": None}}, "correct"],
|
||||
}
|
||||
assert_grain_file_content(
|
||||
"a: aval\nfoo:\n- order\n- is:\n nested: null\n- correct\n"
|
||||
)
|
||||
|
||||
# Unset a nested value don't change anything
|
||||
with set_grains({"a": "aval", "foo": ["order", {"is": "nested"}, "correct"]}):
|
||||
ret = grains.absent(name="foo:is:nested")
|
||||
assert ret["result"] is True
|
||||
assert ret["comment"] == "Grain foo:is:nested does not exist"
|
||||
assert ret["changes"] == {}
|
||||
assert grains.__grains__ == {
|
||||
"a": "aval",
|
||||
"foo": ["order", {"is": "nested"}, "correct"],
|
||||
}
|
||||
assert_grain_file_content("a: aval\nfoo:\n- order\n- is: nested\n- correct\n")
|
||||
|
||||
|
||||
def test_absent_unset_test():
|
||||
with patch.dict(grains.__opts__, {"test": True}):
|
||||
with set_grains({"a": "aval", "foo": "bar"}):
|
||||
# Overwrite an existing grain
|
||||
ret = grains.absent(name="foo")
|
||||
assert ret["result"] is None
|
||||
assert ret["changes"] == {"grain": "foo", "value": None}
|
||||
assert grains.__grains__ == {"a": "aval", "foo": "bar"}
|
||||
assert_grain_file_content("a: aval\nfoo: bar\n")
|
||||
|
||||
|
||||
def test_absent_fails_nested_complex_grain():
|
||||
# Unset a nested complex grain
|
||||
with set_grains(
|
||||
{"a": "aval", "foo": ["order", {"is": {"nested": "bar"}}, "correct"]}
|
||||
):
|
||||
ret = grains.absent(name="foo:is")
|
||||
assert ret["result"] is False
|
||||
assert (
|
||||
ret["comment"]
|
||||
== "The key 'foo:is' exists but is a dict or a list. Use 'force=True' to overwrite."
|
||||
)
|
||||
assert ret["changes"] == {}
|
||||
assert grains.__grains__ == {
|
||||
"a": "aval",
|
||||
"foo": ["order", {"is": {"nested": "bar"}}, "correct"],
|
||||
}
|
||||
assert_grain_file_content(
|
||||
"a: aval\nfoo:\n- order\n- is:\n nested: bar\n- correct\n"
|
||||
)
|
||||
|
||||
|
||||
def test_absent_force_nested_complex_grain():
|
||||
# Unset a nested complex grain
|
||||
with set_grains(
|
||||
{"a": "aval", "foo": ["order", {"is": {"nested": "bar"}}, "correct"]}
|
||||
):
|
||||
ret = grains.absent(name="foo:is", force=True)
|
||||
assert ret["result"] is True
|
||||
assert ret["comment"] == "Value for grain foo:is was set to None"
|
||||
assert ret["changes"] == {"grain": "foo:is", "value": None}
|
||||
assert grains.__grains__ == {
|
||||
"a": "aval",
|
||||
"foo": ["order", {"is": None}, "correct"],
|
||||
}
|
||||
assert_grain_file_content("a: aval\nfoo:\n- order\n- is: null\n- correct\n")
|
||||
|
||||
|
||||
def test_absent_delete():
|
||||
# Delete a grain
|
||||
with set_grains({"a": "aval", "foo": "bar"}):
|
||||
ret = grains.absent(name="foo", destructive=True)
|
||||
assert ret["result"] is True
|
||||
assert ret["comment"] == "Grain foo was deleted"
|
||||
assert ret["changes"] == {"deleted": "foo"}
|
||||
assert grains.__grains__ == {"a": "aval"}
|
||||
assert_grain_file_content("a: aval\n")
|
||||
|
||||
# Delete a previously unset grain
|
||||
with set_grains({"a": "aval", "foo": None}):
|
||||
ret = grains.absent(name="foo", destructive=True)
|
||||
assert ret["result"] is True
|
||||
assert ret["comment"] == "Grain foo was deleted"
|
||||
assert ret["changes"] == {"deleted": "foo"}
|
||||
assert grains.__grains__ == {"a": "aval"}
|
||||
assert_grain_file_content("a: aval\n")
|
||||
|
||||
# Delete a nested grain
|
||||
with set_grains(
|
||||
{
|
||||
"a": "aval",
|
||||
"foo": [
|
||||
"order",
|
||||
{"is": {"nested": "bar", "other": "value"}},
|
||||
"correct",
|
||||
],
|
||||
}
|
||||
):
|
||||
ret = grains.absent(name="foo:is:nested", destructive=True)
|
||||
assert ret["result"] is True
|
||||
assert ret["comment"] == "Grain foo:is:nested was deleted"
|
||||
assert ret["changes"] == {"deleted": "foo:is:nested"}
|
||||
assert grains.__grains__ == {
|
||||
"a": "aval",
|
||||
"foo": ["order", {"is": {"other": "value"}}, "correct"],
|
||||
}
|
||||
assert_grain_file_content(
|
||||
"a: aval\nfoo:\n- order\n- is:\n other: value\n- correct\n"
|
||||
)
|
||||
|
||||
|
||||
# 'append' function tests: 6
|
||||
|
||||
|
||||
def test_append():
|
||||
# Append to an existing list
|
||||
with set_grains({"a": "aval", "foo": ["bar"]}):
|
||||
ret = grains.append(name="foo", value="baz")
|
||||
assert ret["result"] is True
|
||||
assert ret["comment"] == "Value baz was added to grain foo"
|
||||
assert ret["changes"] == {"added": "baz"}
|
||||
assert grains.__grains__ == {"a": "aval", "foo": ["bar", "baz"]}
|
||||
assert_grain_file_content("a: aval\nfoo:\n- bar\n- baz\n")
|
||||
|
||||
|
||||
def test_append_nested():
|
||||
# Append to an existing nested list
|
||||
with set_grains({"a": "aval", "foo": {"list": ["bar"]}}):
|
||||
ret = grains.append(name="foo,list", value="baz", delimiter=",")
|
||||
assert ret["result"] is True
|
||||
assert ret["comment"] == "Value baz was added to grain foo:list"
|
||||
assert ret["changes"] == {"added": "baz"}
|
||||
assert grains.__grains__ == {"a": "aval", "foo": {"list": ["bar", "baz"]}}
|
||||
assert_grain_file_content("a: aval\nfoo:\n list:\n - bar\n - baz\n")
|
||||
|
||||
|
||||
def test_append_already():
|
||||
# Append to an existing list
|
||||
with set_grains({"a": "aval", "foo": ["bar"]}):
|
||||
ret = grains.append(name="foo", value="bar")
|
||||
assert ret["result"] is True
|
||||
assert ret["comment"] == "Value bar is already in the list " + "for grain foo"
|
||||
assert ret["changes"] == {}
|
||||
assert grains.__grains__ == {"a": "aval", "foo": ["bar"]}
|
||||
assert_grain_file_content("a: aval\nfoo:\n- bar\n")
|
||||
|
||||
|
||||
def test_append_fails_not_a_list():
|
||||
# Fail to append to an existing grain, not a list
|
||||
with set_grains({"a": "aval", "foo": {"bar": "val"}}):
|
||||
ret = grains.append(name="foo", value="baz")
|
||||
assert ret["result"] is False
|
||||
assert ret["comment"] == "Grain foo is not a valid list"
|
||||
assert ret["changes"] == {}
|
||||
assert grains.__grains__ == {"a": "aval", "foo": {"bar": "val"}}
|
||||
|
||||
|
||||
def test_append_convert_to_list():
|
||||
# Append to an existing grain, converting to a list
|
||||
with set_grains({"a": "aval", "foo": {"bar": "val"}}):
|
||||
assert_grain_file_content("a: aval\nfoo:\n bar: val\n")
|
||||
ret = grains.append(name="foo", value="baz", convert=True)
|
||||
assert ret["result"] is True
|
||||
assert ret["comment"] == "Value baz was added to grain foo"
|
||||
assert ret["changes"] == {"added": "baz"}
|
||||
assert grains.__grains__ == {"a": "aval", "foo": [{"bar": "val"}, "baz"]}
|
||||
assert_grain_file_content("a: aval\nfoo:\n- bar: val\n- baz\n")
|
||||
|
||||
# Append to an existing grain, converting to a list a multi-value dict
|
||||
with set_grains({"a": "aval", "foo": {"bar": "val", "other": "value"}}):
|
||||
assert_grain_file_content("a: aval\nfoo:\n bar: val\n other: value\n")
|
||||
ret = grains.append(name="foo", value="baz", convert=True)
|
||||
assert ret["result"] is True
|
||||
assert ret["comment"] == "Value baz was added to grain foo"
|
||||
assert ret["changes"] == {"added": "baz"}
|
||||
assert grains.__grains__ == {
|
||||
"a": "aval",
|
||||
"foo": [{"bar": "val", "other": "value"}, "baz"],
|
||||
}
|
||||
assert_grain_file_content("a: aval\nfoo:\n- bar: val\n other: value\n- baz\n")
|
||||
|
||||
|
||||
def test_append_fails_inexistent():
|
||||
# Append to a non existing grain
|
||||
with set_grains({"a": "aval"}):
|
||||
ret = grains.append(name="foo", value="bar")
|
||||
assert ret["result"] is False
|
||||
assert ret["comment"] == "Grain foo does not exist"
|
||||
assert ret["changes"] == {}
|
||||
assert grains.__grains__ == {"a": "aval"}
|
||||
|
||||
|
||||
def test_append_convert_to_list_empty():
|
||||
# Append to an existing list
|
||||
with set_grains({"foo": None}):
|
||||
ret = grains.append(name="foo", value="baz", convert=True)
|
||||
assert ret["result"] is True
|
||||
assert ret["comment"] == "Value baz was added to grain foo"
|
||||
assert ret["changes"] == {"added": "baz"}
|
||||
assert grains.__grains__ == {"foo": ["baz"]}
|
||||
assert_grain_file_content("foo:\n- baz\n")
|
||||
|
||||
|
||||
# 'list_present' function tests: 7
|
||||
|
||||
|
||||
def test_list_present():
|
||||
with set_grains({"a": "aval", "foo": ["bar"]}):
|
||||
ret = grains.list_present(name="foo", value="baz")
|
||||
assert ret["result"] is True
|
||||
assert ret["comment"] == "Append value baz to grain foo"
|
||||
assert ret["changes"] == {"new": {"foo": ["bar", "baz"]}}
|
||||
assert grains.__grains__ == {"a": "aval", "foo": ["bar", "baz"]}
|
||||
assert_grain_file_content("a: aval\nfoo:\n- bar\n- baz\n")
|
||||
|
||||
|
||||
def test_list_present_nested():
|
||||
with set_grains({"a": "aval", "foo": {"is": {"nested": ["bar"]}}}):
|
||||
ret = grains.list_present(name="foo,is,nested", value="baz", delimiter=",")
|
||||
assert ret["result"] is True
|
||||
assert ret["comment"] == "Append value baz to grain foo:is:nested"
|
||||
assert ret["changes"] == {"new": {"foo": {"is": {"nested": ["bar", "baz"]}}}}
|
||||
assert grains.__grains__ == {
|
||||
"a": "aval",
|
||||
"foo": {"is": {"nested": ["bar", "baz"]}},
|
||||
}
|
||||
assert_grain_file_content(
|
||||
"a: aval\nfoo:\n is:\n nested:\n - bar\n - baz\n"
|
||||
)
|
||||
|
||||
|
||||
def test_list_present_inexistent():
|
||||
with set_grains({"a": "aval"}):
|
||||
ret = grains.list_present(name="foo", value="baz")
|
||||
assert ret["result"] is True
|
||||
assert ret["comment"] == "Append value baz to grain foo"
|
||||
assert ret["changes"] == {"new": {"foo": ["baz"]}}
|
||||
assert grains.__grains__ == {"a": "aval", "foo": ["baz"]}
|
||||
assert_grain_file_content("a: aval\nfoo:\n- baz\n")
|
||||
|
||||
|
||||
def test_list_present_inexistent_nested():
|
||||
with set_grains({"a": "aval"}):
|
||||
ret = grains.list_present(name="foo:is:nested", value="baz")
|
||||
assert ret["result"] is True
|
||||
assert ret["comment"] == "Append value baz to grain foo:is:nested"
|
||||
assert ret["changes"] == {"new": {"foo": {"is": {"nested": ["baz"]}}}}
|
||||
assert grains.__grains__ == {"a": "aval", "foo": {"is": {"nested": ["baz"]}}}
|
||||
assert_grain_file_content("a: aval\nfoo:\n is:\n nested:\n - baz\n")
|
||||
|
||||
|
||||
def test_list_present_not_a_list():
|
||||
with set_grains({"a": "aval", "foo": "bar"}):
|
||||
ret = grains.list_present(name="foo", value="baz")
|
||||
assert ret["result"] is False
|
||||
assert ret["comment"] == "Grain foo is not a valid list"
|
||||
assert ret["changes"] == {}
|
||||
assert grains.__grains__ == {"a": "aval", "foo": "bar"}
|
||||
assert_grain_file_content("a: aval\nfoo: bar\n")
|
||||
|
||||
|
||||
def test_list_present_nested_already():
|
||||
with set_grains({"a": "aval", "b": {"foo": ["bar"]}}):
|
||||
ret = grains.list_present(name="b:foo", value="bar")
|
||||
assert ret["result"] is True
|
||||
assert ret["comment"] == "Value bar is already in grain b:foo"
|
||||
assert ret["changes"] == {}
|
||||
assert grains.__grains__ == {"a": "aval", "b": {"foo": ["bar"]}}
|
||||
assert_grain_file_content("a: aval\nb:\n foo:\n - bar\n")
|
||||
|
||||
|
||||
def test_list_present_already():
|
||||
with set_grains({"a": "aval", "foo": ["bar"]}):
|
||||
ret = grains.list_present(name="foo", value="bar")
|
||||
assert ret["result"] is True
|
||||
assert ret["comment"] == "Value bar is already in grain foo"
|
||||
assert ret["changes"] == {}
|
||||
assert grains.__grains__ == {"a": "aval", "foo": ["bar"]}
|
||||
assert_grain_file_content("a: aval\nfoo:\n- bar\n")
|
||||
|
||||
|
||||
def test_list_present_unknown_failure():
|
||||
with set_grains({"a": "aval", "foo": ["bar"]}):
|
||||
# Unknown reason failure
|
||||
|
||||
with patch.dict(grainsmod.__salt__, {"grains.append": MagicMock()}):
|
||||
ret = grains.list_present(name="foo", value="baz")
|
||||
assert ret["result"] is False
|
||||
assert ret["comment"] == "Failed append value baz to grain foo"
|
||||
assert ret["changes"] == {}
|
||||
assert grains.__grains__ == {"a": "aval", "foo": ["bar"]}
|
||||
assert_grain_file_content("a: aval\nfoo:\n- bar\n")
|
||||
|
||||
|
||||
# 'list_absent' function tests: 6
|
||||
|
||||
|
||||
def test_list_absent():
|
||||
with set_grains({"a": "aval", "foo": ["bar"]}):
|
||||
ret = grains.list_absent(name="foo", value="bar")
|
||||
assert ret["result"] is True
|
||||
assert ret["comment"] == "Value bar was deleted from grain foo"
|
||||
assert ret["changes"] == {"deleted": ["bar"]}
|
||||
assert grains.__grains__ == {"a": "aval", "foo": []}
|
||||
assert_grain_file_content("a: aval\nfoo: []\n")
|
||||
|
||||
|
||||
def test_list_absent_nested():
|
||||
with set_grains({"a": "aval", "foo": {"list": ["bar"]}}):
|
||||
ret = grains.list_absent(name="foo:list", value="bar")
|
||||
assert ret["result"] is True
|
||||
assert ret["comment"] == "Value bar was deleted from grain foo:list"
|
||||
assert ret["changes"] == {"deleted": ["bar"]}
|
||||
assert grains.__grains__ == {"a": "aval", "foo": {"list": []}}
|
||||
assert_grain_file_content("a: aval\nfoo:\n list: []\n")
|
||||
|
||||
|
||||
def test_list_absent_inexistent():
|
||||
with set_grains({"a": "aval"}):
|
||||
ret = grains.list_absent(name="foo", value="baz")
|
||||
assert ret["result"] is True
|
||||
assert ret["comment"] == "Grain foo does not exist"
|
||||
assert ret["changes"] == {}
|
||||
assert grains.__grains__ == {"a": "aval"}
|
||||
assert_grain_file_content("a: aval\n")
|
||||
|
||||
|
||||
def test_list_absent_inexistent_nested():
|
||||
with set_grains({"a": "aval"}):
|
||||
ret = grains.list_absent(name="foo:list", value="baz")
|
||||
assert ret["result"] is True
|
||||
assert ret["comment"] == "Grain foo:list does not exist"
|
||||
assert ret["changes"] == {}
|
||||
assert grains.__grains__ == {"a": "aval"}
|
||||
assert_grain_file_content("a: aval\n")
|
||||
|
||||
|
||||
def test_list_absent_not_a_list():
|
||||
with set_grains({"a": "aval", "foo": "bar"}):
|
||||
ret = grains.list_absent(name="foo", value="bar")
|
||||
assert ret["result"] is False
|
||||
assert ret["comment"] == "Grain foo is not a valid list"
|
||||
assert ret["changes"] == {}
|
||||
assert grains.__grains__ == {"a": "aval", "foo": "bar"}
|
||||
assert_grain_file_content("a: aval\nfoo: bar\n")
|
||||
|
||||
|
||||
def test_list_absent_already():
|
||||
with set_grains({"a": "aval", "foo": ["bar"]}):
|
||||
ret = grains.list_absent(name="foo", value="baz")
|
||||
assert ret["result"] is True
|
||||
assert ret["comment"] == "Value baz is absent from grain foo"
|
||||
assert ret["changes"] == {}
|
||||
assert grains.__grains__ == {"a": "aval", "foo": ["bar"]}
|
||||
assert_grain_file_content("a: aval\nfoo:\n- bar\n")
|
|
@ -1,58 +0,0 @@
|
|||
import io
|
||||
import urllib.request
|
||||
|
||||
import salt.modules.tomcat as tomcat
|
||||
from tests.support.mixins import LoaderModuleMockMixin
|
||||
from tests.support.mock import MagicMock, patch
|
||||
from tests.support.unit import TestCase
|
||||
|
||||
|
||||
class TomcatTestCasse(TestCase, LoaderModuleMockMixin):
|
||||
"""
|
||||
Tests cases for salt.modules.tomcat
|
||||
"""
|
||||
|
||||
def setup_loader_modules(self):
|
||||
return {tomcat: {}}
|
||||
|
||||
def test_tomcat_wget_no_bytestring(self):
|
||||
responses = {
|
||||
"string": io.StringIO("Best response ever\r\nAnd you know it!"),
|
||||
"bytes": io.BytesIO(b"Best response ever\r\nAnd you know it!"),
|
||||
}
|
||||
|
||||
string_mock = MagicMock(return_value=responses["string"])
|
||||
bytes_mock = MagicMock(return_value=responses["bytes"])
|
||||
with patch(
|
||||
"salt.modules.tomcat._auth",
|
||||
MagicMock(
|
||||
return_value=urllib.request.build_opener(
|
||||
urllib.request.HTTPBasicAuthHandler(),
|
||||
urllib.request.HTTPDigestAuthHandler(),
|
||||
)
|
||||
),
|
||||
):
|
||||
with patch("urllib.request.urlopen", string_mock):
|
||||
response = tomcat._wget(
|
||||
"tomcat.wait", url="http://localhost:8080/nofail"
|
||||
)
|
||||
for line in response["msg"]:
|
||||
self.assertIsInstance(line, str)
|
||||
|
||||
with patch("urllib.request.urlopen", bytes_mock):
|
||||
try:
|
||||
response = tomcat._wget(
|
||||
"tomcat.wait", url="http://localhost:8080/nofail"
|
||||
)
|
||||
except TypeError as type_error:
|
||||
if (
|
||||
type_error.args[0]
|
||||
== "startswith first arg must be bytes or a tuple of bytes,"
|
||||
" not str"
|
||||
):
|
||||
self.fail("Got back a byte string, should've been a string")
|
||||
else:
|
||||
raise type_error
|
||||
|
||||
for line in response["msg"]:
|
||||
self.assertIsInstance(line, str)
|
|
@ -1,897 +0,0 @@
|
|||
"""
|
||||
unit tests for the grains state
|
||||
"""
|
||||
|
||||
|
||||
import contextlib
|
||||
import os
|
||||
|
||||
import salt.modules.grains as grainsmod
|
||||
import salt.states.grains as grains
|
||||
import salt.utils.files
|
||||
import salt.utils.stringutils
|
||||
import salt.utils.yaml
|
||||
from tests.support.mixins import LoaderModuleMockMixin
|
||||
from tests.support.mock import MagicMock, patch
|
||||
from tests.support.runtests import RUNTIME_VARS
|
||||
from tests.support.unit import TestCase
|
||||
|
||||
|
||||
class GrainsTestCase(TestCase, LoaderModuleMockMixin):
|
||||
def setup_loader_modules(self):
|
||||
grains_test_dir = "__salt_test_state_grains"
|
||||
if not os.path.exists(os.path.join(RUNTIME_VARS.TMP, grains_test_dir)):
|
||||
os.makedirs(os.path.join(RUNTIME_VARS.TMP, grains_test_dir))
|
||||
loader_globals = {
|
||||
"__opts__": {
|
||||
"test": False,
|
||||
"conf_file": os.path.join(RUNTIME_VARS.TMP, grains_test_dir, "minion"),
|
||||
"cachedir": os.path.join(RUNTIME_VARS.TMP, grains_test_dir),
|
||||
"local": True,
|
||||
},
|
||||
"__salt__": {
|
||||
"cmd.run_all": MagicMock(
|
||||
return_value={"pid": 5, "retcode": 0, "stderr": "", "stdout": ""}
|
||||
),
|
||||
"grains.get": grainsmod.get,
|
||||
"grains.set": grainsmod.set,
|
||||
"grains.setval": grainsmod.setval,
|
||||
"grains.delval": grainsmod.delval,
|
||||
"grains.append": grainsmod.append,
|
||||
"grains.remove": grainsmod.remove,
|
||||
"saltutil.sync_grains": MagicMock(),
|
||||
},
|
||||
}
|
||||
return {grains: loader_globals, grainsmod: loader_globals}
|
||||
|
||||
def assertGrainFileContent(self, grains_string):
|
||||
if os.path.isdir(grains.__opts__["conf_file"]):
|
||||
grains_file = os.path.join(grains.__opts__["conf_file"], "grains")
|
||||
else:
|
||||
grains_file = os.path.join(
|
||||
os.path.dirname(grains.__opts__["conf_file"]), "grains"
|
||||
)
|
||||
with salt.utils.files.fopen(grains_file, "r") as grf:
|
||||
grains_data = salt.utils.stringutils.to_unicode(grf.read())
|
||||
self.assertMultiLineEqual(grains_string, grains_data)
|
||||
|
||||
@contextlib.contextmanager
|
||||
def setGrains(self, grains_data):
|
||||
with patch.dict(grains.__grains__, grains_data):
|
||||
with patch.dict(grainsmod.__grains__, grains_data):
|
||||
if os.path.isdir(grains.__opts__["conf_file"]):
|
||||
grains_file = os.path.join(grains.__opts__["conf_file"], "grains")
|
||||
else:
|
||||
grains_file = os.path.join(
|
||||
os.path.dirname(grains.__opts__["conf_file"]), "grains"
|
||||
)
|
||||
with salt.utils.files.fopen(grains_file, "w+") as grf:
|
||||
salt.utils.yaml.safe_dump(
|
||||
grains_data, grf, default_flow_style=False
|
||||
)
|
||||
yield
|
||||
|
||||
# 'exists' function tests: 2
|
||||
|
||||
def test_exists_missing(self):
|
||||
with self.setGrains({"a": "aval"}):
|
||||
ret = grains.exists(name="foo")
|
||||
self.assertEqual(ret["result"], False)
|
||||
self.assertEqual(ret["comment"], "Grain does not exist")
|
||||
self.assertEqual(ret["changes"], {})
|
||||
|
||||
def test_exists_found(self):
|
||||
with self.setGrains({"a": "aval", "foo": "bar"}):
|
||||
# Grain already set
|
||||
ret = grains.exists(name="foo")
|
||||
self.assertEqual(ret["result"], True)
|
||||
self.assertEqual(ret["comment"], "Grain exists")
|
||||
self.assertEqual(ret["changes"], {})
|
||||
|
||||
# 'make_hashable' function tests: 1
|
||||
|
||||
def test_make_hashable(self):
|
||||
with self.setGrains({"cmplx_lst_grain": [{"a": "aval"}, {"foo": "bar"}]}):
|
||||
hashable_list = {"cmplx_lst_grain": [{"a": "aval"}, {"foo": "bar"}]}
|
||||
self.assertEqual(
|
||||
grains.make_hashable(grains.__grains__).issubset(
|
||||
grains.make_hashable(hashable_list)
|
||||
),
|
||||
True,
|
||||
)
|
||||
|
||||
# 'present' function tests: 12
|
||||
|
||||
def test_present_add(self):
|
||||
# Set a non existing grain
|
||||
with self.setGrains({"a": "aval"}):
|
||||
ret = grains.present(name="foo", value="bar")
|
||||
self.assertEqual(ret["result"], True)
|
||||
self.assertEqual(ret["changes"], {"foo": "bar"})
|
||||
self.assertEqual(grains.__grains__, {"a": "aval", "foo": "bar"})
|
||||
self.assertGrainFileContent("a: aval\nfoo: bar\n")
|
||||
|
||||
# Set a non existing nested grain
|
||||
with self.setGrains({"a": "aval"}):
|
||||
ret = grains.present(name="foo:is:nested", value="bar")
|
||||
self.assertEqual(ret["result"], True)
|
||||
self.assertEqual(ret["changes"], {"foo": {"is": {"nested": "bar"}}})
|
||||
self.assertEqual(
|
||||
grains.__grains__, {"a": "aval", "foo": {"is": {"nested": "bar"}}}
|
||||
)
|
||||
self.assertGrainFileContent("a: aval\nfoo:\n is:\n nested: bar\n")
|
||||
|
||||
# Set a non existing nested dict grain
|
||||
with self.setGrains({"a": "aval"}):
|
||||
ret = grains.present(name="foo:is:nested", value={"bar": "is a dict"})
|
||||
self.assertEqual(ret["result"], True)
|
||||
self.assertEqual(
|
||||
ret["changes"], {"foo": {"is": {"nested": {"bar": "is a dict"}}}}
|
||||
)
|
||||
self.assertEqual(
|
||||
grains.__grains__,
|
||||
{"a": "aval", "foo": {"is": {"nested": {"bar": "is a dict"}}}},
|
||||
)
|
||||
self.assertGrainFileContent(
|
||||
"a: aval\n"
|
||||
+ "foo:\n"
|
||||
+ " is:\n"
|
||||
+ " nested:\n"
|
||||
+ " bar: is a dict\n"
|
||||
)
|
||||
|
||||
def test_present_add_key_to_existing(self):
|
||||
with self.setGrains({"a": "aval", "foo": {"k1": "v1"}}):
|
||||
# Fails setting a grain to a dict
|
||||
ret = grains.present(name="foo:k2", value="v2")
|
||||
self.assertEqual(ret["result"], True)
|
||||
self.assertEqual(ret["comment"], "Set grain foo:k2 to v2")
|
||||
self.assertEqual(ret["changes"], {"foo": {"k2": "v2", "k1": "v1"}})
|
||||
self.assertEqual(
|
||||
grains.__grains__, {"a": "aval", "foo": {"k1": "v1", "k2": "v2"}}
|
||||
)
|
||||
self.assertGrainFileContent(
|
||||
"a: aval\n" + "foo:\n" + " k1: v1\n" + " k2: v2\n"
|
||||
)
|
||||
|
||||
def test_present_already_set(self):
|
||||
with self.setGrains({"a": "aval", "foo": "bar"}):
|
||||
# Grain already set
|
||||
ret = grains.present(name="foo", value="bar")
|
||||
self.assertEqual(ret["result"], True)
|
||||
self.assertEqual(ret["comment"], "Grain is already set")
|
||||
self.assertEqual(ret["changes"], {})
|
||||
self.assertEqual(grains.__grains__, {"a": "aval", "foo": "bar"})
|
||||
|
||||
with self.setGrains({"a": "aval", "foo": {"is": {"nested": "bar"}}}):
|
||||
# Nested grain already set
|
||||
ret = grains.present(name="foo:is:nested", value="bar")
|
||||
self.assertEqual(ret["result"], True)
|
||||
self.assertEqual(ret["comment"], "Grain is already set")
|
||||
self.assertEqual(ret["changes"], {})
|
||||
self.assertEqual(
|
||||
grains.__grains__, {"a": "aval", "foo": {"is": {"nested": "bar"}}}
|
||||
)
|
||||
|
||||
with self.setGrains({"a": "aval", "foo": {"is": {"nested": "bar"}}}):
|
||||
# Nested dict grain already set
|
||||
ret = grains.present(name="foo:is", value={"nested": "bar"})
|
||||
self.assertEqual(ret["result"], True)
|
||||
self.assertEqual(ret["comment"], "Grain is already set")
|
||||
self.assertEqual(ret["changes"], {})
|
||||
self.assertEqual(
|
||||
grains.__grains__, {"a": "aval", "foo": {"is": {"nested": "bar"}}}
|
||||
)
|
||||
|
||||
def test_present_overwrite(self):
|
||||
with self.setGrains({"a": "aval", "foo": "bar"}):
|
||||
# Overwrite an existing grain
|
||||
ret = grains.present(name="foo", value="newbar")
|
||||
self.assertEqual(ret["result"], True)
|
||||
self.assertEqual(ret["changes"], {"foo": "newbar"})
|
||||
self.assertEqual(grains.__grains__, {"a": "aval", "foo": "newbar"})
|
||||
self.assertGrainFileContent("a: aval\n" + "foo: newbar\n")
|
||||
|
||||
with self.setGrains({"a": "aval", "foo": "bar"}):
|
||||
# Clear a grain (set to None)
|
||||
ret = grains.present(name="foo", value=None)
|
||||
self.assertEqual(ret["result"], True)
|
||||
self.assertEqual(ret["changes"], {"foo": None})
|
||||
self.assertEqual(grains.__grains__, {"a": "aval", "foo": None})
|
||||
self.assertGrainFileContent("a: aval\n" + "foo: null\n")
|
||||
|
||||
with self.setGrains({"a": "aval", "foo": {"is": {"nested": "bar"}}}):
|
||||
# Overwrite an existing nested grain
|
||||
ret = grains.present(name="foo:is:nested", value="newbar")
|
||||
self.assertEqual(ret["result"], True)
|
||||
self.assertEqual(ret["changes"], {"foo": {"is": {"nested": "newbar"}}})
|
||||
self.assertEqual(
|
||||
grains.__grains__, {"a": "aval", "foo": {"is": {"nested": "newbar"}}}
|
||||
)
|
||||
self.assertGrainFileContent(
|
||||
"a: aval\n" + "foo:\n" + " is:\n" + " nested: newbar\n"
|
||||
)
|
||||
|
||||
with self.setGrains({"a": "aval", "foo": {"is": {"nested": "bar"}}}):
|
||||
# Clear a nested grain (set to None)
|
||||
ret = grains.present(name="foo:is:nested", value=None)
|
||||
self.assertEqual(ret["result"], True)
|
||||
self.assertEqual(ret["changes"], {"foo": {"is": {"nested": None}}})
|
||||
self.assertEqual(
|
||||
grains.__grains__, {"a": "aval", "foo": {"is": {"nested": None}}}
|
||||
)
|
||||
self.assertGrainFileContent(
|
||||
"a: aval\n" + "foo:\n" + " is:\n" + " nested: null\n"
|
||||
)
|
||||
|
||||
def test_present_fail_overwrite(self):
|
||||
with self.setGrains({"a": "aval", "foo": {"is": {"nested": "val"}}}):
|
||||
# Overwrite an existing grain
|
||||
ret = grains.present(name="foo:is", value="newbar")
|
||||
self.assertEqual(ret["result"], False)
|
||||
self.assertEqual(ret["changes"], {})
|
||||
self.assertEqual(
|
||||
ret["comment"],
|
||||
"The key 'foo:is' exists but is a dict or a list. Use 'force=True' to"
|
||||
" overwrite.",
|
||||
)
|
||||
self.assertEqual(
|
||||
grains.__grains__, {"a": "aval", "foo": {"is": {"nested": "val"}}}
|
||||
)
|
||||
|
||||
with self.setGrains({"a": "aval", "foo": {"is": {"nested": "val"}}}):
|
||||
# Clear a grain (set to None)
|
||||
ret = grains.present(name="foo:is", value=None)
|
||||
self.assertEqual(ret["result"], False)
|
||||
self.assertEqual(ret["changes"], {})
|
||||
self.assertEqual(
|
||||
ret["comment"],
|
||||
"The key 'foo:is' exists but is a dict or a list. Use 'force=True' to"
|
||||
" overwrite.",
|
||||
)
|
||||
self.assertEqual(
|
||||
grains.__grains__, {"a": "aval", "foo": {"is": {"nested": "val"}}}
|
||||
)
|
||||
|
||||
def test_present_fails_to_set_dict_or_list(self):
|
||||
with self.setGrains({"a": "aval", "foo": "bar"}):
|
||||
# Fails to overwrite a grain to a list
|
||||
ret = grains.present(name="foo", value=["l1", "l2"])
|
||||
self.assertEqual(ret["result"], False)
|
||||
self.assertEqual(
|
||||
ret["comment"],
|
||||
"The key 'foo' exists and the "
|
||||
+ "given value is a dict or a list. "
|
||||
+ "Use 'force=True' to overwrite.",
|
||||
)
|
||||
self.assertEqual(ret["changes"], {})
|
||||
self.assertEqual(grains.__grains__, {"a": "aval", "foo": "bar"})
|
||||
|
||||
with self.setGrains({"a": "aval", "foo": "bar"}):
|
||||
# Fails setting a grain to a dict
|
||||
ret = grains.present(name="foo", value={"k1": "v1"})
|
||||
self.assertEqual(ret["result"], False)
|
||||
self.assertEqual(
|
||||
ret["comment"],
|
||||
"The key 'foo' exists and the given "
|
||||
+ "value is a dict or a list. Use "
|
||||
+ "'force=True' to overwrite.",
|
||||
)
|
||||
self.assertEqual(ret["changes"], {})
|
||||
self.assertEqual(grains.__grains__, {"a": "aval", "foo": "bar"})
|
||||
|
||||
with self.setGrains({"a": "aval", "foo": {"is": {"nested": "bar"}}}):
|
||||
# Fails to overwrite a nested grain to a list
|
||||
ret = grains.present(
|
||||
name="foo,is,nested", value=["l1", "l2"], delimiter=","
|
||||
)
|
||||
self.assertEqual(ret["result"], False)
|
||||
self.assertEqual(ret["changes"], {})
|
||||
self.assertEqual(
|
||||
ret["comment"],
|
||||
"The key 'foo:is:nested' exists and the "
|
||||
+ "given value is a dict or a list. "
|
||||
+ "Use 'force=True' to overwrite.",
|
||||
)
|
||||
self.assertEqual(
|
||||
grains.__grains__, {"a": "aval", "foo": {"is": {"nested": "bar"}}}
|
||||
)
|
||||
|
||||
with self.setGrains({"a": "aval", "foo": {"is": {"nested": "bar"}}}):
|
||||
# Fails setting a nested grain to a dict
|
||||
ret = grains.present(name="foo:is:nested", value={"k1": "v1"})
|
||||
self.assertEqual(ret["result"], False)
|
||||
self.assertEqual(
|
||||
ret["comment"],
|
||||
"The key 'foo:is:nested' exists and the "
|
||||
+ "given value is a dict or a list. "
|
||||
+ "Use 'force=True' to overwrite.",
|
||||
)
|
||||
self.assertEqual(ret["changes"], {})
|
||||
self.assertEqual(
|
||||
grains.__grains__, {"a": "aval", "foo": {"is": {"nested": "bar"}}}
|
||||
)
|
||||
|
||||
def test_present_fail_merge_dict(self):
|
||||
with self.setGrains({"a": "aval", "foo": {"k1": "v1"}}):
|
||||
# Fails setting a grain to a dict
|
||||
ret = grains.present(name="foo", value={"k2": "v2"})
|
||||
self.assertEqual(ret["result"], False)
|
||||
self.assertEqual(
|
||||
ret["comment"],
|
||||
"The key 'foo' exists but "
|
||||
+ "is a dict or a list. "
|
||||
+ "Use 'force=True' to overwrite.",
|
||||
)
|
||||
self.assertEqual(grains.__grains__, {"a": "aval", "foo": {"k1": "v1"}})
|
||||
self.assertGrainFileContent("a: aval\n" + "foo:\n" + " k1: v1\n")
|
||||
|
||||
def test_present_force_to_set_dict_or_list(self):
|
||||
with self.setGrains({"a": "aval", "foo": "bar"}):
|
||||
# Force to overwrite a grain to a list
|
||||
ret = grains.present(name="foo", value=["l1", "l2"], force=True)
|
||||
self.assertEqual(ret["result"], True)
|
||||
self.assertEqual(ret["comment"], "Set grain foo to ['l1', 'l2']")
|
||||
self.assertEqual(ret["changes"], {"foo": ["l1", "l2"]})
|
||||
self.assertEqual(grains.__grains__, {"a": "aval", "foo": ["l1", "l2"]})
|
||||
self.assertGrainFileContent("a: aval\n" + "foo:\n" + "- l1\n" + "- l2\n")
|
||||
|
||||
with self.setGrains({"a": "aval", "foo": "bar"}):
|
||||
# Force setting a grain to a dict
|
||||
ret = grains.present(name="foo", value={"k1": "v1"}, force=True)
|
||||
self.assertEqual(ret["result"], True)
|
||||
self.assertEqual(ret["comment"], "Set grain foo to {'k1': 'v1'}")
|
||||
self.assertEqual(ret["changes"], {"foo": {"k1": "v1"}})
|
||||
self.assertEqual(grains.__grains__, {"a": "aval", "foo": {"k1": "v1"}})
|
||||
self.assertGrainFileContent("a: aval\n" + "foo:\n" + " k1: v1\n")
|
||||
|
||||
with self.setGrains({"a": "aval", "foo": {"is": {"nested": "bar"}}}):
|
||||
# Force to overwrite a nested grain to a list
|
||||
ret = grains.present(
|
||||
name="foo,is,nested", value=["l1", "l2"], delimiter=",", force=True
|
||||
)
|
||||
self.assertEqual(ret["result"], True)
|
||||
self.assertEqual(ret["changes"], {"foo": {"is": {"nested": ["l1", "l2"]}}})
|
||||
self.assertEqual(ret["comment"], "Set grain foo:is:nested to ['l1', 'l2']")
|
||||
self.assertEqual(
|
||||
grains.__grains__,
|
||||
{"a": "aval", "foo": {"is": {"nested": ["l1", "l2"]}}},
|
||||
)
|
||||
self.assertGrainFileContent(
|
||||
"a: aval\n"
|
||||
+ "foo:\n"
|
||||
+ " is:\n"
|
||||
+ " nested:\n"
|
||||
+ " - l1\n"
|
||||
+ " - l2\n"
|
||||
)
|
||||
|
||||
with self.setGrains(
|
||||
{"a": "aval", "foo": {"is": {"nested": "bar"}, "and": "other"}}
|
||||
):
|
||||
# Force setting a nested grain to a dict
|
||||
ret = grains.present(name="foo:is:nested", value={"k1": "v1"}, force=True)
|
||||
self.assertEqual(ret["result"], True)
|
||||
self.assertEqual(ret["comment"], "Set grain foo:is:nested to {'k1': 'v1'}")
|
||||
self.assertEqual(
|
||||
ret["changes"],
|
||||
{"foo": {"is": {"nested": {"k1": "v1"}}, "and": "other"}},
|
||||
)
|
||||
self.assertEqual(
|
||||
grains.__grains__,
|
||||
{"a": "aval", "foo": {"is": {"nested": {"k1": "v1"}}, "and": "other"}},
|
||||
)
|
||||
self.assertGrainFileContent(
|
||||
"a: aval\n"
|
||||
+ "foo:\n"
|
||||
+ " and: other\n"
|
||||
+ " is:\n"
|
||||
+ " nested:\n"
|
||||
+ " k1: v1\n"
|
||||
)
|
||||
|
||||
def test_present_fails_to_convert_value_to_key(self):
|
||||
with self.setGrains({"a": "aval", "foo": "bar"}):
|
||||
# Fails converting a value to a nested grain key
|
||||
ret = grains.present(name="foo:is:nested", value={"k1": "v1"})
|
||||
self.assertEqual(ret["result"], False)
|
||||
self.assertEqual(
|
||||
ret["comment"],
|
||||
"The key 'foo' value is 'bar', "
|
||||
+ "which is different from the provided "
|
||||
+ "key 'is'. Use 'force=True' to overwrite.",
|
||||
)
|
||||
self.assertEqual(ret["changes"], {})
|
||||
|
||||
def test_present_overwrite_test(self):
|
||||
with patch.dict(grains.__opts__, {"test": True}):
|
||||
with self.setGrains({"a": "aval", "foo": "bar"}):
|
||||
# Overwrite an existing grain
|
||||
ret = grains.present(name="foo", value="newbar")
|
||||
self.assertEqual(ret["result"], None)
|
||||
self.assertEqual(ret["changes"], {"changed": {"foo": "newbar"}})
|
||||
self.assertEqual(grains.__grains__, {"a": "aval", "foo": "bar"})
|
||||
self.assertGrainFileContent("a: aval\n" + "foo: bar\n")
|
||||
|
||||
def test_present_convert_value_to_key(self):
|
||||
with self.setGrains({"a": "aval", "foo": "is"}):
|
||||
# Converts a value to a nested grain key
|
||||
ret = grains.present(name="foo:is:nested", value={"k1": "v1"})
|
||||
self.assertEqual(ret["result"], True)
|
||||
self.assertEqual(ret["comment"], "Set grain foo:is:nested to {'k1': 'v1'}")
|
||||
self.assertEqual(ret["changes"], {"foo": {"is": {"nested": {"k1": "v1"}}}})
|
||||
self.assertEqual(
|
||||
grains.__grains__,
|
||||
{"a": "aval", "foo": {"is": {"nested": {"k1": "v1"}}}},
|
||||
)
|
||||
self.assertGrainFileContent(
|
||||
"a: aval\n" + "foo:\n" + " is:\n" + " nested:\n" + " k1: v1\n"
|
||||
)
|
||||
|
||||
with self.setGrains({"a": "aval", "foo": ["one", "is", "correct"]}):
|
||||
# Converts a list element to a nested grain key
|
||||
ret = grains.present(name="foo:is:nested", value={"k1": "v1"})
|
||||
self.assertEqual(ret["result"], True)
|
||||
self.assertEqual(ret["comment"], "Set grain foo:is:nested to {'k1': 'v1'}")
|
||||
self.assertEqual(
|
||||
ret["changes"],
|
||||
{"foo": ["one", {"is": {"nested": {"k1": "v1"}}}, "correct"]},
|
||||
)
|
||||
self.assertEqual(
|
||||
grains.__grains__,
|
||||
{
|
||||
"a": "aval",
|
||||
"foo": ["one", {"is": {"nested": {"k1": "v1"}}}, "correct"],
|
||||
},
|
||||
)
|
||||
self.assertGrainFileContent(
|
||||
"a: aval\n"
|
||||
+ "foo:\n"
|
||||
+ "- one\n"
|
||||
+ "- is:\n"
|
||||
+ " nested:\n"
|
||||
+ " k1: v1\n"
|
||||
+ "- correct\n"
|
||||
)
|
||||
|
||||
def test_present_unknown_failure(self):
|
||||
with patch("salt.modules.grains.setval") as mocked_setval:
|
||||
mocked_setval.return_value = "Failed to set grain foo"
|
||||
with self.setGrains({"a": "aval", "foo": "bar"}):
|
||||
# Unknown reason failure
|
||||
ret = grains.present(name="foo", value="baz")
|
||||
self.assertEqual(ret["result"], False)
|
||||
self.assertEqual(ret["comment"], "Failed to set grain foo")
|
||||
self.assertEqual(ret["changes"], {})
|
||||
self.assertEqual(grains.__grains__, {"a": "aval", "foo": "bar"})
|
||||
self.assertGrainFileContent("a: aval\n" + "foo: bar\n")
|
||||
|
||||
# 'absent' function tests: 6
|
||||
|
||||
def test_absent_already(self):
|
||||
# Unset a non existent grain
|
||||
with self.setGrains({"a": "aval"}):
|
||||
ret = grains.absent(name="foo")
|
||||
self.assertEqual(ret["result"], True)
|
||||
self.assertEqual(ret["comment"], "Grain foo does not exist")
|
||||
self.assertEqual(ret["changes"], {})
|
||||
self.assertEqual(grains.__grains__, {"a": "aval"})
|
||||
self.assertGrainFileContent("a: aval\n")
|
||||
|
||||
# Unset a non existent nested grain
|
||||
with self.setGrains({"a": "aval"}):
|
||||
ret = grains.absent(name="foo:is:nested")
|
||||
self.assertEqual(ret["result"], True)
|
||||
self.assertEqual(ret["comment"], "Grain foo:is:nested does not exist")
|
||||
self.assertEqual(ret["changes"], {})
|
||||
self.assertEqual(grains.__grains__, {"a": "aval"})
|
||||
self.assertGrainFileContent("a: aval\n")
|
||||
|
||||
def test_absent_unset(self):
|
||||
# Unset a grain
|
||||
with self.setGrains({"a": "aval", "foo": "bar"}):
|
||||
ret = grains.absent(name="foo")
|
||||
self.assertEqual(ret["result"], True)
|
||||
self.assertEqual(ret["comment"], "Value for grain foo was set to None")
|
||||
self.assertEqual(ret["changes"], {"grain": "foo", "value": None})
|
||||
self.assertEqual(grains.__grains__, {"a": "aval", "foo": None})
|
||||
self.assertGrainFileContent("a: aval\n" + "foo: null\n")
|
||||
|
||||
# Unset grain when its value is False
|
||||
with self.setGrains({"a": "aval", "foo": False}):
|
||||
ret = grains.absent(name="foo")
|
||||
self.assertEqual(ret["result"], True)
|
||||
self.assertEqual(ret["comment"], "Value for grain foo was set to None")
|
||||
self.assertEqual(ret["changes"], {"grain": "foo", "value": None})
|
||||
self.assertEqual(grains.__grains__, {"a": "aval", "foo": None})
|
||||
self.assertGrainFileContent("a: aval\n" + "foo: null\n")
|
||||
|
||||
# Unset a nested grain
|
||||
with self.setGrains(
|
||||
{"a": "aval", "foo": ["order", {"is": {"nested": "bar"}}, "correct"]}
|
||||
):
|
||||
ret = grains.absent(name="foo,is,nested", delimiter=",")
|
||||
self.assertEqual(ret["result"], True)
|
||||
self.assertEqual(
|
||||
ret["comment"], "Value for grain foo:is:nested was set to None"
|
||||
)
|
||||
self.assertEqual(ret["changes"], {"grain": "foo:is:nested", "value": None})
|
||||
self.assertEqual(
|
||||
grains.__grains__,
|
||||
{"a": "aval", "foo": ["order", {"is": {"nested": None}}, "correct"]},
|
||||
)
|
||||
self.assertGrainFileContent(
|
||||
"a: aval\n"
|
||||
+ "foo:\n"
|
||||
+ "- order\n"
|
||||
+ "- is:\n"
|
||||
+ " nested: null\n"
|
||||
+ "- correct\n"
|
||||
)
|
||||
|
||||
# Unset a nested value don't change anything
|
||||
with self.setGrains(
|
||||
{"a": "aval", "foo": ["order", {"is": "nested"}, "correct"]}
|
||||
):
|
||||
ret = grains.absent(name="foo:is:nested")
|
||||
self.assertEqual(ret["result"], True)
|
||||
self.assertEqual(ret["comment"], "Grain foo:is:nested does not exist")
|
||||
self.assertEqual(ret["changes"], {})
|
||||
self.assertEqual(
|
||||
grains.__grains__,
|
||||
{"a": "aval", "foo": ["order", {"is": "nested"}, "correct"]},
|
||||
)
|
||||
self.assertGrainFileContent(
|
||||
"a: aval\n" + "foo:\n" + "- order\n" + "- is: nested\n" + "- correct\n"
|
||||
)
|
||||
|
||||
def test_absent_unset_test(self):
|
||||
with patch.dict(grains.__opts__, {"test": True}):
|
||||
with self.setGrains({"a": "aval", "foo": "bar"}):
|
||||
# Overwrite an existing grain
|
||||
ret = grains.absent(name="foo")
|
||||
self.assertEqual(ret["result"], None)
|
||||
self.assertEqual(ret["changes"], {"grain": "foo", "value": None})
|
||||
self.assertEqual(grains.__grains__, {"a": "aval", "foo": "bar"})
|
||||
self.assertGrainFileContent("a: aval\n" + "foo: bar\n")
|
||||
|
||||
def test_absent_fails_nested_complex_grain(self):
|
||||
# Unset a nested complex grain
|
||||
with self.setGrains(
|
||||
{"a": "aval", "foo": ["order", {"is": {"nested": "bar"}}, "correct"]}
|
||||
):
|
||||
ret = grains.absent(name="foo:is")
|
||||
self.assertEqual(ret["result"], False)
|
||||
self.assertEqual(
|
||||
ret["comment"],
|
||||
"The key 'foo:is' exists but is a dict or a list. Use 'force=True' to"
|
||||
" overwrite.",
|
||||
)
|
||||
self.assertEqual(ret["changes"], {})
|
||||
self.assertEqual(
|
||||
grains.__grains__,
|
||||
{"a": "aval", "foo": ["order", {"is": {"nested": "bar"}}, "correct"]},
|
||||
)
|
||||
self.assertGrainFileContent(
|
||||
"a: aval\n"
|
||||
+ "foo:\n"
|
||||
+ "- order\n"
|
||||
+ "- is:\n"
|
||||
+ " nested: bar\n"
|
||||
+ "- correct\n"
|
||||
)
|
||||
|
||||
def test_absent_force_nested_complex_grain(self):
|
||||
# Unset a nested complex grain
|
||||
with self.setGrains(
|
||||
{"a": "aval", "foo": ["order", {"is": {"nested": "bar"}}, "correct"]}
|
||||
):
|
||||
ret = grains.absent(name="foo:is", force=True)
|
||||
self.assertEqual(ret["result"], True)
|
||||
self.assertEqual(ret["comment"], "Value for grain foo:is was set to None")
|
||||
self.assertEqual(ret["changes"], {"grain": "foo:is", "value": None})
|
||||
self.assertEqual(
|
||||
grains.__grains__,
|
||||
{"a": "aval", "foo": ["order", {"is": None}, "correct"]},
|
||||
)
|
||||
self.assertGrainFileContent(
|
||||
"a: aval\n" + "foo:\n" + "- order\n" + "- is: null\n" + "- correct\n"
|
||||
)
|
||||
|
||||
def test_absent_delete(self):
|
||||
# Delete a grain
|
||||
with self.setGrains({"a": "aval", "foo": "bar"}):
|
||||
ret = grains.absent(name="foo", destructive=True)
|
||||
self.assertEqual(ret["result"], True)
|
||||
self.assertEqual(ret["comment"], "Grain foo was deleted")
|
||||
self.assertEqual(ret["changes"], {"deleted": "foo"})
|
||||
self.assertEqual(grains.__grains__, {"a": "aval"})
|
||||
self.assertGrainFileContent("a: aval\n")
|
||||
|
||||
# Delete a previously unset grain
|
||||
with self.setGrains({"a": "aval", "foo": None}):
|
||||
ret = grains.absent(name="foo", destructive=True)
|
||||
self.assertEqual(ret["result"], True)
|
||||
self.assertEqual(ret["comment"], "Grain foo was deleted")
|
||||
self.assertEqual(ret["changes"], {"deleted": "foo"})
|
||||
self.assertEqual(grains.__grains__, {"a": "aval"})
|
||||
self.assertGrainFileContent("a: aval\n")
|
||||
|
||||
# Delete a nested grain
|
||||
with self.setGrains(
|
||||
{
|
||||
"a": "aval",
|
||||
"foo": [
|
||||
"order",
|
||||
{"is": {"nested": "bar", "other": "value"}},
|
||||
"correct",
|
||||
],
|
||||
}
|
||||
):
|
||||
ret = grains.absent(name="foo:is:nested", destructive=True)
|
||||
self.assertEqual(ret["result"], True)
|
||||
self.assertEqual(ret["comment"], "Grain foo:is:nested was deleted")
|
||||
self.assertEqual(ret["changes"], {"deleted": "foo:is:nested"})
|
||||
self.assertEqual(
|
||||
grains.__grains__,
|
||||
{"a": "aval", "foo": ["order", {"is": {"other": "value"}}, "correct"]},
|
||||
)
|
||||
self.assertGrainFileContent(
|
||||
"a: aval\n"
|
||||
+ "foo:\n"
|
||||
+ "- order\n"
|
||||
+ "- is:\n"
|
||||
+ " other: value\n"
|
||||
+ "- correct\n"
|
||||
)
|
||||
|
||||
# 'append' function tests: 6
|
||||
|
||||
def test_append(self):
|
||||
# Append to an existing list
|
||||
with self.setGrains({"a": "aval", "foo": ["bar"]}):
|
||||
ret = grains.append(name="foo", value="baz")
|
||||
self.assertEqual(ret["result"], True)
|
||||
self.assertEqual(ret["comment"], "Value baz was added to grain foo")
|
||||
self.assertEqual(ret["changes"], {"added": "baz"})
|
||||
self.assertEqual(grains.__grains__, {"a": "aval", "foo": ["bar", "baz"]})
|
||||
self.assertGrainFileContent("a: aval\n" + "foo:\n" + "- bar\n" + "- baz\n")
|
||||
|
||||
def test_append_nested(self):
|
||||
# Append to an existing nested list
|
||||
with self.setGrains({"a": "aval", "foo": {"list": ["bar"]}}):
|
||||
ret = grains.append(name="foo,list", value="baz", delimiter=",")
|
||||
self.assertEqual(ret["result"], True)
|
||||
self.assertEqual(ret["comment"], "Value baz was added to grain foo:list")
|
||||
self.assertEqual(ret["changes"], {"added": "baz"})
|
||||
self.assertEqual(
|
||||
grains.__grains__, {"a": "aval", "foo": {"list": ["bar", "baz"]}}
|
||||
)
|
||||
self.assertGrainFileContent(
|
||||
"a: aval\n" + "foo:\n" + " list:\n" + " - bar\n" + " - baz\n"
|
||||
)
|
||||
|
||||
def test_append_already(self):
|
||||
# Append to an existing list
|
||||
with self.setGrains({"a": "aval", "foo": ["bar"]}):
|
||||
ret = grains.append(name="foo", value="bar")
|
||||
self.assertEqual(ret["result"], True)
|
||||
self.assertEqual(
|
||||
ret["comment"], "Value bar is already in the list " + "for grain foo"
|
||||
)
|
||||
self.assertEqual(ret["changes"], {})
|
||||
self.assertEqual(grains.__grains__, {"a": "aval", "foo": ["bar"]})
|
||||
self.assertGrainFileContent("a: aval\n" + "foo:\n" + "- bar\n")
|
||||
|
||||
def test_append_fails_not_a_list(self):
|
||||
# Fail to append to an existing grain, not a list
|
||||
with self.setGrains({"a": "aval", "foo": {"bar": "val"}}):
|
||||
ret = grains.append(name="foo", value="baz")
|
||||
self.assertEqual(ret["result"], False)
|
||||
self.assertEqual(ret["comment"], "Grain foo is not a valid list")
|
||||
self.assertEqual(ret["changes"], {})
|
||||
self.assertEqual(grains.__grains__, {"a": "aval", "foo": {"bar": "val"}})
|
||||
|
||||
def test_append_convert_to_list(self):
|
||||
# Append to an existing grain, converting to a list
|
||||
with self.setGrains({"a": "aval", "foo": {"bar": "val"}}):
|
||||
self.assertGrainFileContent("a: aval\n" + "foo:\n" + " bar: val\n")
|
||||
ret = grains.append(name="foo", value="baz", convert=True)
|
||||
self.assertEqual(ret["result"], True)
|
||||
self.assertEqual(ret["comment"], "Value baz was added to grain foo")
|
||||
self.assertEqual(ret["changes"], {"added": "baz"})
|
||||
self.assertEqual(
|
||||
grains.__grains__, {"a": "aval", "foo": [{"bar": "val"}, "baz"]}
|
||||
)
|
||||
self.assertGrainFileContent(
|
||||
"a: aval\n" + "foo:\n" + "- bar: val\n" + "- baz\n"
|
||||
)
|
||||
|
||||
# Append to an existing grain, converting to a list a multi-value dict
|
||||
with self.setGrains({"a": "aval", "foo": {"bar": "val", "other": "value"}}):
|
||||
self.assertGrainFileContent(
|
||||
"a: aval\n" + "foo:\n" + " bar: val\n" + " other: value\n"
|
||||
)
|
||||
ret = grains.append(name="foo", value="baz", convert=True)
|
||||
self.assertEqual(ret["result"], True)
|
||||
self.assertEqual(ret["comment"], "Value baz was added to grain foo")
|
||||
self.assertEqual(ret["changes"], {"added": "baz"})
|
||||
self.assertEqual(
|
||||
grains.__grains__,
|
||||
{"a": "aval", "foo": [{"bar": "val", "other": "value"}, "baz"]},
|
||||
)
|
||||
self.assertGrainFileContent(
|
||||
"a: aval\n" + "foo:\n" + "- bar: val\n" + " other: value\n" + "- baz\n"
|
||||
)
|
||||
|
||||
def test_append_fails_inexistent(self):
|
||||
# Append to a non existing grain
|
||||
with self.setGrains({"a": "aval"}):
|
||||
ret = grains.append(name="foo", value="bar")
|
||||
self.assertEqual(ret["result"], False)
|
||||
self.assertEqual(ret["comment"], "Grain foo does not exist")
|
||||
self.assertEqual(ret["changes"], {})
|
||||
self.assertEqual(grains.__grains__, {"a": "aval"})
|
||||
|
||||
def test_append_convert_to_list_empty(self):
|
||||
# Append to an existing list
|
||||
with self.setGrains({"foo": None}):
|
||||
ret = grains.append(name="foo", value="baz", convert=True)
|
||||
self.assertEqual(ret["result"], True)
|
||||
self.assertEqual(ret["comment"], "Value baz was added to grain foo")
|
||||
self.assertEqual(ret["changes"], {"added": "baz"})
|
||||
self.assertEqual(grains.__grains__, {"foo": ["baz"]})
|
||||
self.assertGrainFileContent("foo:\n" + "- baz\n")
|
||||
|
||||
# 'list_present' function tests: 7
|
||||
|
||||
def test_list_present(self):
|
||||
with self.setGrains({"a": "aval", "foo": ["bar"]}):
|
||||
ret = grains.list_present(name="foo", value="baz")
|
||||
self.assertEqual(ret["result"], True)
|
||||
self.assertEqual(ret["comment"], "Append value baz to grain foo")
|
||||
self.assertEqual(ret["changes"], {"new": {"foo": ["bar", "baz"]}})
|
||||
self.assertEqual(grains.__grains__, {"a": "aval", "foo": ["bar", "baz"]})
|
||||
self.assertGrainFileContent("a: aval\n" + "foo:\n" + "- bar\n" + "- baz\n")
|
||||
|
||||
def test_list_present_nested(self):
|
||||
with self.setGrains({"a": "aval", "foo": {"is": {"nested": ["bar"]}}}):
|
||||
ret = grains.list_present(name="foo,is,nested", value="baz", delimiter=",")
|
||||
self.assertEqual(ret["result"], True)
|
||||
self.assertEqual(ret["comment"], "Append value baz to grain foo:is:nested")
|
||||
self.assertEqual(
|
||||
ret["changes"], {"new": {"foo": {"is": {"nested": ["bar", "baz"]}}}}
|
||||
)
|
||||
self.assertEqual(
|
||||
grains.__grains__,
|
||||
{"a": "aval", "foo": {"is": {"nested": ["bar", "baz"]}}},
|
||||
)
|
||||
self.assertGrainFileContent(
|
||||
"a: aval\n"
|
||||
+ "foo:\n"
|
||||
+ " is:\n"
|
||||
+ " nested:\n"
|
||||
+ " - bar\n"
|
||||
+ " - baz\n"
|
||||
)
|
||||
|
||||
def test_list_present_inexistent(self):
|
||||
with self.setGrains({"a": "aval"}):
|
||||
ret = grains.list_present(name="foo", value="baz")
|
||||
self.assertEqual(ret["result"], True)
|
||||
self.assertEqual(ret["comment"], "Append value baz to grain foo")
|
||||
self.assertEqual(ret["changes"], {"new": {"foo": ["baz"]}})
|
||||
self.assertEqual(grains.__grains__, {"a": "aval", "foo": ["baz"]})
|
||||
self.assertGrainFileContent("a: aval\n" + "foo:\n" + "- baz\n")
|
||||
|
||||
def test_list_present_inexistent_nested(self):
|
||||
with self.setGrains({"a": "aval"}):
|
||||
ret = grains.list_present(name="foo:is:nested", value="baz")
|
||||
self.assertEqual(ret["result"], True)
|
||||
self.assertEqual(ret["comment"], "Append value baz to grain foo:is:nested")
|
||||
self.assertEqual(
|
||||
ret["changes"], {"new": {"foo": {"is": {"nested": ["baz"]}}}}
|
||||
)
|
||||
self.assertEqual(
|
||||
grains.__grains__, {"a": "aval", "foo": {"is": {"nested": ["baz"]}}}
|
||||
)
|
||||
self.assertGrainFileContent(
|
||||
"a: aval\n" + "foo:\n" + " is:\n" + " nested:\n" + " - baz\n"
|
||||
)
|
||||
|
||||
def test_list_present_not_a_list(self):
|
||||
with self.setGrains({"a": "aval", "foo": "bar"}):
|
||||
ret = grains.list_present(name="foo", value="baz")
|
||||
self.assertEqual(ret["result"], False)
|
||||
self.assertEqual(ret["comment"], "Grain foo is not a valid list")
|
||||
self.assertEqual(ret["changes"], {})
|
||||
self.assertEqual(grains.__grains__, {"a": "aval", "foo": "bar"})
|
||||
self.assertGrainFileContent("a: aval\n" + "foo: bar\n")
|
||||
|
||||
def test_list_present_nested_already(self):
|
||||
with self.setGrains({"a": "aval", "b": {"foo": ["bar"]}}):
|
||||
ret = grains.list_present(name="b:foo", value="bar")
|
||||
self.assertEqual(ret["result"], True)
|
||||
self.assertEqual(ret["comment"], "Value bar is already in grain b:foo")
|
||||
self.assertEqual(ret["changes"], {})
|
||||
self.assertEqual(grains.__grains__, {"a": "aval", "b": {"foo": ["bar"]}})
|
||||
self.assertGrainFileContent("a: aval\n" + "b:\n" + " foo:\n" + " - bar\n")
|
||||
|
||||
def test_list_present_already(self):
|
||||
with self.setGrains({"a": "aval", "foo": ["bar"]}):
|
||||
ret = grains.list_present(name="foo", value="bar")
|
||||
self.assertEqual(ret["result"], True)
|
||||
self.assertEqual(ret["comment"], "Value bar is already in grain foo")
|
||||
self.assertEqual(ret["changes"], {})
|
||||
self.assertEqual(grains.__grains__, {"a": "aval", "foo": ["bar"]})
|
||||
self.assertGrainFileContent("a: aval\n" + "foo:\n" + "- bar\n")
|
||||
|
||||
def test_list_present_unknown_failure(self):
|
||||
with self.setGrains({"a": "aval", "foo": ["bar"]}):
|
||||
# Unknown reason failure
|
||||
|
||||
with patch.dict(grainsmod.__salt__, {"grains.append": MagicMock()}):
|
||||
ret = grains.list_present(name="foo", value="baz")
|
||||
self.assertEqual(ret["result"], False)
|
||||
self.assertEqual(ret["comment"], "Failed append value baz to grain foo")
|
||||
self.assertEqual(ret["changes"], {})
|
||||
self.assertEqual(grains.__grains__, {"a": "aval", "foo": ["bar"]})
|
||||
self.assertGrainFileContent("a: aval\n" + "foo:\n" + "- bar\n")
|
||||
|
||||
# 'list_absent' function tests: 6
|
||||
|
||||
def test_list_absent(self):
|
||||
with self.setGrains({"a": "aval", "foo": ["bar"]}):
|
||||
ret = grains.list_absent(name="foo", value="bar")
|
||||
self.assertEqual(ret["result"], True)
|
||||
self.assertEqual(ret["comment"], "Value bar was deleted from grain foo")
|
||||
self.assertEqual(ret["changes"], {"deleted": ["bar"]})
|
||||
self.assertEqual(grains.__grains__, {"a": "aval", "foo": []})
|
||||
self.assertGrainFileContent("a: aval\n" + "foo: []\n")
|
||||
|
||||
def test_list_absent_nested(self):
|
||||
with self.setGrains({"a": "aval", "foo": {"list": ["bar"]}}):
|
||||
ret = grains.list_absent(name="foo:list", value="bar")
|
||||
self.assertEqual(ret["result"], True)
|
||||
self.assertEqual(
|
||||
ret["comment"], "Value bar was deleted from grain foo:list"
|
||||
)
|
||||
self.assertEqual(ret["changes"], {"deleted": ["bar"]})
|
||||
self.assertEqual(grains.__grains__, {"a": "aval", "foo": {"list": []}})
|
||||
self.assertGrainFileContent("a: aval\n" + "foo:\n" + " list: []\n")
|
||||
|
||||
def test_list_absent_inexistent(self):
|
||||
with self.setGrains({"a": "aval"}):
|
||||
ret = grains.list_absent(name="foo", value="baz")
|
||||
self.assertEqual(ret["result"], True)
|
||||
self.assertEqual(ret["comment"], "Grain foo does not exist")
|
||||
self.assertEqual(ret["changes"], {})
|
||||
self.assertEqual(grains.__grains__, {"a": "aval"})
|
||||
self.assertGrainFileContent("a: aval\n")
|
||||
|
||||
def test_list_absent_inexistent_nested(self):
|
||||
with self.setGrains({"a": "aval"}):
|
||||
ret = grains.list_absent(name="foo:list", value="baz")
|
||||
self.assertEqual(ret["result"], True)
|
||||
self.assertEqual(ret["comment"], "Grain foo:list does not exist")
|
||||
self.assertEqual(ret["changes"], {})
|
||||
self.assertEqual(grains.__grains__, {"a": "aval"})
|
||||
self.assertGrainFileContent("a: aval\n")
|
||||
|
||||
def test_list_absent_not_a_list(self):
|
||||
with self.setGrains({"a": "aval", "foo": "bar"}):
|
||||
ret = grains.list_absent(name="foo", value="bar")
|
||||
self.assertEqual(ret["result"], False)
|
||||
self.assertEqual(ret["comment"], "Grain foo is not a valid list")
|
||||
self.assertEqual(ret["changes"], {})
|
||||
self.assertEqual(grains.__grains__, {"a": "aval", "foo": "bar"})
|
||||
self.assertGrainFileContent("a: aval\n" + "foo: bar\n")
|
||||
|
||||
def test_list_absent_already(self):
|
||||
with self.setGrains({"a": "aval", "foo": ["bar"]}):
|
||||
ret = grains.list_absent(name="foo", value="baz")
|
||||
self.assertEqual(ret["result"], True)
|
||||
self.assertEqual(ret["comment"], "Value baz is absent from grain foo")
|
||||
self.assertEqual(ret["changes"], {})
|
||||
self.assertEqual(grains.__grains__, {"a": "aval", "foo": ["bar"]})
|
||||
self.assertGrainFileContent("a: aval\n" + "foo:\n" + "- bar\n")
|
|
@ -380,6 +380,9 @@ def rpm(
|
|||
assert incoming is not None
|
||||
assert repo_path is not None
|
||||
assert key_id is not None
|
||||
|
||||
if distro == "photon":
|
||||
distro_version = f"{distro_version}.0"
|
||||
display_name = f"{distro.capitalize()} {distro_version}"
|
||||
if distro_version not in _rpm_distro_info[distro]:
|
||||
ctx.error(f"Support for {display_name} is missing.")
|
||||
|
|
Loading…
Add table
Reference in a new issue