2012-03-27 17:05:38 -06:00
|
|
|
import os
|
2018-12-19 10:40:56 -08:00
|
|
|
import random
|
2013-04-10 16:24:41 +04:00
|
|
|
import sys
|
2017-12-21 15:53:38 -08:00
|
|
|
import tempfile
|
2019-08-01 11:07:51 +01:00
|
|
|
from contextlib import contextmanager
|
2020-04-02 20:10:20 -05:00
|
|
|
|
2020-04-10 08:30:25 +01:00
|
|
|
import pytest
|
2022-07-20 10:42:30 +01:00
|
|
|
|
Use explicit unicode strings + break up salt.utils
This PR is part of what will be an ongoing effort to use explicit
unicode strings in Salt. Because Python 3 does not suport Python 2's raw
unicode string syntax (i.e. `ur'\d+'`), we must use
`salt.utils.locales.sdecode()` to ensure that the raw string is unicode.
However, because of how `salt/utils/__init__.py` has evolved into the
hulking monstrosity it is today, this means importing a large module in
places where it is not needed, which could negatively impact
performance. For this reason, this PR also breaks out some of the
functions from `salt/utils/__init__.py` into new/existing modules under
`salt/utils/`. The long term goal will be that the modules within this
directory do not depend on importing `salt.utils`.
A summary of the changes in this PR is as follows:
* Moves the following functions from `salt.utils` to new locations
(including a deprecation warning if invoked from `salt.utils`):
`to_bytes`, `to_str`, `to_unicode`, `str_to_num`, `is_quoted`,
`dequote`, `is_hex`, `is_bin_str`, `rand_string`,
`contains_whitespace`, `clean_kwargs`, `invalid_kwargs`, `which`,
`which_bin`, `path_join`, `shlex_split`, `rand_str`, `is_windows`,
`is_proxy`, `is_linux`, `is_darwin`, `is_sunos`, `is_smartos`,
`is_smartos_globalzone`, `is_smartos_zone`, `is_freebsd`, `is_netbsd`,
`is_openbsd`, `is_aix`
* Moves the functions already deprecated by @rallytime to the bottom of
`salt/utils/__init__.py` for better organization, so we can keep the
deprecated ones separate from the ones yet to be deprecated as we
continue to break up `salt.utils`
* Updates `salt/*.py` and all files under `salt/client/` to use explicit
unicode string literals.
* Gets rid of implicit imports of `salt.utils` (e.g. `from salt.utils
import foo` becomes `import salt.utils.foo as foo`).
* Renames the `test.rand_str` function to `test.random_hash` to more
accurately reflect what it does
* Modifies `salt.utils.stringutils.random()` (née `salt.utils.rand_string()`)
such that it returns a string matching the passed size. Previously
this function would get `size` bytes from `os.urandom()`,
base64-encode it, and return the result, which would in most cases not
be equal to the passed size.
2017-07-24 20:47:15 -05:00
|
|
|
import salt.utils.path
|
2018-03-30 13:12:02 -05:00
|
|
|
import salt.utils.platform
|
2020-05-18 17:03:53 +01:00
|
|
|
import salt.utils.user
|
2017-04-03 17:04:09 +01:00
|
|
|
from tests.support.case import ModuleCase
|
2022-02-22 11:47:29 +00:00
|
|
|
from tests.support.helpers import SKIP_INITIAL_PHOTONOS_FAILURES, dedent
|
2018-12-07 17:52:49 +00:00
|
|
|
from tests.support.runtests import RUNTIME_VARS
|
2013-06-27 11:51:22 +01:00
|
|
|
|
Use explicit unicode strings + break up salt.utils
This PR is part of what will be an ongoing effort to use explicit
unicode strings in Salt. Because Python 3 does not suport Python 2's raw
unicode string syntax (i.e. `ur'\d+'`), we must use
`salt.utils.locales.sdecode()` to ensure that the raw string is unicode.
However, because of how `salt/utils/__init__.py` has evolved into the
hulking monstrosity it is today, this means importing a large module in
places where it is not needed, which could negatively impact
performance. For this reason, this PR also breaks out some of the
functions from `salt/utils/__init__.py` into new/existing modules under
`salt/utils/`. The long term goal will be that the modules within this
directory do not depend on importing `salt.utils`.
A summary of the changes in this PR is as follows:
* Moves the following functions from `salt.utils` to new locations
(including a deprecation warning if invoked from `salt.utils`):
`to_bytes`, `to_str`, `to_unicode`, `str_to_num`, `is_quoted`,
`dequote`, `is_hex`, `is_bin_str`, `rand_string`,
`contains_whitespace`, `clean_kwargs`, `invalid_kwargs`, `which`,
`which_bin`, `path_join`, `shlex_split`, `rand_str`, `is_windows`,
`is_proxy`, `is_linux`, `is_darwin`, `is_sunos`, `is_smartos`,
`is_smartos_globalzone`, `is_smartos_zone`, `is_freebsd`, `is_netbsd`,
`is_openbsd`, `is_aix`
* Moves the functions already deprecated by @rallytime to the bottom of
`salt/utils/__init__.py` for better organization, so we can keep the
deprecated ones separate from the ones yet to be deprecated as we
continue to break up `salt.utils`
* Updates `salt/*.py` and all files under `salt/client/` to use explicit
unicode string literals.
* Gets rid of implicit imports of `salt.utils` (e.g. `from salt.utils
import foo` becomes `import salt.utils.foo as foo`).
* Renames the `test.rand_str` function to `test.random_hash` to more
accurately reflect what it does
* Modifies `salt.utils.stringutils.random()` (née `salt.utils.rand_string()`)
such that it returns a string matching the passed size. Previously
this function would get `size` bytes from `os.urandom()`,
base64-encode it, and return the result, which would in most cases not
be equal to the passed size.
2017-07-24 20:47:15 -05:00
|
|
|
AVAILABLE_PYTHON_EXECUTABLE = salt.utils.path.which_bin(
|
2014-01-14 14:10:33 +00:00
|
|
|
["python", "python2", "python2.6", "python2.7"]
|
|
|
|
)
|
2012-05-05 19:39:23 +05:30
|
|
|
|
2012-03-27 17:05:38 -06:00
|
|
|
|
2020-04-10 08:30:25 +01:00
|
|
|
@pytest.mark.windows_whitelisted
|
2017-04-03 17:04:09 +01:00
|
|
|
class CMDModuleTest(ModuleCase):
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2012-03-27 17:05:38 -06:00
|
|
|
Validate the cmd module
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
|
|
|
|
2018-08-03 14:57:15 -04:00
|
|
|
def setUp(self):
|
2018-08-03 15:32:15 -04:00
|
|
|
self.runas_usr = "nobody"
|
|
|
|
if salt.utils.platform.is_darwin():
|
|
|
|
self.runas_usr = "macsalttest"
|
2018-08-03 14:57:15 -04:00
|
|
|
|
2019-08-01 11:07:51 +01:00
|
|
|
@contextmanager
|
|
|
|
def _ensure_user_exists(self, name):
|
|
|
|
if name in self.run_function("user.info", [name]).values():
|
|
|
|
# User already exists; don't touch
|
|
|
|
yield
|
|
|
|
else:
|
|
|
|
# Need to create user for test
|
|
|
|
self.run_function("user.add", [name])
|
|
|
|
try:
|
|
|
|
yield
|
|
|
|
finally:
|
|
|
|
self.run_function("user.delete", [name], remove=True)
|
2018-08-03 14:57:15 -04:00
|
|
|
|
2021-01-31 08:57:48 +00:00
|
|
|
@pytest.mark.slow_test
|
2022-11-03 17:28:06 +00:00
|
|
|
@pytest.mark.skip_on_windows
|
2012-03-27 17:05:38 -06:00
|
|
|
def test_run(self):
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2012-03-27 17:05:38 -06:00
|
|
|
cmd.run
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2013-08-10 12:14:10 -06:00
|
|
|
shell = os.environ.get("SHELL")
|
|
|
|
if shell is None:
|
|
|
|
# Failed to get the SHELL var, don't run
|
2013-08-10 19:50:31 +01:00
|
|
|
self.skipTest("Unable to get the SHELL environment variable")
|
|
|
|
|
2012-03-27 17:05:38 -06:00
|
|
|
self.assertTrue(self.run_function("cmd.run", ["echo $SHELL"]))
|
|
|
|
self.assertEqual(
|
2017-12-05 16:07:30 -06:00
|
|
|
self.run_function(
|
2024-02-27 11:08:46 +00:00
|
|
|
"cmd.run", ["echo $SHELL", f"shell={shell}"], python_shell=True
|
2013-04-10 16:24:41 +04:00
|
|
|
).rstrip(),
|
2020-04-02 20:10:20 -05:00
|
|
|
shell,
|
|
|
|
)
|
2012-03-27 17:05:38 -06:00
|
|
|
self.assertEqual(
|
2014-12-23 13:02:56 -07:00
|
|
|
self.run_function("cmd.run", ["ls / | grep etc"], python_shell=True), "etc"
|
2020-04-02 20:10:20 -05:00
|
|
|
)
|
2012-03-27 17:05:38 -06:00
|
|
|
self.assertEqual(
|
2017-12-05 16:07:30 -06:00
|
|
|
self.run_function(
|
2020-04-02 20:10:20 -05:00
|
|
|
"cmd.run",
|
2012-03-27 17:05:38 -06:00
|
|
|
['echo {{grains.id}} | awk "{print $1}"'],
|
2015-02-23 15:04:43 -07:00
|
|
|
template="jinja",
|
|
|
|
python_shell=True,
|
2020-04-02 20:10:20 -05:00
|
|
|
),
|
|
|
|
"minion",
|
|
|
|
)
|
2012-03-27 17:05:38 -06:00
|
|
|
self.assertEqual(
|
2013-03-21 16:22:29 -06:00
|
|
|
self.run_function(
|
2015-02-23 15:04:43 -07:00
|
|
|
"cmd.run", ["grep f"], stdin="one\ntwo\nthree\nfour\nfive\n"
|
|
|
|
),
|
|
|
|
"four\nfive",
|
|
|
|
)
|
2024-08-26 22:18:20 +02:00
|
|
|
self.assertEqual(
|
|
|
|
self.run_function(
|
|
|
|
"cmd.run", ["cat"], stdin="one\\ntwo", stdin_raw_newlines=False
|
|
|
|
),
|
|
|
|
"one\ntwo",
|
|
|
|
)
|
|
|
|
self.assertEqual(
|
|
|
|
self.run_function(
|
|
|
|
"cmd.run", ["cat"], stdin="one\\ntwo", stdin_raw_newlines=True
|
|
|
|
),
|
|
|
|
"one\\ntwo",
|
|
|
|
)
|
2015-02-23 15:04:43 -07:00
|
|
|
self.assertEqual(
|
|
|
|
self.run_function(
|
|
|
|
"cmd.run", ['echo "a=b" | sed -e s/=/:/g'], python_shell=True
|
|
|
|
),
|
|
|
|
"a:b",
|
|
|
|
)
|
2012-03-27 17:05:38 -06:00
|
|
|
|
2021-01-31 08:57:48 +00:00
|
|
|
@pytest.mark.slow_test
|
2012-03-27 17:05:38 -06:00
|
|
|
def test_stdout(self):
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2012-03-27 17:05:38 -06:00
|
|
|
cmd.run_stdout
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2013-03-21 16:22:29 -06:00
|
|
|
self.assertEqual(
|
|
|
|
self.run_function("cmd.run_stdout", ['echo "cheese"']).rstrip(),
|
2018-08-08 13:35:30 -04:00
|
|
|
"cheese" if not salt.utils.platform.is_windows() else '"cheese"',
|
|
|
|
)
|
2012-03-27 17:05:38 -06:00
|
|
|
|
2021-01-31 08:57:48 +00:00
|
|
|
@pytest.mark.slow_test
|
2012-03-27 17:05:38 -06:00
|
|
|
def test_stderr(self):
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2012-03-27 17:05:38 -06:00
|
|
|
cmd.run_stderr
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2014-09-04 10:23:59 +02:00
|
|
|
if sys.platform.startswith(("freebsd", "openbsd")):
|
2013-04-10 16:24:41 +04:00
|
|
|
shell = "/bin/sh"
|
|
|
|
else:
|
|
|
|
shell = "/bin/bash"
|
|
|
|
|
2013-03-21 16:22:29 -06:00
|
|
|
self.assertEqual(
|
|
|
|
self.run_function(
|
|
|
|
"cmd.run_stderr",
|
2024-02-27 11:08:46 +00:00
|
|
|
['echo "cheese" 1>&2', f"shell={shell}"],
|
2014-12-23 13:02:56 -07:00
|
|
|
python_shell=True,
|
2013-04-10 16:24:41 +04:00
|
|
|
).rstrip(),
|
2018-08-08 13:35:30 -04:00
|
|
|
"cheese" if not salt.utils.platform.is_windows() else '"cheese"',
|
|
|
|
)
|
2012-03-27 17:05:38 -06:00
|
|
|
|
2021-01-31 08:57:48 +00:00
|
|
|
@pytest.mark.slow_test
|
2012-03-27 17:05:38 -06:00
|
|
|
def test_run_all(self):
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2012-03-27 17:05:38 -06:00
|
|
|
cmd.run_all
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2014-09-04 10:23:59 +02:00
|
|
|
if sys.platform.startswith(("freebsd", "openbsd")):
|
2013-04-10 16:24:41 +04:00
|
|
|
shell = "/bin/sh"
|
|
|
|
else:
|
|
|
|
shell = "/bin/bash"
|
2020-04-02 20:10:20 -05:00
|
|
|
|
2013-04-10 16:24:41 +04:00
|
|
|
ret = self.run_function(
|
|
|
|
"cmd.run_all",
|
2024-02-27 11:08:46 +00:00
|
|
|
['echo "cheese" 1>&2', f"shell={shell}"],
|
2014-12-23 13:02:56 -07:00
|
|
|
python_shell=True,
|
|
|
|
)
|
2012-03-27 17:05:38 -06:00
|
|
|
self.assertTrue("pid" in ret)
|
|
|
|
self.assertTrue("retcode" in ret)
|
|
|
|
self.assertTrue("stdout" in ret)
|
|
|
|
self.assertTrue("stderr" in ret)
|
|
|
|
self.assertTrue(isinstance(ret.get("pid"), int))
|
|
|
|
self.assertTrue(isinstance(ret.get("retcode"), int))
|
2021-01-12 15:23:38 +00:00
|
|
|
self.assertTrue(isinstance(ret.get("stdout"), str))
|
|
|
|
self.assertTrue(isinstance(ret.get("stderr"), str))
|
2018-08-08 13:35:30 -04:00
|
|
|
self.assertEqual(
|
|
|
|
ret.get("stderr").rstrip(),
|
|
|
|
"cheese" if not salt.utils.platform.is_windows() else '"cheese"',
|
|
|
|
)
|
2012-03-27 17:05:38 -06:00
|
|
|
|
2021-01-31 08:57:48 +00:00
|
|
|
@pytest.mark.slow_test
|
2012-03-27 17:05:38 -06:00
|
|
|
def test_retcode(self):
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2012-03-27 17:05:38 -06:00
|
|
|
cmd.retcode
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2014-12-23 13:02:56 -07:00
|
|
|
self.assertEqual(
|
|
|
|
self.run_function("cmd.retcode", ["exit 0"], python_shell=True), 0
|
|
|
|
)
|
|
|
|
self.assertEqual(
|
|
|
|
self.run_function("cmd.retcode", ["exit 1"], python_shell=True), 1
|
|
|
|
)
|
2012-03-27 17:05:38 -06:00
|
|
|
|
2021-01-31 08:57:48 +00:00
|
|
|
@pytest.mark.slow_test
|
2018-02-08 16:04:25 -08:00
|
|
|
def test_run_all_with_success_retcodes(self):
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2018-02-08 16:04:25 -08:00
|
|
|
cmd.run with success_retcodes
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2018-02-02 18:13:51 -08:00
|
|
|
ret = self.run_function(
|
2018-02-08 16:04:25 -08:00
|
|
|
"cmd.run_all", ["exit 42"], success_retcodes=[42], python_shell=True
|
2018-02-02 18:13:51 -08:00
|
|
|
)
|
|
|
|
|
|
|
|
self.assertTrue("retcode" in ret)
|
|
|
|
self.assertEqual(ret.get("retcode"), 0)
|
|
|
|
|
2021-01-31 08:57:48 +00:00
|
|
|
@pytest.mark.slow_test
|
2018-02-08 16:04:25 -08:00
|
|
|
def test_retcode_with_success_retcodes(self):
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2018-02-08 16:04:25 -08:00
|
|
|
cmd.run with success_retcodes
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2018-02-02 18:13:51 -08:00
|
|
|
ret = self.run_function(
|
2018-02-08 16:04:25 -08:00
|
|
|
"cmd.retcode", ["exit 42"], success_retcodes=[42], python_shell=True
|
2018-02-02 18:13:51 -08:00
|
|
|
)
|
|
|
|
|
|
|
|
self.assertEqual(ret, 0)
|
|
|
|
|
2018-12-19 10:40:56 -08:00
|
|
|
@pytest.mark.slow_test
|
|
|
|
def test_run_all_with_success_stderr(self):
|
2021-03-18 18:55:55 -07:00
|
|
|
"""
|
2018-12-19 10:40:56 -08:00
|
|
|
cmd.run with success_retcodes
|
2021-03-18 18:55:55 -07:00
|
|
|
"""
|
|
|
|
random_file = "{}{}{}".format(
|
|
|
|
RUNTIME_VARS.TMP_ROOT_DIR, os.path.sep, random.random()
|
|
|
|
)
|
2019-01-03 10:54:03 -08:00
|
|
|
|
|
|
|
if salt.utils.platform.is_windows():
|
2021-03-18 18:55:55 -07:00
|
|
|
func = "type"
|
2021-04-02 07:23:55 -07:00
|
|
|
expected_stderr = "cannot find the file specified"
|
2019-01-03 10:54:03 -08:00
|
|
|
else:
|
2021-03-18 18:55:55 -07:00
|
|
|
func = "cat"
|
2021-04-02 07:23:55 -07:00
|
|
|
expected_stderr = "No such file or directory"
|
2021-03-18 18:55:55 -07:00
|
|
|
ret = self.run_function(
|
|
|
|
"cmd.run_all",
|
2024-02-27 11:08:46 +00:00
|
|
|
[f"{func} {random_file}"],
|
2021-03-18 18:55:55 -07:00
|
|
|
success_stderr=[expected_stderr],
|
|
|
|
python_shell=True,
|
|
|
|
)
|
|
|
|
|
|
|
|
self.assertTrue("retcode" in ret)
|
|
|
|
self.assertEqual(ret.get("retcode"), 0)
|
2018-12-19 10:40:56 -08:00
|
|
|
|
2021-01-31 08:57:48 +00:00
|
|
|
@pytest.mark.slow_test
|
2016-08-30 17:13:12 -06:00
|
|
|
def test_blacklist_glob(self):
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2016-08-30 17:13:12 -06:00
|
|
|
cmd_blacklist_glob
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2016-08-30 17:13:12 -06:00
|
|
|
self.assertEqual(
|
|
|
|
self.run_function("cmd.run", ["bad_command --foo"]).rstrip(),
|
2018-02-01 22:24:28 -06:00
|
|
|
'ERROR: The shell command "bad_command --foo" is not permitted',
|
|
|
|
)
|
2016-08-30 17:13:12 -06:00
|
|
|
|
2021-01-31 08:57:48 +00:00
|
|
|
@pytest.mark.slow_test
|
2025-01-17 23:05:31 +00:00
|
|
|
@pytest.mark.skip_on_windows
|
2015-03-01 19:54:22 -07:00
|
|
|
def test_script(self):
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2015-03-01 19:54:22 -07:00
|
|
|
cmd.script
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2015-03-01 19:54:22 -07:00
|
|
|
args = "saltines crackers biscuits=yes"
|
|
|
|
script = "salt://script.py"
|
2022-02-08 01:16:07 +00:00
|
|
|
ret = self.run_function("cmd.script", [script, args], saltenv="base")
|
2015-03-01 19:54:22 -07:00
|
|
|
self.assertEqual(ret["stdout"], args)
|
|
|
|
|
2021-01-29 15:35:59 -07:00
|
|
|
@pytest.mark.slow_test
|
2025-01-17 23:05:31 +00:00
|
|
|
@pytest.mark.skip_on_windows
|
2021-01-29 15:35:59 -07:00
|
|
|
def test_script_query_string(self):
|
|
|
|
"""
|
|
|
|
cmd.script
|
|
|
|
"""
|
|
|
|
args = "saltines crackers biscuits=yes"
|
|
|
|
script = "salt://script.py?saltenv=base"
|
2022-02-08 01:16:07 +00:00
|
|
|
ret = self.run_function("cmd.script", [script, args], saltenv="base")
|
2021-01-29 15:35:59 -07:00
|
|
|
self.assertEqual(ret["stdout"], args)
|
|
|
|
|
2021-01-31 08:57:48 +00:00
|
|
|
@pytest.mark.slow_test
|
2025-01-17 23:05:31 +00:00
|
|
|
@pytest.mark.skip_on_windows
|
2015-03-01 19:54:22 -07:00
|
|
|
def test_script_retcode(self):
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2015-03-01 19:54:22 -07:00
|
|
|
cmd.script_retcode
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2015-03-01 19:54:22 -07:00
|
|
|
script = "salt://script.py"
|
2022-02-08 01:16:07 +00:00
|
|
|
ret = self.run_function("cmd.script_retcode", [script], saltenv="base")
|
2015-03-01 19:54:22 -07:00
|
|
|
self.assertEqual(ret, 0)
|
|
|
|
|
2021-01-31 08:57:48 +00:00
|
|
|
@pytest.mark.slow_test
|
2025-01-17 23:05:31 +00:00
|
|
|
@pytest.mark.skip_on_windows
|
2017-12-21 15:53:38 -08:00
|
|
|
def test_script_cwd(self):
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2017-12-21 15:53:38 -08:00
|
|
|
cmd.script with cwd
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2018-12-07 17:52:49 +00:00
|
|
|
tmp_cwd = tempfile.mkdtemp(dir=RUNTIME_VARS.TMP)
|
2017-12-21 15:53:38 -08:00
|
|
|
args = "saltines crackers biscuits=yes"
|
|
|
|
script = "salt://script.py"
|
2022-02-08 01:16:07 +00:00
|
|
|
ret = self.run_function(
|
|
|
|
"cmd.script", [script, args], cwd=tmp_cwd, saltenv="base"
|
|
|
|
)
|
2017-12-21 15:53:38 -08:00
|
|
|
self.assertEqual(ret["stdout"], args)
|
|
|
|
|
2021-01-31 08:57:48 +00:00
|
|
|
@pytest.mark.slow_test
|
2025-01-17 23:05:31 +00:00
|
|
|
@pytest.mark.skip_on_windows
|
2017-12-21 15:53:38 -08:00
|
|
|
def test_script_cwd_with_space(self):
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2017-12-21 15:53:38 -08:00
|
|
|
cmd.script with cwd
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2021-01-12 15:23:38 +00:00
|
|
|
tmp_cwd = "{}{}test 2".format(
|
2018-12-07 17:52:49 +00:00
|
|
|
tempfile.mkdtemp(dir=RUNTIME_VARS.TMP), os.path.sep
|
|
|
|
)
|
2017-12-21 15:53:38 -08:00
|
|
|
os.mkdir(tmp_cwd)
|
|
|
|
|
|
|
|
args = "saltines crackers biscuits=yes"
|
|
|
|
script = "salt://script.py"
|
2022-02-08 01:16:07 +00:00
|
|
|
ret = self.run_function(
|
|
|
|
"cmd.script", [script, args], cwd=tmp_cwd, saltenv="base"
|
|
|
|
)
|
2017-12-21 15:53:38 -08:00
|
|
|
self.assertEqual(ret["stdout"], args)
|
|
|
|
|
2021-01-30 09:03:57 +00:00
|
|
|
@pytest.mark.destructive_test
|
2015-03-01 19:54:22 -07:00
|
|
|
def test_tty(self):
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2015-03-01 19:54:22 -07:00
|
|
|
cmd.tty
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2015-03-01 19:54:22 -07:00
|
|
|
for tty in ("tty0", "pts3"):
|
|
|
|
if os.path.exists(os.path.join("/dev", tty)):
|
|
|
|
ret = self.run_function("cmd.tty", [tty, "apply salt liberally"])
|
|
|
|
self.assertTrue("Success" in ret)
|
|
|
|
|
2021-08-31 13:08:29 -06:00
|
|
|
@pytest.mark.skip_on_windows
|
2021-01-31 10:03:56 +00:00
|
|
|
@pytest.mark.skip_if_binaries_missing("which")
|
2012-03-27 17:05:38 -06:00
|
|
|
def test_which(self):
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2012-03-27 17:05:38 -06:00
|
|
|
cmd.which
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2020-05-05 18:56:30 +01:00
|
|
|
cmd_which = self.run_function("cmd.which", ["cat"])
|
|
|
|
self.assertIsInstance(cmd_which, str)
|
|
|
|
cmd_run = self.run_function("cmd.run", ["which cat"])
|
|
|
|
self.assertIsInstance(cmd_run, str)
|
|
|
|
self.assertEqual(cmd_which.rstrip(), cmd_run.rstrip())
|
2012-03-27 17:05:38 -06:00
|
|
|
|
2021-08-31 13:08:29 -06:00
|
|
|
@pytest.mark.skip_on_windows
|
2021-01-31 10:03:56 +00:00
|
|
|
@pytest.mark.skip_if_binaries_missing("which")
|
2015-03-01 19:54:22 -07:00
|
|
|
def test_which_bin(self):
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2015-03-01 19:54:22 -07:00
|
|
|
cmd.which_bin
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2017-03-16 22:07:52 -05:00
|
|
|
cmds = ["pip3", "pip2", "pip", "pip-python"]
|
2015-03-01 19:54:22 -07:00
|
|
|
ret = self.run_function("cmd.which_bin", [cmds])
|
|
|
|
self.assertTrue(os.path.split(ret)[1] in cmds)
|
|
|
|
|
2021-01-31 08:57:48 +00:00
|
|
|
@pytest.mark.slow_test
|
2012-03-27 17:05:38 -06:00
|
|
|
def test_has_exec(self):
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2012-03-27 17:05:38 -06:00
|
|
|
cmd.has_exec
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2014-01-14 14:10:33 +00:00
|
|
|
self.assertTrue(
|
|
|
|
self.run_function("cmd.has_exec", [AVAILABLE_PYTHON_EXECUTABLE])
|
2020-04-02 20:10:20 -05:00
|
|
|
)
|
2013-03-21 16:22:29 -06:00
|
|
|
self.assertFalse(
|
|
|
|
self.run_function("cmd.has_exec", ["alllfsdfnwieulrrh9123857ygf"])
|
|
|
|
)
|
2012-03-27 17:05:38 -06:00
|
|
|
|
2021-01-31 08:57:48 +00:00
|
|
|
@pytest.mark.slow_test
|
2012-03-27 17:05:38 -06:00
|
|
|
def test_exec_code(self):
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2012-03-27 17:05:38 -06:00
|
|
|
cmd.exec_code
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2020-05-13 23:08:26 +00:00
|
|
|
code = dedent(
|
|
|
|
"""
|
2020-04-23 01:44:41 +03:00
|
|
|
import sys
|
|
|
|
sys.stdout.write('cheese')
|
|
|
|
"""
|
2020-05-13 23:08:26 +00:00
|
|
|
)
|
2013-03-21 16:22:29 -06:00
|
|
|
self.assertEqual(
|
|
|
|
self.run_function(
|
2014-01-14 14:10:33 +00:00
|
|
|
"cmd.exec_code", [AVAILABLE_PYTHON_EXECUTABLE, code]
|
|
|
|
).rstrip(),
|
2013-03-21 16:22:29 -06:00
|
|
|
"cheese",
|
|
|
|
)
|
2012-05-05 19:39:23 +05:30
|
|
|
|
2021-01-31 08:57:48 +00:00
|
|
|
@pytest.mark.slow_test
|
2017-08-16 21:40:33 +02:00
|
|
|
def test_exec_code_with_single_arg(self):
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2017-08-16 21:40:33 +02:00
|
|
|
cmd.exec_code
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2020-05-13 23:08:26 +00:00
|
|
|
code = dedent(
|
|
|
|
"""
|
2020-04-23 01:44:41 +03:00
|
|
|
import sys
|
|
|
|
sys.stdout.write(sys.argv[1])
|
|
|
|
"""
|
2020-05-13 23:08:26 +00:00
|
|
|
)
|
2017-08-16 21:40:33 +02:00
|
|
|
arg = "cheese"
|
|
|
|
self.assertEqual(
|
|
|
|
self.run_function(
|
|
|
|
"cmd.exec_code", [AVAILABLE_PYTHON_EXECUTABLE, code], args=arg
|
|
|
|
).rstrip(),
|
|
|
|
arg,
|
|
|
|
)
|
|
|
|
|
2021-01-31 08:57:48 +00:00
|
|
|
@pytest.mark.slow_test
|
2017-08-16 21:40:33 +02:00
|
|
|
def test_exec_code_with_multiple_args(self):
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2017-08-16 21:40:33 +02:00
|
|
|
cmd.exec_code
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2020-05-13 23:08:26 +00:00
|
|
|
code = dedent(
|
|
|
|
"""
|
2020-04-23 01:44:41 +03:00
|
|
|
import sys
|
|
|
|
sys.stdout.write(sys.argv[1])
|
|
|
|
"""
|
2020-05-13 23:08:26 +00:00
|
|
|
)
|
2017-08-16 21:40:33 +02:00
|
|
|
arg = "cheese"
|
|
|
|
self.assertEqual(
|
|
|
|
self.run_function(
|
|
|
|
"cmd.exec_code", [AVAILABLE_PYTHON_EXECUTABLE, code], args=[arg, "test"]
|
|
|
|
).rstrip(),
|
|
|
|
arg,
|
|
|
|
)
|
|
|
|
|
2021-01-31 08:57:48 +00:00
|
|
|
@pytest.mark.slow_test
|
2012-07-26 22:21:07 +06:00
|
|
|
def test_quotes(self):
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2012-07-26 22:21:07 +06:00
|
|
|
cmd.run with quoted command
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2012-07-26 22:21:07 +06:00
|
|
|
cmd = """echo 'SELECT * FROM foo WHERE bar="baz"' """
|
|
|
|
expected_result = 'SELECT * FROM foo WHERE bar="baz"'
|
2018-08-08 13:35:30 -04:00
|
|
|
if salt.utils.platform.is_windows():
|
2018-08-01 14:05:52 -04:00
|
|
|
expected_result = "'SELECT * FROM foo WHERE bar=\"baz\"'"
|
2012-07-26 22:21:07 +06:00
|
|
|
result = self.run_function("cmd.run_stdout", [cmd]).strip()
|
|
|
|
self.assertEqual(result, expected_result)
|
|
|
|
|
2021-02-02 18:36:14 +00:00
|
|
|
@pytest.mark.skip_if_not_root
|
2021-02-12 17:43:28 -07:00
|
|
|
@pytest.mark.skip_on_windows(reason="Skip on Windows, requires password")
|
2012-07-26 22:21:07 +06:00
|
|
|
def test_quotes_runas(self):
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2012-07-26 22:21:07 +06:00
|
|
|
cmd.run with quoted command
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2012-07-26 22:21:07 +06:00
|
|
|
cmd = """echo 'SELECT * FROM foo WHERE bar="baz"' """
|
|
|
|
expected_result = 'SELECT * FROM foo WHERE bar="baz"'
|
2020-05-05 18:56:30 +01:00
|
|
|
result = self.run_function(
|
|
|
|
"cmd.run_all", [cmd], runas=RUNTIME_VARS.RUNNING_TESTS_USER
|
|
|
|
)
|
2024-02-27 11:08:46 +00:00
|
|
|
errmsg = f"The command returned: {result}"
|
2020-05-05 18:56:30 +01:00
|
|
|
self.assertEqual(result["retcode"], 0, errmsg)
|
|
|
|
self.assertEqual(result["stdout"], expected_result, errmsg)
|
2012-07-26 22:21:07 +06:00
|
|
|
|
2021-01-30 09:03:57 +00:00
|
|
|
@pytest.mark.destructive_test
|
2021-02-02 18:36:14 +00:00
|
|
|
@pytest.mark.skip_if_not_root
|
2021-02-12 17:43:28 -07:00
|
|
|
@pytest.mark.skip_on_windows(reason="Skip on Windows, uses unix commands")
|
2021-01-31 08:57:48 +00:00
|
|
|
@pytest.mark.slow_test
|
2019-07-31 16:53:29 +01:00
|
|
|
def test_avoid_injecting_shell_code_as_root(self):
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2019-07-31 16:53:29 +01:00
|
|
|
cmd.run should execute the whole command as the "runas" user, not
|
|
|
|
running substitutions as root.
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2019-07-31 16:53:29 +01:00
|
|
|
cmd = "echo $(id -u)"
|
|
|
|
|
|
|
|
root_id = self.run_function("cmd.run_stdout", [cmd])
|
2019-10-11 13:17:24 +01:00
|
|
|
runas_root_id = self.run_function(
|
|
|
|
"cmd.run_stdout", [cmd], runas=RUNTIME_VARS.RUNNING_TESTS_USER
|
|
|
|
)
|
2019-08-01 11:07:51 +01:00
|
|
|
with self._ensure_user_exists(self.runas_usr):
|
|
|
|
user_id = self.run_function("cmd.run_stdout", [cmd], runas=self.runas_usr)
|
2019-07-31 16:53:29 +01:00
|
|
|
|
|
|
|
self.assertNotEqual(user_id, root_id)
|
|
|
|
self.assertNotEqual(user_id, runas_root_id)
|
|
|
|
self.assertEqual(root_id, runas_root_id)
|
|
|
|
|
2021-01-30 09:03:57 +00:00
|
|
|
@pytest.mark.destructive_test
|
2021-02-02 18:36:14 +00:00
|
|
|
@pytest.mark.skip_if_not_root
|
2021-02-12 17:43:28 -07:00
|
|
|
@pytest.mark.skip_on_windows(reason="Skip on Windows, uses unix commands")
|
2021-01-31 08:57:48 +00:00
|
|
|
@pytest.mark.slow_test
|
2019-07-31 16:53:29 +01:00
|
|
|
def test_cwd_runas(self):
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2019-07-31 16:53:29 +01:00
|
|
|
cmd.run should be able to change working directory correctly, whether
|
|
|
|
or not runas is in use.
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2019-07-31 16:53:29 +01:00
|
|
|
cmd = "pwd"
|
2018-12-07 17:52:49 +00:00
|
|
|
tmp_cwd = tempfile.mkdtemp(dir=RUNTIME_VARS.TMP)
|
2019-08-01 11:07:51 +01:00
|
|
|
os.chmod(tmp_cwd, 0o711)
|
2019-07-31 16:53:29 +01:00
|
|
|
|
|
|
|
cwd_normal = self.run_function("cmd.run_stdout", [cmd], cwd=tmp_cwd).rstrip(
|
|
|
|
"\n"
|
|
|
|
)
|
|
|
|
self.assertEqual(tmp_cwd, cwd_normal)
|
|
|
|
|
2019-08-01 11:07:51 +01:00
|
|
|
with self._ensure_user_exists(self.runas_usr):
|
|
|
|
cwd_runas = self.run_function(
|
|
|
|
"cmd.run_stdout", [cmd], cwd=tmp_cwd, runas=self.runas_usr
|
|
|
|
).rstrip("\n")
|
2019-07-31 16:53:29 +01:00
|
|
|
self.assertEqual(tmp_cwd, cwd_runas)
|
|
|
|
|
2021-01-30 09:03:57 +00:00
|
|
|
@pytest.mark.destructive_test
|
2021-02-02 18:36:14 +00:00
|
|
|
@pytest.mark.skip_if_not_root
|
2021-02-12 17:43:28 -07:00
|
|
|
@pytest.mark.skip_unless_on_darwin(reason="Applicable to MacOS only")
|
2021-01-31 08:57:48 +00:00
|
|
|
@pytest.mark.slow_test
|
2019-07-31 16:53:29 +01:00
|
|
|
def test_runas_env(self):
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2019-07-31 16:53:29 +01:00
|
|
|
cmd.run should be able to change working directory correctly, whether
|
|
|
|
or not runas is in use.
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2019-08-01 11:07:51 +01:00
|
|
|
with self._ensure_user_exists(self.runas_usr):
|
|
|
|
user_path = self.run_function(
|
|
|
|
"cmd.run_stdout", ['printf %s "$PATH"'], runas=self.runas_usr
|
|
|
|
)
|
2019-07-31 16:53:29 +01:00
|
|
|
# XXX: Not sure of a better way. Environment starts out with
|
|
|
|
# /bin:/usr/bin and should be populated by path helper and the bash
|
|
|
|
# profile.
|
|
|
|
self.assertNotEqual("/bin:/usr/bin", user_path)
|
|
|
|
|
2021-01-30 09:03:57 +00:00
|
|
|
@pytest.mark.destructive_test
|
2021-02-02 18:36:14 +00:00
|
|
|
@pytest.mark.skip_if_not_root
|
2021-02-12 17:43:28 -07:00
|
|
|
@pytest.mark.skip_unless_on_darwin(reason="Applicable to MacOS only")
|
2021-01-31 08:57:48 +00:00
|
|
|
@pytest.mark.slow_test
|
2019-08-01 11:25:35 +01:00
|
|
|
def test_runas_complex_command_bad_cwd(self):
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2019-08-01 11:25:35 +01:00
|
|
|
cmd.run should not accidentally run parts of a complex command when
|
|
|
|
given a cwd which cannot be used by the user the command is run as.
|
|
|
|
|
|
|
|
Due to the need to use `su -l` to login to another user on MacOS, we
|
|
|
|
cannot cd into directories that the target user themselves does not
|
|
|
|
have execute permission for. To an extent, this test is testing that
|
|
|
|
buggy behaviour, but its purpose is to ensure that the greater bug of
|
|
|
|
running commands after failing to cd does not occur.
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2018-12-07 17:52:49 +00:00
|
|
|
tmp_cwd = tempfile.mkdtemp(dir=RUNTIME_VARS.TMP)
|
2019-08-01 11:25:35 +01:00
|
|
|
os.chmod(tmp_cwd, 0o700)
|
|
|
|
|
|
|
|
with self._ensure_user_exists(self.runas_usr):
|
|
|
|
cmd_result = self.run_function(
|
|
|
|
"cmd.run_all",
|
|
|
|
['pwd; pwd; : $(echo "You have failed the test" >&2)'],
|
|
|
|
cwd=tmp_cwd,
|
|
|
|
runas=self.runas_usr,
|
|
|
|
)
|
2020-04-02 20:10:20 -05:00
|
|
|
|
2019-08-01 11:25:35 +01:00
|
|
|
self.assertEqual("", cmd_result["stdout"])
|
|
|
|
self.assertNotIn("You have failed the test", cmd_result["stderr"])
|
|
|
|
self.assertNotEqual(0, cmd_result["retcode"])
|
2020-04-02 20:10:20 -05:00
|
|
|
|
2022-02-22 11:47:29 +00:00
|
|
|
@SKIP_INITIAL_PHOTONOS_FAILURES
|
|
|
|
@pytest.mark.skip_on_windows
|
2021-02-02 18:36:14 +00:00
|
|
|
@pytest.mark.skip_if_not_root
|
2021-01-30 09:03:57 +00:00
|
|
|
@pytest.mark.destructive_test
|
2021-01-31 08:57:48 +00:00
|
|
|
@pytest.mark.slow_test
|
2018-03-30 13:12:02 -05:00
|
|
|
def test_runas(self):
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2018-03-30 13:12:02 -05:00
|
|
|
Ensure that the env is the runas user's
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2019-08-01 11:07:51 +01:00
|
|
|
with self._ensure_user_exists(self.runas_usr):
|
|
|
|
out = self.run_function(
|
2025-01-01 15:03:04 -07:00
|
|
|
"cmd.run", ["env"], runas=self.runas_usr, cwd="/tmp"
|
2019-08-01 11:07:51 +01:00
|
|
|
).splitlines()
|
2024-02-27 11:08:46 +00:00
|
|
|
self.assertIn(f"USER={self.runas_usr}", out)
|
2018-03-30 13:12:02 -05:00
|
|
|
|
2021-05-05 16:21:56 +01:00
|
|
|
@pytest.mark.skip_if_binaries_missing("sleep", reason="sleep cmd not installed")
|
2013-06-11 11:41:01 -07:00
|
|
|
def test_timeout(self):
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2013-06-11 11:41:01 -07:00
|
|
|
cmd.run trigger timeout
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2017-02-25 20:11:06 -06:00
|
|
|
out = self.run_function(
|
|
|
|
"cmd.run", ["sleep 2 && echo hello"], f_timeout=1, python_shell=True
|
|
|
|
)
|
|
|
|
self.assertTrue("Timed out" in out)
|
2013-06-11 11:41:01 -07:00
|
|
|
|
2021-05-05 16:21:56 +01:00
|
|
|
@pytest.mark.skip_if_binaries_missing("sleep", reason="sleep cmd not installed")
|
2013-06-11 11:41:01 -07:00
|
|
|
def test_timeout_success(self):
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2013-06-11 11:41:01 -07:00
|
|
|
cmd.run sufficient timeout to succeed
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2017-02-25 20:11:06 -06:00
|
|
|
out = self.run_function(
|
|
|
|
"cmd.run", ["sleep 1 && echo hello"], f_timeout=2, python_shell=True
|
|
|
|
)
|
|
|
|
self.assertEqual(out, "hello")
|
2017-12-05 16:07:30 -06:00
|
|
|
|
2021-01-31 08:57:48 +00:00
|
|
|
@pytest.mark.slow_test
|
2017-12-05 16:07:30 -06:00
|
|
|
def test_hide_output(self):
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2017-12-05 16:07:30 -06:00
|
|
|
Test the hide_output argument
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
Update file state/execution modules and associated files with unicode_literals
This updates the file state and execution modules to use
unicode_literals. Since the serializers and the cmd module are touched
by the file state/exec module, those are also updated here, as well as
the cmd state module, for good measure.
Additionally, I found that salt.utils.data.decode_dict (and decode_list)
are misnamed for what they actually do. Since they *encode* the
contents, the functions should be named encode_dict and encode_list,
respectively. And we also should have counterparts which actually
decode, so I've added them. The compatibility functions from salt.utils
still use the old "decode" names to preserve backward compatibility, but
they now invoke the renamed "encode" functions in salt.utils.data. Note
that this means that the compatibility functions
salt.utils.decode_dict/list, and their cognates in salt.utils.data now
do different things, but since the move to salt.utils.data is also
happening in the Oxygen release this is as good a time as any to correct
this oversight.
I've updated the jinja filter docs to include information on the renamed
jinja filters, and also added a section on jinja filter renaming to the
Oxygen release notes. There was another filter that I renamed during the
process of moving functions from salt.utils which I did not properly
document in the release notes, so this is now included along with the
others.
2017-12-12 10:30:33 -06:00
|
|
|
ls_command = (
|
2017-12-05 16:07:30 -06:00
|
|
|
["ls", "/"] if not salt.utils.platform.is_windows() else ["dir", "c:\\"]
|
2020-04-02 20:10:20 -05:00
|
|
|
)
|
2017-12-05 16:07:30 -06:00
|
|
|
|
|
|
|
error_command = ["thiscommanddoesnotexist"]
|
|
|
|
|
|
|
|
# cmd.run
|
|
|
|
out = self.run_function("cmd.run", ls_command, hide_output=True)
|
Update file state/execution modules and associated files with unicode_literals
This updates the file state and execution modules to use
unicode_literals. Since the serializers and the cmd module are touched
by the file state/exec module, those are also updated here, as well as
the cmd state module, for good measure.
Additionally, I found that salt.utils.data.decode_dict (and decode_list)
are misnamed for what they actually do. Since they *encode* the
contents, the functions should be named encode_dict and encode_list,
respectively. And we also should have counterparts which actually
decode, so I've added them. The compatibility functions from salt.utils
still use the old "decode" names to preserve backward compatibility, but
they now invoke the renamed "encode" functions in salt.utils.data. Note
that this means that the compatibility functions
salt.utils.decode_dict/list, and their cognates in salt.utils.data now
do different things, but since the move to salt.utils.data is also
happening in the Oxygen release this is as good a time as any to correct
this oversight.
I've updated the jinja filter docs to include information on the renamed
jinja filters, and also added a section on jinja filter renaming to the
Oxygen release notes. There was another filter that I renamed during the
process of moving functions from salt.utils which I did not properly
document in the release notes, so this is now included along with the
others.
2017-12-12 10:30:33 -06:00
|
|
|
self.assertEqual(out, "")
|
2017-12-05 16:07:30 -06:00
|
|
|
|
|
|
|
# cmd.shell
|
|
|
|
out = self.run_function("cmd.shell", ls_command, hide_output=True)
|
Update file state/execution modules and associated files with unicode_literals
This updates the file state and execution modules to use
unicode_literals. Since the serializers and the cmd module are touched
by the file state/exec module, those are also updated here, as well as
the cmd state module, for good measure.
Additionally, I found that salt.utils.data.decode_dict (and decode_list)
are misnamed for what they actually do. Since they *encode* the
contents, the functions should be named encode_dict and encode_list,
respectively. And we also should have counterparts which actually
decode, so I've added them. The compatibility functions from salt.utils
still use the old "decode" names to preserve backward compatibility, but
they now invoke the renamed "encode" functions in salt.utils.data. Note
that this means that the compatibility functions
salt.utils.decode_dict/list, and their cognates in salt.utils.data now
do different things, but since the move to salt.utils.data is also
happening in the Oxygen release this is as good a time as any to correct
this oversight.
I've updated the jinja filter docs to include information on the renamed
jinja filters, and also added a section on jinja filter renaming to the
Oxygen release notes. There was another filter that I renamed during the
process of moving functions from salt.utils which I did not properly
document in the release notes, so this is now included along with the
others.
2017-12-12 10:30:33 -06:00
|
|
|
self.assertEqual(out, "")
|
2017-12-05 16:07:30 -06:00
|
|
|
|
|
|
|
# cmd.run_stdout
|
|
|
|
out = self.run_function("cmd.run_stdout", ls_command, hide_output=True)
|
Update file state/execution modules and associated files with unicode_literals
This updates the file state and execution modules to use
unicode_literals. Since the serializers and the cmd module are touched
by the file state/exec module, those are also updated here, as well as
the cmd state module, for good measure.
Additionally, I found that salt.utils.data.decode_dict (and decode_list)
are misnamed for what they actually do. Since they *encode* the
contents, the functions should be named encode_dict and encode_list,
respectively. And we also should have counterparts which actually
decode, so I've added them. The compatibility functions from salt.utils
still use the old "decode" names to preserve backward compatibility, but
they now invoke the renamed "encode" functions in salt.utils.data. Note
that this means that the compatibility functions
salt.utils.decode_dict/list, and their cognates in salt.utils.data now
do different things, but since the move to salt.utils.data is also
happening in the Oxygen release this is as good a time as any to correct
this oversight.
I've updated the jinja filter docs to include information on the renamed
jinja filters, and also added a section on jinja filter renaming to the
Oxygen release notes. There was another filter that I renamed during the
process of moving functions from salt.utils which I did not properly
document in the release notes, so this is now included along with the
others.
2017-12-12 10:30:33 -06:00
|
|
|
self.assertEqual(out, "")
|
2017-12-05 16:07:30 -06:00
|
|
|
|
|
|
|
# cmd.run_stderr
|
|
|
|
out = self.run_function("cmd.shell", error_command, hide_output=True)
|
Update file state/execution modules and associated files with unicode_literals
This updates the file state and execution modules to use
unicode_literals. Since the serializers and the cmd module are touched
by the file state/exec module, those are also updated here, as well as
the cmd state module, for good measure.
Additionally, I found that salt.utils.data.decode_dict (and decode_list)
are misnamed for what they actually do. Since they *encode* the
contents, the functions should be named encode_dict and encode_list,
respectively. And we also should have counterparts which actually
decode, so I've added them. The compatibility functions from salt.utils
still use the old "decode" names to preserve backward compatibility, but
they now invoke the renamed "encode" functions in salt.utils.data. Note
that this means that the compatibility functions
salt.utils.decode_dict/list, and their cognates in salt.utils.data now
do different things, but since the move to salt.utils.data is also
happening in the Oxygen release this is as good a time as any to correct
this oversight.
I've updated the jinja filter docs to include information on the renamed
jinja filters, and also added a section on jinja filter renaming to the
Oxygen release notes. There was another filter that I renamed during the
process of moving functions from salt.utils which I did not properly
document in the release notes, so this is now included along with the
others.
2017-12-12 10:30:33 -06:00
|
|
|
self.assertEqual(out, "")
|
2017-12-05 16:07:30 -06:00
|
|
|
|
|
|
|
# cmd.run_all (command should have produced stdout)
|
|
|
|
out = self.run_function("cmd.run_all", ls_command, hide_output=True)
|
Update file state/execution modules and associated files with unicode_literals
This updates the file state and execution modules to use
unicode_literals. Since the serializers and the cmd module are touched
by the file state/exec module, those are also updated here, as well as
the cmd state module, for good measure.
Additionally, I found that salt.utils.data.decode_dict (and decode_list)
are misnamed for what they actually do. Since they *encode* the
contents, the functions should be named encode_dict and encode_list,
respectively. And we also should have counterparts which actually
decode, so I've added them. The compatibility functions from salt.utils
still use the old "decode" names to preserve backward compatibility, but
they now invoke the renamed "encode" functions in salt.utils.data. Note
that this means that the compatibility functions
salt.utils.decode_dict/list, and their cognates in salt.utils.data now
do different things, but since the move to salt.utils.data is also
happening in the Oxygen release this is as good a time as any to correct
this oversight.
I've updated the jinja filter docs to include information on the renamed
jinja filters, and also added a section on jinja filter renaming to the
Oxygen release notes. There was another filter that I renamed during the
process of moving functions from salt.utils which I did not properly
document in the release notes, so this is now included along with the
others.
2017-12-12 10:30:33 -06:00
|
|
|
self.assertEqual(out["stdout"], "")
|
|
|
|
self.assertEqual(out["stderr"], "")
|
2017-12-05 16:07:30 -06:00
|
|
|
|
|
|
|
# cmd.run_all (command should have produced stderr)
|
|
|
|
out = self.run_function("cmd.run_all", error_command, hide_output=True)
|
Update file state/execution modules and associated files with unicode_literals
This updates the file state and execution modules to use
unicode_literals. Since the serializers and the cmd module are touched
by the file state/exec module, those are also updated here, as well as
the cmd state module, for good measure.
Additionally, I found that salt.utils.data.decode_dict (and decode_list)
are misnamed for what they actually do. Since they *encode* the
contents, the functions should be named encode_dict and encode_list,
respectively. And we also should have counterparts which actually
decode, so I've added them. The compatibility functions from salt.utils
still use the old "decode" names to preserve backward compatibility, but
they now invoke the renamed "encode" functions in salt.utils.data. Note
that this means that the compatibility functions
salt.utils.decode_dict/list, and their cognates in salt.utils.data now
do different things, but since the move to salt.utils.data is also
happening in the Oxygen release this is as good a time as any to correct
this oversight.
I've updated the jinja filter docs to include information on the renamed
jinja filters, and also added a section on jinja filter renaming to the
Oxygen release notes. There was another filter that I renamed during the
process of moving functions from salt.utils which I did not properly
document in the release notes, so this is now included along with the
others.
2017-12-12 10:30:33 -06:00
|
|
|
self.assertEqual(out["stdout"], "")
|
|
|
|
self.assertEqual(out["stderr"], "")
|
2018-06-01 14:54:12 -04:00
|
|
|
|
2021-01-31 08:57:48 +00:00
|
|
|
@pytest.mark.slow_test
|
2018-05-29 21:51:02 +00:00
|
|
|
def test_cmd_run_whoami(self):
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2018-05-29 21:51:02 +00:00
|
|
|
test return of whoami
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2020-05-18 17:03:53 +01:00
|
|
|
if not salt.utils.platform.is_windows():
|
|
|
|
user = RUNTIME_VARS.RUNTIME_CONFIGS["master"]["user"]
|
2018-05-29 21:51:02 +00:00
|
|
|
else:
|
2020-05-18 17:03:53 +01:00
|
|
|
user = salt.utils.user.get_specific_user()
|
2020-05-24 09:03:26 +01:00
|
|
|
if user.startswith("sudo_"):
|
|
|
|
user = user.replace("sudo_", "")
|
2020-05-18 17:03:53 +01:00
|
|
|
cmd = self.run_function("cmd.run", ["whoami"])
|
2022-11-03 17:28:06 +00:00
|
|
|
try:
|
|
|
|
self.assertEqual(user.lower(), cmd.lower())
|
|
|
|
except AssertionError as exc:
|
|
|
|
if not salt.utils.platform.is_windows():
|
|
|
|
raise exc from None
|
|
|
|
if "\\" in user:
|
|
|
|
user = user.split("\\")[-1]
|
|
|
|
self.assertEqual(user.lower(), cmd.lower())
|
2019-04-10 09:39:32 -04:00
|
|
|
|
2021-02-12 17:43:28 -07:00
|
|
|
@pytest.mark.skip_unless_on_windows(reason="Minion is not Windows")
|
2021-01-31 08:57:48 +00:00
|
|
|
@pytest.mark.slow_test
|
2019-04-10 09:39:32 -04:00
|
|
|
def test_windows_env_handling(self):
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2019-04-10 09:39:32 -04:00
|
|
|
Ensure that nt.environ is used properly with cmd.run*
|
2020-04-02 20:10:20 -05:00
|
|
|
"""
|
2019-04-10 09:39:32 -04:00
|
|
|
out = self.run_function(
|
|
|
|
"cmd.run", ["set"], env={"abc": "123", "ABC": "456"}
|
|
|
|
).splitlines()
|
|
|
|
self.assertIn("abc=123", out)
|
|
|
|
self.assertIn("ABC=456", out)
|