Switch to pytest-salt-factories

This commit is contained in:
Pedro Algarvio 2020-05-07 19:10:55 +01:00 committed by Daniel Wozniak
parent c58707e0de
commit e157459016
25 changed files with 517 additions and 1349 deletions

View file

@ -682,8 +682,9 @@ allowed-3rd-party-modules=msgpack,
libcloud,
zmq,
pytest,
setuptools,
pytestsalt,
setuptools
saltfactories
[EXCEPTIONS]

View file

@ -680,6 +680,9 @@ def pytest_parametrized(session, coverage, transport, crypto):
# Install requirements
_install_requirements(session, transport)
session.run(
"pip", "uninstall", "-y", "pytest-salt", silent=True,
)
if crypto:
session.run(
"pip",

View file

@ -1,7 +1,8 @@
mock >= 3.0.0
# PyTest
pytest >=4.6.9,<4.7 # PyTest 4.6.x are the last Py2 and Py3 releases
pytest-salt >= 2020.1.27
pytest-salt
pytest-salt-factories >= 0.10.0
pytest-tempdir >= 2019.10.12
pytest-helpers-namespace >= 2019.1.8
pytest-salt-runtests-bridge >= 2019.12.5

View file

@ -88,6 +88,7 @@ pyopenssl==19.0.0
pyparsing==2.4.5 # via junos-eznc, packaging
pyserial==3.4 # via junos-eznc
pytest-helpers-namespace==2019.1.8
pytest-salt-factories==0.10.4
pytest-salt-runtests-bridge==2019.12.5
pytest-salt==2020.1.27
pytest-tempdir==2019.10.12
@ -108,7 +109,7 @@ s3transfer==0.2.0 # via boto3
salttesting==2017.6.1
scp==0.13.2 # via junos-eznc
setproctitle==1.1.10
six==1.12.0 # via bcrypt, cheroot, cherrypy, cryptography, docker, docker-pycreds, google-auth, junos-eznc, kubernetes, mock, more-itertools, moto, ncclient, packaging, pathlib2, pynacl, pyopenssl, pytest, python-dateutil, python-jose, pyvmomi, responses, salttesting, tempora, textfsm, transitions, vcert, virtualenv, websocket-client
six==1.12.0 # via bcrypt, cheroot, cherrypy, cryptography, docker, docker-pycreds, google-auth, junos-eznc, kubernetes, mock, more-itertools, moto, ncclient, packaging, pathlib2, pynacl, pyopenssl, pytest, pytest-salt-factories, python-dateutil, python-jose, pyvmomi, responses, salttesting, tempora, textfsm, transitions, vcert, virtualenv, websocket-client
smmap2==2.0.5 # via gitdb2
strict-rfc3339==0.7
tempora==1.14.1 # via portend

View file

@ -84,6 +84,7 @@ pyopenssl==19.0.0
pyparsing==2.4.5 # via junos-eznc, packaging
pyserial==3.4 # via junos-eznc
pytest-helpers-namespace==2019.1.8
pytest-salt-factories==0.10.4
pytest-salt-runtests-bridge==2019.12.5
pytest-salt==2020.1.27
pytest-tempdir==2019.10.12
@ -105,7 +106,7 @@ salttesting==2017.6.1
scp==0.13.2 # via junos-eznc
setproctitle==1.1.10
setuptools-scm==3.2.0
six==1.12.0 # via bcrypt, cheroot, cherrypy, cryptography, docker, docker-pycreds, google-auth, junos-eznc, kazoo, kubernetes, mock, more-itertools, moto, ncclient, packaging, pathlib2, pygit2, pynacl, pyopenssl, pytest, python-dateutil, python-jose, pyvmomi, responses, salttesting, tempora, textfsm, transitions, vcert, websocket-client
six==1.12.0 # via bcrypt, cheroot, cherrypy, cryptography, docker, docker-pycreds, google-auth, junos-eznc, kazoo, kubernetes, mock, more-itertools, moto, ncclient, packaging, pathlib2, pygit2, pynacl, pyopenssl, pytest, pytest-salt-factories, python-dateutil, python-jose, pyvmomi, responses, salttesting, tempora, textfsm, transitions, vcert, websocket-client
smmap2==2.0.5 # via gitdb2
strict-rfc3339==0.7
tempora==1.14.1 # via portend

View file

@ -78,6 +78,7 @@ pymysql==0.9.3
pyopenssl==19.0.0
pyparsing==2.4.5 # via packaging
pytest-helpers-namespace==2019.1.8
pytest-salt-factories==0.10.4
pytest-salt-runtests-bridge==2019.12.5
pytest-salt==2020.1.27
pytest-tempdir==2019.10.12
@ -100,7 +101,7 @@ s3transfer==0.2.0 # via boto3
salttesting==2017.6.1
sed==0.3.1
setproctitle==1.1.10
six==1.12.0 # via cheroot, cherrypy, cryptography, docker, docker-pycreds, google-auth, kubernetes, mock, more-itertools, moto, packaging, pathlib2, pygit2, pyopenssl, pytest, python-dateutil, python-jose, pyvmomi, responses, salttesting, tempora, websocket-client
six==1.12.0 # via cheroot, cherrypy, cryptography, docker, docker-pycreds, google-auth, kubernetes, mock, more-itertools, moto, packaging, pathlib2, pygit2, pyopenssl, pytest, pytest-salt-factories, python-dateutil, python-jose, pyvmomi, responses, salttesting, tempora, websocket-client
smmap2==2.0.5
strict-rfc3339==0.7
tempora==1.14.1 # via portend

View file

@ -87,6 +87,7 @@ pyopenssl==19.0.0
pyparsing==2.4.5 # via junos-eznc, packaging
pyserial==3.4 # via junos-eznc
pytest-helpers-namespace==2019.1.8
pytest-salt-factories==0.10.4
pytest-salt-runtests-bridge==2019.12.5
pytest-salt==2020.1.27
pytest-tempdir==2019.10.12
@ -107,7 +108,7 @@ s3transfer==0.2.0 # via boto3
salttesting==2017.6.1
scp==0.13.2 # via junos-eznc
setproctitle==1.1.10
six==1.12.0 # via bcrypt, cheroot, cherrypy, cryptography, docker, docker-pycreds, google-auth, junos-eznc, kubernetes, mock, more-itertools, moto, ncclient, packaging, pynacl, pyopenssl, pytest, python-dateutil, python-jose, pyvmomi, responses, salttesting, tempora, textfsm, transitions, vcert, virtualenv, websocket-client
six==1.12.0 # via bcrypt, cheroot, cherrypy, cryptography, docker, docker-pycreds, google-auth, junos-eznc, kubernetes, mock, more-itertools, moto, ncclient, packaging, pynacl, pyopenssl, pytest, pytest-salt-factories, python-dateutil, python-jose, pyvmomi, responses, salttesting, tempora, textfsm, transitions, vcert, virtualenv, websocket-client
smmap2==2.0.5 # via gitdb2
strict-rfc3339==0.7
tempora==1.14.1 # via portend

View file

@ -83,6 +83,7 @@ pyopenssl==19.0.0
pyparsing==2.4.5 # via junos-eznc, packaging
pyserial==3.4 # via junos-eznc
pytest-helpers-namespace==2019.1.8
pytest-salt-factories==0.10.4
pytest-salt-runtests-bridge==2019.12.5
pytest-salt==2020.1.27
pytest-tempdir==2019.10.12
@ -104,7 +105,7 @@ salttesting==2017.6.1
scp==0.13.2 # via junos-eznc
setproctitle==1.1.10
setuptools-scm==3.2.0
six==1.12.0 # via bcrypt, cheroot, cherrypy, cryptography, docker, docker-pycreds, google-auth, junos-eznc, kazoo, kubernetes, mock, more-itertools, moto, ncclient, packaging, pygit2, pynacl, pyopenssl, pytest, python-dateutil, python-jose, pyvmomi, responses, salttesting, tempora, textfsm, transitions, vcert, websocket-client
six==1.12.0 # via bcrypt, cheroot, cherrypy, cryptography, docker, docker-pycreds, google-auth, junos-eznc, kazoo, kubernetes, mock, more-itertools, moto, ncclient, packaging, pygit2, pynacl, pyopenssl, pytest, pytest-salt-factories, python-dateutil, python-jose, pyvmomi, responses, salttesting, tempora, textfsm, transitions, vcert, websocket-client
smmap2==2.0.5 # via gitdb2
strict-rfc3339==0.7
tempora==1.14.1 # via portend

View file

@ -77,6 +77,7 @@ pymysql==0.9.3
pyopenssl==19.0.0
pyparsing==2.4.5 # via packaging
pytest-helpers-namespace==2019.1.8
pytest-salt-factories==0.10.4
pytest-salt-runtests-bridge==2019.12.5
pytest-salt==2020.1.27
pytest-tempdir==2019.10.12
@ -99,7 +100,7 @@ s3transfer==0.2.0 # via boto3
salttesting==2017.6.1
sed==0.3.1
setproctitle==1.1.10
six==1.12.0 # via cheroot, cherrypy, cryptography, docker, docker-pycreds, google-auth, kubernetes, mock, more-itertools, moto, packaging, pygit2, pyopenssl, pytest, python-dateutil, python-jose, pyvmomi, responses, salttesting, tempora, websocket-client
six==1.12.0 # via cheroot, cherrypy, cryptography, docker, docker-pycreds, google-auth, kubernetes, mock, more-itertools, moto, packaging, pygit2, pyopenssl, pytest, pytest-salt-factories, python-dateutil, python-jose, pyvmomi, responses, salttesting, tempora, websocket-client
smmap2==2.0.5
strict-rfc3339==0.7
tempora==1.14.1 # via portend

View file

@ -86,6 +86,7 @@ pyopenssl==19.0.0
pyparsing==2.4.5 # via junos-eznc, packaging
pyserial==3.4 # via junos-eznc
pytest-helpers-namespace==2019.1.8
pytest-salt-factories==0.10.4
pytest-salt-runtests-bridge==2019.12.5
pytest-salt==2020.1.27
pytest-tempdir==2019.10.12
@ -106,7 +107,7 @@ s3transfer==0.2.0 # via boto3
salttesting==2017.6.1
scp==0.13.2 # via junos-eznc
setproctitle==1.1.10
six==1.12.0 # via bcrypt, cheroot, cherrypy, cryptography, docker, docker-pycreds, google-auth, junos-eznc, kubernetes, mock, more-itertools, moto, ncclient, packaging, pynacl, pyopenssl, pytest, python-dateutil, python-jose, pyvmomi, responses, salttesting, tempora, textfsm, transitions, vcert, virtualenv, websocket-client
six==1.12.0 # via bcrypt, cheroot, cherrypy, cryptography, docker, docker-pycreds, google-auth, junos-eznc, kubernetes, mock, more-itertools, moto, ncclient, packaging, pynacl, pyopenssl, pytest, pytest-salt-factories, python-dateutil, python-jose, pyvmomi, responses, salttesting, tempora, textfsm, transitions, vcert, virtualenv, websocket-client
smmap2==2.0.5 # via gitdb2
strict-rfc3339==0.7
tempora==1.14.1 # via portend

View file

@ -83,6 +83,7 @@ pyopenssl==19.0.0
pyparsing==2.4.5 # via junos-eznc, packaging
pyserial==3.4 # via junos-eznc
pytest-helpers-namespace==2019.1.8
pytest-salt-factories==0.10.4
pytest-salt-runtests-bridge==2019.12.5
pytest-salt==2020.1.27
pytest-tempdir==2019.10.12
@ -104,7 +105,7 @@ salttesting==2017.6.1
scp==0.13.2 # via junos-eznc
setproctitle==1.1.10
setuptools-scm==3.2.0
six==1.12.0 # via bcrypt, cheroot, cherrypy, cryptography, docker, docker-pycreds, google-auth, junos-eznc, kazoo, kubernetes, mock, more-itertools, moto, ncclient, packaging, pygit2, pynacl, pyopenssl, pytest, python-dateutil, python-jose, pyvmomi, responses, salttesting, tempora, textfsm, transitions, vcert, websocket-client
six==1.12.0 # via bcrypt, cheroot, cherrypy, cryptography, docker, docker-pycreds, google-auth, junos-eznc, kazoo, kubernetes, mock, more-itertools, moto, ncclient, packaging, pygit2, pynacl, pyopenssl, pytest, pytest-salt-factories, python-dateutil, python-jose, pyvmomi, responses, salttesting, tempora, textfsm, transitions, vcert, websocket-client
smmap2==2.0.5 # via gitdb2
strict-rfc3339==0.7
tempora==1.14.1 # via portend

View file

@ -76,6 +76,7 @@ pymysql==0.9.3
pyopenssl==19.0.0
pyparsing==2.4.5 # via packaging
pytest-helpers-namespace==2019.1.8
pytest-salt-factories==0.10.4
pytest-salt-runtests-bridge==2019.12.5
pytest-salt==2020.1.27
pytest-tempdir==2019.10.12
@ -98,7 +99,7 @@ s3transfer==0.2.0 # via boto3
salttesting==2017.6.1
sed==0.3.1
setproctitle==1.1.10
six==1.12.0 # via cheroot, cherrypy, cryptography, docker, docker-pycreds, google-auth, kubernetes, mock, more-itertools, moto, packaging, pygit2, pyopenssl, pytest, python-dateutil, python-jose, pyvmomi, responses, salttesting, tempora, websocket-client
six==1.12.0 # via cheroot, cherrypy, cryptography, docker, docker-pycreds, google-auth, kubernetes, mock, more-itertools, moto, packaging, pygit2, pyopenssl, pytest, pytest-salt-factories, python-dateutil, python-jose, pyvmomi, responses, salttesting, tempora, websocket-client
smmap2==2.0.5
strict-rfc3339==0.7
tempora==1.14.1 # via portend

View file

@ -85,6 +85,7 @@ pyopenssl==19.0.0
pyparsing==2.4.5 # via junos-eznc, packaging
pyserial==3.4 # via junos-eznc
pytest-helpers-namespace==2019.1.8
pytest-salt-factories==0.10.4
pytest-salt-runtests-bridge==2019.12.5
pytest-salt==2020.1.27
pytest-tempdir==2019.10.12
@ -105,7 +106,7 @@ s3transfer==0.2.0 # via boto3
salttesting==2017.6.1
scp==0.13.2 # via junos-eznc
setproctitle==1.1.10
six==1.12.0 # via bcrypt, cheroot, cherrypy, cryptography, docker, docker-pycreds, google-auth, junos-eznc, kubernetes, mock, more-itertools, moto, ncclient, packaging, pynacl, pyopenssl, pytest, python-dateutil, python-jose, pyvmomi, responses, salttesting, tempora, textfsm, transitions, vcert, virtualenv, websocket-client
six==1.12.0 # via bcrypt, cheroot, cherrypy, cryptography, docker, docker-pycreds, google-auth, junos-eznc, kubernetes, mock, more-itertools, moto, ncclient, packaging, pynacl, pyopenssl, pytest, pytest-salt-factories, python-dateutil, python-jose, pyvmomi, responses, salttesting, tempora, textfsm, transitions, vcert, virtualenv, websocket-client
smmap2==2.0.5 # via gitdb2
strict-rfc3339==0.7
tempora==1.14.1 # via portend

View file

@ -83,6 +83,7 @@ pyopenssl==19.0.0
pyparsing==2.4.5 # via junos-eznc, packaging
pyserial==3.4 # via junos-eznc
pytest-helpers-namespace==2019.1.8
pytest-salt-factories==0.10.4
pytest-salt-runtests-bridge==2019.12.5
pytest-salt==2020.1.27
pytest-tempdir==2019.10.12
@ -104,7 +105,7 @@ salttesting==2017.6.1
scp==0.13.2 # via junos-eznc
setproctitle==1.1.10
setuptools-scm==3.2.0
six==1.12.0 # via bcrypt, cheroot, cherrypy, cryptography, docker, docker-pycreds, google-auth, junos-eznc, kazoo, kubernetes, mock, more-itertools, moto, ncclient, packaging, pynacl, pyopenssl, pytest, python-dateutil, python-jose, pyvmomi, responses, salttesting, tempora, textfsm, transitions, vcert, websocket-client
six==1.12.0 # via bcrypt, cheroot, cherrypy, cryptography, docker, docker-pycreds, google-auth, junos-eznc, kazoo, kubernetes, mock, more-itertools, moto, ncclient, packaging, pynacl, pyopenssl, pytest, pytest-salt-factories, python-dateutil, python-jose, pyvmomi, responses, salttesting, tempora, textfsm, transitions, vcert, websocket-client
smmap2==2.0.5 # via gitdb2
strict-rfc3339==0.7
tempora==1.14.1 # via portend

View file

@ -85,6 +85,7 @@ pyopenssl==19.0.0
pyparsing==2.4.5 # via junos-eznc, packaging
pyserial==3.4 # via junos-eznc
pytest-helpers-namespace==2019.1.8
pytest-salt-factories==0.10.4
pytest-salt-runtests-bridge==2019.12.5
pytest-salt==2020.1.27
pytest-tempdir==2019.10.12
@ -105,7 +106,7 @@ s3transfer==0.2.0 # via boto3
salttesting==2017.6.1
scp==0.13.2 # via junos-eznc
setproctitle==1.1.10
six==1.12.0 # via bcrypt, cheroot, cherrypy, cryptography, docker, docker-pycreds, google-auth, junos-eznc, kubernetes, mock, more-itertools, moto, ncclient, packaging, pynacl, pyopenssl, pytest, python-dateutil, python-jose, pyvmomi, responses, salttesting, tempora, textfsm, transitions, vcert, virtualenv, websocket-client
six==1.12.0 # via bcrypt, cheroot, cherrypy, cryptography, docker, docker-pycreds, google-auth, junos-eznc, kubernetes, mock, more-itertools, moto, ncclient, packaging, pynacl, pyopenssl, pytest, pytest-salt-factories, python-dateutil, python-jose, pyvmomi, responses, salttesting, tempora, textfsm, transitions, vcert, virtualenv, websocket-client
smmap2==2.0.5 # via gitdb2
strict-rfc3339==0.7
tempora==1.14.1 # via portend

View file

@ -83,6 +83,7 @@ pyopenssl==19.0.0
pyparsing==2.4.5 # via junos-eznc, packaging
pyserial==3.4 # via junos-eznc
pytest-helpers-namespace==2019.1.8
pytest-salt-factories==0.10.4
pytest-salt-runtests-bridge==2019.12.5
pytest-salt==2020.1.27
pytest-tempdir==2019.10.12
@ -104,7 +105,7 @@ salttesting==2017.6.1
scp==0.13.2 # via junos-eznc
setproctitle==1.1.10
setuptools-scm==3.2.0
six==1.12.0 # via bcrypt, cheroot, cherrypy, cryptography, docker, docker-pycreds, google-auth, junos-eznc, kazoo, kubernetes, mock, more-itertools, moto, ncclient, packaging, pynacl, pyopenssl, pytest, python-dateutil, python-jose, pyvmomi, responses, salttesting, tempora, textfsm, transitions, vcert, websocket-client
six==1.12.0 # via bcrypt, cheroot, cherrypy, cryptography, docker, docker-pycreds, google-auth, junos-eznc, kazoo, kubernetes, mock, more-itertools, moto, ncclient, packaging, pynacl, pyopenssl, pytest, pytest-salt-factories, python-dateutil, python-jose, pyvmomi, responses, salttesting, tempora, textfsm, transitions, vcert, websocket-client
smmap2==2.0.5 # via gitdb2
strict-rfc3339==0.7
tempora==1.14.1 # via portend

View file

@ -37,7 +37,6 @@ import salt.utils.path
import salt.utils.platform
import salt.utils.win_functions
from _pytest.mark.evaluate import MarkEvaluator
from pytestsalt.utils import cli_scripts
from salt.ext import six
from salt.serializers import yaml
from salt.utils.immutabletypes import freeze
@ -56,7 +55,6 @@ if CODE_DIR in sys.path:
sys.path.remove(CODE_DIR)
sys.path.insert(0, CODE_DIR)
# Coverage
if "COVERAGE_PROCESS_START" in os.environ:
MAYBE_RUN_COVERAGE = True
@ -116,18 +114,6 @@ log = logging.getLogger("salt.testsuite")
# ----- PyTest Tempdir Plugin Hooks --------------------------------------------------------------------------------->
def pytest_tempdir_temproot():
# Taken from https://github.com/saltstack/salt/blob/v2019.2.0/tests/support/paths.py
# Avoid ${TMPDIR} and gettempdir() on MacOS as they yield a base path too long
# for unix sockets: ``error: AF_UNIX path too long``
# Gentoo Portage prefers ebuild tests are rooted in ${TMPDIR}
if not sys.platform.startswith("darwin"):
tempdir = os.environ.get("TMPDIR") or tempfile.gettempdir()
else:
tempdir = "/tmp"
return os.path.abspath(os.path.realpath(tempdir))
def pytest_tempdir_basename():
"""
Return the temporary directory basename for the salt test suite.
@ -339,32 +325,6 @@ def pytest_report_header():
return "max open files; soft: {}; hard: {}".format(soft, hard)
def pytest_runtest_logstart(nodeid):
"""
signal the start of running a single test item.
This hook will be called **before** :func:`pytest_runtest_setup`, :func:`pytest_runtest_call` and
:func:`pytest_runtest_teardown` hooks.
:param str nodeid: full id of the item
:param location: a triple of ``(filename, linenum, testname)``
"""
log.debug(">>>>> START >>>>> %s", nodeid)
def pytest_runtest_logfinish(nodeid):
"""
signal the complete finish of running a single test item.
This hook will be called **after** :func:`pytest_runtest_setup`, :func:`pytest_runtest_call` and
:func:`pytest_runtest_teardown` hooks.
:param str nodeid: full id of the item
:param location: a triple of ``(filename, linenum, testname)``
"""
log.debug("<<<<< END <<<<<<< %s", nodeid)
@pytest.hookimpl(hookwrapper=True, trylast=True)
def pytest_collection_modifyitems(config, items):
"""
@ -404,13 +364,17 @@ def pytest_collection_modifyitems(config, items):
return self._finished
except AttributeError:
if self.node_ids:
log.debug(
"%s is still going to be used, not terminating it. "
"Still in use on:\n%s",
self,
pprint.pformat(list(self.node_ids)),
)
return
if (
not request.session.shouldfail
and not request.session.shouldstop
):
log.debug(
"%s is still going to be used, not terminating it. "
"Still in use on:\n%s",
self,
pprint.pformat(list(self.node_ids)),
)
return
log.debug("Finish called on %s", self)
try:
return func(request)
@ -458,7 +422,8 @@ def pytest_runtest_protocol(item, nextitem):
yield
finally:
for fixturedef in used_fixture_defs:
fixturedef.node_ids.remove(item.nodeid)
if item.nodeid in fixturedef.node_ids:
fixturedef.node_ids.remove(item.nodeid)
if not fixturedef.node_ids:
# This fixture is not used in any more test functions
fixturedef.finish(request)
@ -919,301 +884,6 @@ def temp_state_file(name, contents, saltenv="base", strip_first_newline=True):
# ----- Fixtures Overrides ------------------------------------------------------------------------------------------>
# ----- Generate CLI Scripts ---------------------------------------------------------------------------------------->
@pytest.fixture(scope="session")
def cli_master_script_name():
"""
Return the CLI script basename
"""
return "cli_salt_master.py"
@pytest.fixture(scope="session")
def cli_minion_script_name():
"""
Return the CLI script basename
"""
return "cli_salt_minion.py"
@pytest.fixture(scope="session")
def cli_salt_script_name():
"""
Return the CLI script basename
"""
return "cli_salt.py"
@pytest.fixture(scope="session")
def cli_run_script_name():
"""
Return the CLI script basename
"""
return "cli_salt_run.py"
@pytest.fixture(scope="session")
def cli_key_script_name():
"""
Return the CLI script basename
"""
return "cli_salt_key.py"
@pytest.fixture(scope="session")
def cli_call_script_name():
"""
Return the CLI script basename
"""
return "cli_salt_call.py"
@pytest.fixture(scope="session")
def cli_syndic_script_name():
"""
Return the CLI script basename
"""
return "cli_salt_syndic.py"
@pytest.fixture(scope="session")
def cli_ssh_script_name():
"""
Return the CLI script basename
"""
return "cli_salt_ssh.py"
@pytest.fixture(scope="session")
def cli_proxy_script_name():
"""
Return the CLI script basename
"""
return "cli_salt_proxy.py"
@pytest.fixture(scope="session")
def cli_bin_dir(
tempdir,
request,
python_executable_path,
cli_master_script_name,
cli_minion_script_name,
cli_salt_script_name,
cli_call_script_name,
cli_key_script_name,
cli_run_script_name,
cli_ssh_script_name,
cli_syndic_script_name,
cli_proxy_script_name,
):
"""
Return the path to the CLI script directory to use
"""
tmp_cli_scripts_dir = tempdir.join("cli-scrips-bin")
# Make sure we re-write the scripts every time we start the tests
shutil.rmtree(tmp_cli_scripts_dir.strpath, ignore_errors=True)
tmp_cli_scripts_dir.ensure(dir=True)
cli_bin_dir_path = tmp_cli_scripts_dir.strpath
# Now that we have the CLI directory created, lets generate the required CLI scripts to run salt's test suite
for script_name in (
cli_master_script_name,
cli_minion_script_name,
cli_call_script_name,
cli_key_script_name,
cli_run_script_name,
cli_salt_script_name,
cli_ssh_script_name,
cli_syndic_script_name,
cli_proxy_script_name,
):
original_script_name = (
os.path.splitext(script_name)[0].split("cli_")[-1].replace("_", "-")
)
cli_scripts.generate_script(
bin_dir=cli_bin_dir_path,
script_name=original_script_name,
executable=sys.executable,
code_dir=CODE_DIR,
inject_sitecustomize=MAYBE_RUN_COVERAGE,
)
# Return the CLI bin dir value
return cli_bin_dir_path
# <---- Generate CLI Scripts -----------------------------------------------------------------------------------------
# ----- Salt Configuration ------------------------------------------------------------------------------------------>
@pytest.fixture(scope="session")
def session_master_of_masters_id():
"""
Returns the master of masters id
"""
return "syndic_master"
@pytest.fixture(scope="session")
def session_master_id():
"""
Returns the session scoped master id
"""
return "master"
@pytest.fixture(scope="session")
def session_minion_id():
"""
Returns the session scoped minion id
"""
return "minion"
@pytest.fixture(scope="session")
def session_secondary_minion_id():
"""
Returns the session scoped secondary minion id
"""
return "sub_minion"
@pytest.fixture(scope="session")
def session_syndic_id():
"""
Returns the session scoped syndic id
"""
return "syndic"
@pytest.fixture(scope="session")
def session_proxy_id():
"""
Returns the session scoped proxy id
"""
return "proxytest"
@pytest.fixture(scope="session")
def salt_fail_hard():
"""
Return the salt fail hard value
"""
return True
@pytest.fixture(scope="session")
def session_master_default_options(request, session_root_dir):
with salt.utils.files.fopen(os.path.join(RUNTIME_VARS.CONF_DIR, "master")) as rfh:
opts = yaml.deserialize(rfh.read())
tests_known_hosts_file = session_root_dir.join("salt_ssh_known_hosts").strpath
with salt.utils.files.fopen(tests_known_hosts_file, "w") as known_hosts:
known_hosts.write("")
opts["known_hosts_file"] = tests_known_hosts_file
opts["syndic_master"] = "localhost"
opts["transport"] = request.config.getoption("--transport")
# Config settings to test `event_return`
if "returner_dirs" not in opts:
opts["returner_dirs"] = []
opts["returner_dirs"].append(os.path.join(RUNTIME_VARS.FILES, "returners"))
opts["event_return"] = "runtests_noop"
return opts
@pytest.fixture(scope="session")
def session_master_config_overrides(session_root_dir):
ext_pillar = []
if salt.utils.platform.is_windows():
ext_pillar.append(
{
"cmd_yaml": "type {0}".format(
os.path.join(RUNTIME_VARS.FILES, "ext.yaml")
)
}
)
else:
ext_pillar.append(
{"cmd_yaml": "cat {0}".format(os.path.join(RUNTIME_VARS.FILES, "ext.yaml"))}
)
ext_pillar.append(
{
"file_tree": {
"root_dir": os.path.join(RUNTIME_VARS.PILLAR_DIR, "base", "file_tree"),
"follow_dir_links": False,
"keep_newline": True,
}
}
)
# We need to copy the extension modules into the new master root_dir or
# it will be prefixed by it
extension_modules_path = session_root_dir.join("extension_modules").strpath
if not os.path.exists(extension_modules_path):
shutil.copytree(
os.path.join(RUNTIME_VARS.FILES, "extension_modules"),
extension_modules_path,
)
# Copy the autosign_file to the new master root_dir
autosign_file_path = session_root_dir.join("autosign_file").strpath
shutil.copyfile(
os.path.join(RUNTIME_VARS.FILES, "autosign_file"), autosign_file_path
)
# all read, only owner write
autosign_file_permissions = (
stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH | stat.S_IWUSR
)
os.chmod(autosign_file_path, autosign_file_permissions)
pytest_stop_sending_events_file = session_root_dir.join(
"pytest_stop_sending_events_file"
).strpath
with salt.utils.files.fopen(pytest_stop_sending_events_file, "w") as wfh:
wfh.write("")
return {
"pillar_opts": True,
"ext_pillar": ext_pillar,
"extension_modules": extension_modules_path,
"file_roots": {
"base": [os.path.join(RUNTIME_VARS.FILES, "file", "base")],
# Alternate root to test __env__ choices
"prod": [os.path.join(RUNTIME_VARS.FILES, "file", "prod")],
},
"pillar_roots": {"base": [os.path.join(RUNTIME_VARS.FILES, "pillar", "base")]},
"reactor": [
{
"salt/minion/*/start": [
os.path.join(RUNTIME_VARS.FILES, "reactor-sync-minion.sls")
],
},
{
"salt/test/reactor": [
os.path.join(RUNTIME_VARS.FILES, "reactor-test.sls")
],
},
],
"pytest_stop_sending_events_file": pytest_stop_sending_events_file,
}
@pytest.fixture(scope="session")
def session_minion_default_options(request, tempdir):
with salt.utils.files.fopen(os.path.join(RUNTIME_VARS.CONF_DIR, "minion")) as rfh:
opts = yaml.deserialize(rfh.read())
opts["hosts.file"] = tempdir.join("hosts").strpath
opts["aliases.file"] = tempdir.join("aliases").strpath
opts["transport"] = request.config.getoption("--transport")
return opts
def _get_virtualenv_binary_path():
try:
return _get_virtualenv_binary_path.__virtualenv_binary__
@ -1254,75 +924,140 @@ def _get_virtualenv_binary_path():
return virtualenv_binary
@pytest.fixture(scope="session")
def session_minion_config_overrides():
opts = {
"file_roots": {
"base": [os.path.join(RUNTIME_VARS.FILES, "file", "base")],
# Alternate root to test __env__ choices
"prod": [os.path.join(RUNTIME_VARS.FILES, "file", "prod")],
},
"pillar_roots": {"base": [os.path.join(RUNTIME_VARS.FILES, "pillar", "base")]},
}
virtualenv_binary = _get_virtualenv_binary_path()
if virtualenv_binary:
opts["venv_bin"] = virtualenv_binary
return opts
# @pytest.fixture(scope='session')
# def salt_syndic_master_config(request, salt_factories):
# return salt_factories.configure_master(request, 'syndic_master', order_masters=True)
# @pytest.fixture(scope='session')
# def salt_syndic_config(request, salt_factories, salt_syndic_master_config):
# return salt_factories.configure_syndic(request, 'syndic', master_of_masters_id='syndic_master')
# @pytest.fixture(scope='session')
# def salt_master_config(request, salt_factories, salt_syndic_master_config):
# return salt_factories.configure_master(request, 'master', master_of_masters_id='syndic_master')
@pytest.fixture(scope="session")
def session_secondary_minion_default_options(request, tempdir):
with salt.utils.files.fopen(
os.path.join(RUNTIME_VARS.CONF_DIR, "sub_minion")
) as rfh:
opts = yaml.deserialize(rfh.read())
opts["hosts.file"] = tempdir.join("hosts").strpath
opts["aliases.file"] = tempdir.join("aliases").strpath
opts["transport"] = request.config.getoption("--transport")
return opts
def salt_master_config(request, salt_factories):
return salt_factories.configure_master(request, "master")
@pytest.fixture(scope="session")
def session_seconary_minion_config_overrides():
def salt_minion_config(request, salt_factories, salt_master_config):
return salt_factories.configure_minion(request, "minion", master_id="master")
@pytest.fixture(scope="session")
def salt_sub_minion_config(request, salt_factories, salt_master_config):
return salt_factories.configure_minion(request, "sub_minion", master_id="master")
def pytest_saltfactories_generate_default_master_configuration(
request, factories_manager, root_dir, master_id, order_masters
):
"""
Hook which should return a dictionary tailored for the provided master_id
Stops at the first non None result
"""
if master_id == "master":
with salt.utils.files.fopen(
os.path.join(RUNTIME_VARS.CONF_DIR, "master")
) as rfh:
opts = yaml.deserialize(rfh.read())
tests_known_hosts_file = root_dir.join("salt_ssh_known_hosts").strpath
with salt.utils.files.fopen(tests_known_hosts_file, "w") as known_hosts:
known_hosts.write("")
opts["known_hosts_file"] = tests_known_hosts_file
opts["syndic_master"] = "localhost"
opts["transport"] = request.config.getoption("--transport")
# Config settings to test `event_return`
if "returner_dirs" not in opts:
opts["returner_dirs"] = []
opts["returner_dirs"].append(os.path.join(RUNTIME_VARS.FILES, "returners"))
opts["event_return"] = "runtests_noop"
return opts
elif master_id == "syndic_master":
with salt.utils.files.fopen(
os.path.join(RUNTIME_VARS.CONF_DIR, "syndic_master")
) as rfh:
opts = yaml.deserialize(rfh.read())
opts["hosts.file"] = root_dir.join("hosts").strpath
opts["aliases.file"] = root_dir.join("aliases").strpath
opts["transport"] = request.config.getoption("--transport")
return opts
elif master_id == "mm-master":
with salt.utils.files.fopen(
os.path.join(RUNTIME_VARS.CONF_DIR, "mm_master")
) as rfh:
opts = yaml.deserialize(rfh.read())
return opts
elif master_id == "mm-sub-master":
with salt.utils.files.fopen(
os.path.join(RUNTIME_VARS.CONF_DIR, "mm_sub_master")
) as rfh:
opts = yaml.deserialize(rfh.read())
return opts
def pytest_saltfactories_master_configuration_overrides(
request, factories_manager, root_dir, master_id, default_options, order_masters
):
"""
Hook which should return a dictionary tailored for the provided master_id.
This dictionary will override the default_options dictionary.
Stops at the first non None result
"""
opts = {}
virtualenv_binary = _get_virtualenv_binary_path()
if virtualenv_binary:
opts["venv_bin"] = virtualenv_binary
return opts
@pytest.fixture(scope="session")
def session_master_of_masters_default_options(request, tempdir):
with salt.utils.files.fopen(
os.path.join(RUNTIME_VARS.CONF_DIR, "syndic_master")
) as rfh:
opts = yaml.deserialize(rfh.read())
opts["hosts.file"] = tempdir.join("hosts").strpath
opts["aliases.file"] = tempdir.join("aliases").strpath
opts["transport"] = request.config.getoption("--transport")
return opts
@pytest.fixture(scope="session")
def session_master_of_masters_config_overrides(session_master_of_masters_root_dir):
ext_pillar = []
if salt.utils.platform.is_windows():
ext_pillar = {
"cmd_yaml": "type {0}".format(os.path.join(RUNTIME_VARS.FILES, "ext.yaml"))
}
ext_pillar.append(
{
"cmd_yaml": "type {0}".format(
os.path.join(RUNTIME_VARS.FILES, "ext.yaml")
)
}
)
else:
ext_pillar = {
"cmd_yaml": "cat {0}".format(os.path.join(RUNTIME_VARS.FILES, "ext.yaml"))
}
ext_pillar.append(
{"cmd_yaml": "cat {0}".format(os.path.join(RUNTIME_VARS.FILES, "ext.yaml"))}
)
if master_id == "master":
ext_pillar.append(
{
"file_tree": {
"root_dir": os.path.join(
RUNTIME_VARS.PILLAR_DIR, "base", "file_tree"
),
"follow_dir_links": False,
"keep_newline": True,
}
}
)
opts["pillar_opts"] = True
opts["reactor"] = [
{
"salt/minion/*/start": [
os.path.join(RUNTIME_VARS.FILES, "reactor-sync-minion.sls")
],
},
{
"salt/test/reactor": [
os.path.join(RUNTIME_VARS.FILES, "reactor-test.sls")
],
},
]
# We need to copy the extension modules into the new master root_dir or
# it will be prefixed by it
extension_modules_path = session_master_of_masters_root_dir.join(
"extension_modules"
).strpath
extension_modules_path = root_dir.join("extension_modules").strpath
if not os.path.exists(extension_modules_path):
shutil.copytree(
os.path.join(RUNTIME_VARS.FILES, "extension_modules"),
@ -1330,9 +1065,7 @@ def session_master_of_masters_config_overrides(session_master_of_masters_root_di
)
# Copy the autosign_file to the new master root_dir
autosign_file_path = session_master_of_masters_root_dir.join(
"autosign_file"
).strpath
autosign_file_path = root_dir.join("autosign_file").strpath
shutil.copyfile(
os.path.join(RUNTIME_VARS.FILES, "autosign_file"), autosign_file_path
)
@ -1342,128 +1075,242 @@ def session_master_of_masters_config_overrides(session_master_of_masters_root_di
)
os.chmod(autosign_file_path, autosign_file_permissions)
pytest_stop_sending_events_file = session_master_of_masters_root_dir.join(
"pytest_stop_sending_events_file"
).strpath
with salt.utils.files.fopen(pytest_stop_sending_events_file, "w") as wfh:
wfh.write("")
return {
"ext_pillar": [ext_pillar],
"extension_modules": extension_modules_path,
"file_roots": {
"base": [os.path.join(RUNTIME_VARS.FILES, "file", "base")],
# Alternate root to test __env__ choices
"prod": [os.path.join(RUNTIME_VARS.FILES, "file", "prod")],
},
"pillar_roots": {"base": [os.path.join(RUNTIME_VARS.FILES, "pillar", "base")]},
"pytest_stop_sending_events_file": pytest_stop_sending_events_file,
}
opts.update(
{
"ext_pillar": ext_pillar,
"extension_modules": extension_modules_path,
"file_roots": {
"base": [
RUNTIME_VARS.TMP_STATE_TREE,
os.path.join(RUNTIME_VARS.FILES, "file", "base"),
],
# Alternate root to test __env__ choices
"prod": [
RUNTIME_VARS.TMP_PRODENV_STATE_TREE,
os.path.join(RUNTIME_VARS.FILES, "file", "prod"),
],
},
"pillar_roots": {
"base": [
RUNTIME_VARS.TMP_PILLAR_TREE,
os.path.join(RUNTIME_VARS.FILES, "pillar", "base"),
],
"prod": [RUNTIME_VARS.TMP_PRODENV_PILLAR_TREE],
},
}
)
return opts
@pytest.fixture(scope="session")
def session_syndic_master_default_options(request, tempdir):
with salt.utils.files.fopen(
os.path.join(RUNTIME_VARS.CONF_DIR, "syndic_master")
) as rfh:
opts = yaml.deserialize(rfh.read())
def pytest_saltfactories_generate_default_minion_configuration(
request, factories_manager, root_dir, minion_id, master_port
):
"""
Hook which should return a dictionary tailored for the provided minion_id
opts["hosts.file"] = tempdir.join("hosts").strpath
opts["aliases.file"] = tempdir.join("aliases").strpath
opts["transport"] = request.config.getoption("--transport")
Stops at the first non None result
"""
if minion_id == "minion":
with salt.utils.files.fopen(
os.path.join(RUNTIME_VARS.CONF_DIR, "minion")
) as rfh:
opts = yaml.deserialize(rfh.read())
elif minion_id == "sub_minion":
with salt.utils.files.fopen(
os.path.join(RUNTIME_VARS.CONF_DIR, "sub_minion")
) as rfh:
opts = yaml.deserialize(rfh.read())
elif minion_id == "mm-minion":
with salt.utils.files.fopen(
os.path.join(RUNTIME_VARS.CONF_DIR, "mm_minion")
) as rfh:
opts = yaml.deserialize(rfh.read())
elif minion_id == "mm-sub-minion":
with salt.utils.files.fopen(
os.path.join(RUNTIME_VARS.CONF_DIR, "mm_sub_minion")
) as rfh:
opts = yaml.deserialize(rfh.read())
else:
raise RuntimeError("Not prepared to handle minion_id '{}'".format(minion_id))
opts["hosts.file"] = root_dir.join("hosts").strpath
opts["aliases.file"] = root_dir.join("aliases").strpath
opts["transport"] = request.config.getoption("--transport")
return opts
def pytest_saltfactories_minion_configuration_overrides(
request, factories_manager, root_dir, minion_id, default_options
):
"""
Hook which should return a dictionary tailored for the provided minion_id.
This dictionary will override the default_options dictionary.
Stops at the first non None result
"""
if minion_id in ("minion", "sub_minion"):
opts = {
"file_roots": {
"base": [
RUNTIME_VARS.TMP_STATE_TREE,
os.path.join(RUNTIME_VARS.FILES, "file", "base"),
],
# Alternate root to test __env__ choices
"prod": [
RUNTIME_VARS.TMP_PRODENV_STATE_TREE,
os.path.join(RUNTIME_VARS.FILES, "file", "prod"),
],
},
"pillar_roots": {
"base": [
RUNTIME_VARS.TMP_PILLAR_TREE,
os.path.join(RUNTIME_VARS.FILES, "pillar", "base"),
],
"prod": [RUNTIME_VARS.TMP_PRODENV_PILLAR_TREE],
},
}
virtualenv_binary = _get_virtualenv_binary_path()
if virtualenv_binary:
opts["venv_bin"] = virtualenv_binary
return opts
if minion_id in ("mm-minion", "mm-sub-minion"):
mm_master_port = factories_manager.cache["configs"]["masters"]["mm-master"][
"ret_port"
]
mm_sub_master_port = factories_manager.cache["configs"]["masters"][
"mm-sub-master"
]["ret_port"]
opts = {
"master_port": "",
"master": [
"localhost:{}".format(mm_master_port),
"localhost:{}".format(mm_sub_master_port),
],
"test.foo": "baz",
}
return opts
@pytest.fixture(scope="session")
def session_syndic_default_options(request, tempdir):
with salt.utils.files.fopen(os.path.join(RUNTIME_VARS.CONF_DIR, "syndic")) as rfh:
opts = yaml.deserialize(rfh.read())
@pytest.hookspec(firstresult=True)
def pytest_saltfactories_generate_default_syndic_configuration(
request, factories_manager, root_dir, syndic_id, syndic_master_port
):
"""
Hook which should return a dictionary tailored for the provided syndic_id with 3 keys:
opts["hosts.file"] = tempdir.join("hosts").strpath
opts["aliases.file"] = tempdir.join("aliases").strpath
opts["transport"] = request.config.getoption("--transport")
* `master`: The default config for the master running along with the syndic
* `minion`: The default config for the master running along with the syndic
* `syndic`: The default config for the master running along with the syndic
return opts
Stops at the first non None result
"""
factory_opts = {"master": None, "minion": None, "syndic": None}
if syndic_id == "syndic":
with salt.utils.files.fopen(
os.path.join(RUNTIME_VARS.CONF_DIR, "syndic")
) as rfh:
opts = yaml.deserialize(rfh.read())
opts["hosts.file"] = root_dir.join("hosts").strpath
opts["aliases.file"] = root_dir.join("aliases").strpath
opts["transport"] = request.config.getoption("--transport")
factory_opts["syndic"] = opts
return factory_opts
@pytest.fixture(scope="session")
def session_proxy_default_options(request, tempdir):
with salt.utils.files.fopen(os.path.join(RUNTIME_VARS.CONF_DIR, "proxy")) as rfh:
opts = yaml.deserialize(rfh.read())
@pytest.hookspec(firstresult=True)
def pytest_saltfactories_syndic_configuration_overrides(
request, factories_manager, syndic_id, default_options
):
"""
Hook which should return a dictionary tailored for the provided syndic_id.
This dictionary will override the default_options dictionary.
opts["hosts.file"] = tempdir.join("hosts").strpath
opts["aliases.file"] = tempdir.join("aliases").strpath
opts["transport"] = request.config.getoption("--transport")
The returned dictionary should contain 3 keys:
return opts
* `master`: The config overrides for the master running along with the syndic
* `minion`: The config overrides for the master running along with the syndic
* `syndic`: The config overridess for the master running along with the syndic
The `default_options` parameter be None or have 3 keys, `master`, `minion`, `syndic`,
while will contain the default options for each of the daemons.
Stops at the first non None result
"""
@pytest.hookspec(firstresult=True)
def pytest_saltfactories_generate_default_proxy_minion_configuration(
request, factories_manager, proxy_minion_id, master_port
):
"""
Hook which should return a dictionary tailored for the provided proxy_minion_id
Stops at the first non None result
"""
@pytest.hookspec(firstresult=True)
def pytest_saltfactories_proxy_minion_configuration_overrides(
request, factories_manager, root_dir, proxy_minion_id, default_options
):
"""
Hook which should return a dictionary tailored for the provided proxy_minion_id.
This dictionary will override the default_options dictionary.
Stops at the first non None result
"""
if proxy_minion_id == "proxy":
with salt.utils.files.fopen(
os.path.join(RUNTIME_VARS.CONF_DIR, "proxy")
) as rfh:
opts = yaml.deserialize(rfh.read())
else:
raise RuntimeError(
"Not prepared to handle proxy minion_id '{}'".format(proxy_minion_id)
)
opts["hosts.file"] = root_dir.join("hosts").strpath
opts["aliases.file"] = root_dir.join("aliases").strpath
opts["transport"] = request.config.getoption("--transport")
return opts
@pytest.fixture(scope="session", autouse=True)
def bridge_pytest_and_runtests(
reap_stray_processes,
session_root_dir,
session_conf_dir,
session_secondary_conf_dir,
session_syndic_conf_dir,
session_master_of_masters_conf_dir,
session_base_env_pillar_tree_root_dir,
session_base_env_state_tree_root_dir,
session_prod_env_state_tree_root_dir,
session_master_config,
session_minion_config,
session_secondary_minion_config,
session_master_of_masters_config,
session_syndic_config,
base_env_state_tree_root_dir,
prod_env_state_tree_root_dir,
base_env_pillar_tree_root_dir,
prod_env_pillar_tree_root_dir,
salt_factories,
# salt_syndic_master_config,
# salt_syndic_config,
salt_master_config,
salt_minion_config,
salt_sub_minion_config,
):
# Make sure unittest2 uses the pytest generated configuration
RUNTIME_VARS.RUNTIME_CONFIGS["master"] = freeze(salt_master_config)
RUNTIME_VARS.RUNTIME_CONFIGS["minion"] = freeze(salt_minion_config)
RUNTIME_VARS.RUNTIME_CONFIGS["sub_minion"] = freeze(salt_sub_minion_config)
# RUNTIME_VARS.RUNTIME_CONFIGS['syndic_master'] = freeze(salt_syndic_master_config)
# RUNTIME_VARS.RUNTIME_CONFIGS['syndic'] = freeze(salt_syndic_config)
RUNTIME_VARS.RUNTIME_CONFIGS["client_config"] = freeze(
salt.config.client_config(salt_master_config["conf_file"])
)
# Make sure unittest2 classes know their paths
RUNTIME_VARS.TMP_ROOT_DIR = session_root_dir.realpath().strpath
RUNTIME_VARS.TMP_CONF_DIR = session_conf_dir.realpath().strpath
RUNTIME_VARS.TMP_SUB_MINION_CONF_DIR = session_secondary_conf_dir.realpath().strpath
RUNTIME_VARS.TMP_SYNDIC_MASTER_CONF_DIR = (
session_master_of_masters_conf_dir.realpath().strpath
RUNTIME_VARS.TMP_ROOT_DIR = salt_factories.root_dir.realpath().strpath
RUNTIME_VARS.TMP_CONF_DIR = os.path.dirname(salt_master_config["conf_file"])
RUNTIME_VARS.TMP_MINION_CONF_DIR = os.path.dirname(salt_minion_config["conf_file"])
RUNTIME_VARS.TMP_SUB_MINION_CONF_DIR = os.path.dirname(
salt_sub_minion_config["conf_file"]
)
RUNTIME_VARS.TMP_SYNDIC_MINION_CONF_DIR = session_syndic_conf_dir.realpath().strpath
RUNTIME_VARS.TMP_PILLAR_TREE = (
session_base_env_pillar_tree_root_dir.realpath().strpath
)
RUNTIME_VARS.TMP_STATE_TREE = (
session_base_env_state_tree_root_dir.realpath().strpath
)
RUNTIME_VARS.TMP_PRODENV_STATE_TREE = (
session_prod_env_state_tree_root_dir.realpath().strpath
)
# Make sure unittest2 uses the pytest generated configuration
RUNTIME_VARS.RUNTIME_CONFIGS["master"] = freeze(session_master_config)
RUNTIME_VARS.RUNTIME_CONFIGS["minion"] = freeze(session_minion_config)
RUNTIME_VARS.RUNTIME_CONFIGS["sub_minion"] = freeze(session_secondary_minion_config)
RUNTIME_VARS.RUNTIME_CONFIGS["syndic_master"] = freeze(
session_master_of_masters_config
)
RUNTIME_VARS.RUNTIME_CONFIGS["syndic"] = freeze(session_syndic_config)
RUNTIME_VARS.RUNTIME_CONFIGS["client_config"] = freeze(
salt.config.client_config(session_conf_dir.join("master").strpath)
)
# Copy configuration files and directories which are not automatically generated
for entry in os.listdir(RUNTIME_VARS.CONF_DIR):
if entry in (
"master",
"minion",
"sub_minion",
"syndic",
"syndic_master",
"proxy",
):
# These have runtime computed values and are handled by pytest-salt fixtures
continue
entry_path = os.path.join(RUNTIME_VARS.CONF_DIR, entry)
if os.path.isfile(entry_path):
shutil.copy(entry_path, os.path.join(RUNTIME_VARS.TMP_CONF_DIR, entry))
elif os.path.isdir(entry_path):
shutil.copytree(entry_path, os.path.join(RUNTIME_VARS.TMP_CONF_DIR, entry))
# RUNTIME_VARS.TMP_SYNDIC_MASTER_CONF_DIR = os.path.dirname(salt_syndic_master_config['conf_file'])
# RUNTIME_VARS.TMP_SYNDIC_MINION_CONF_DIR = os.path.dirname(salt_syndic_config['conf_file'])
# <---- Salt Configuration -------------------------------------------------------------------------------------------

View file

@ -7,48 +7,54 @@
"""
# pylint: disable=unused-argument,redefined-outer-name
# Import Python libs
from __future__ import absolute_import, unicode_literals
import logging
from collections import OrderedDict
# Import 3rd-party libs
import psutil
import pytest
log = logging.getLogger(__name__)
# @pytest.fixture(scope='package')
# def salt_syndic_master(request, salt_factories):
# return salt_factories.spawn_master(request, 'syndic_master', order_masters=True)
# @pytest.fixture(scope='package')
# def salt_syndic(request, salt_factories, salt_syndic_master):
# return salt_factories.spawn_syndic(request, 'syndic', master_of_masters_id='syndic_master')
# @pytest.fixture(scope='package')
# def salt_master(request, salt_factories, salt_syndic_master):
# return salt_factories.spawn_master(request, 'master', master_of_masters_id='syndic_master')
@pytest.fixture(scope="package")
def salt_master(request, salt_factories):
return salt_factories.spawn_master(request, "master")
@pytest.fixture(scope="package")
def salt_minion(request, salt_factories, salt_master):
return salt_factories.spawn_minion(request, "minion", master_id="master")
@pytest.fixture(scope="package")
def salt_sub_minion(request, salt_factories, salt_master):
return salt_factories.spawn_minion(request, "sub_minion", master_id="master")
@pytest.fixture(scope="package", autouse=True)
def default_session_daemons(
request,
log_server,
session_salt_master,
session_salt_minion,
session_secondary_salt_minion,
def bridge_pytest_and_runtests(
bridge_pytest_and_runtests,
salt_factories,
# salt_syndic_master,
# salt_syndic,
salt_master,
salt_minion,
salt_sub_minion,
):
request.session.stats_processes.update(
OrderedDict(
(
("Salt Master", psutil.Process(session_salt_master.pid)),
("Salt Minion", psutil.Process(session_salt_minion.pid)),
("Salt Sub Minion", psutil.Process(session_secondary_salt_minion.pid)),
)
).items()
)
# Run tests
yield
# Stop daemons now(they would be stopped at the end of the test run session
for daemon in (
session_secondary_salt_minion,
session_salt_minion,
session_salt_master,
):
try:
daemon.terminate()
except Exception as exc: # pylint: disable=broad-except
log.warning("Failed to terminate daemon: %s", daemon.__class__.__name__)

View file

@ -10,809 +10,100 @@ from __future__ import absolute_import, print_function, unicode_literals
import logging
import os
import shutil
from collections import OrderedDict
import psutil
import pytest
import salt.utils.files
from pytestsalt.fixtures.config import apply_master_config, apply_minion_config
from pytestsalt.fixtures.daemons import SaltMaster, SaltMinion, start_daemon
from pytestsalt.fixtures.ports import get_unused_localhost_port
from salt.serializers import yaml
from salt.utils.immutabletypes import freeze
from tests.support.runtests import RUNTIME_VARS
log = logging.getLogger(__name__)
SESSION_ROOT_DIR = "session-mm-root"
SESSION_SECONDARY_ROOT_DIR = "session-secondary-mm-root"
@pytest.fixture(scope="package")
def salt_mm_master_config(request, salt_factories):
return salt_factories.configure_master(request, "mm-master")
@pytest.fixture(scope="session")
def session_mm_root_dir(tempdir):
"""
Return the session scoped salt root dir
"""
return tempdir.mkdir(SESSION_ROOT_DIR)
@pytest.fixture(scope="session")
def session_mm_conf_dir(session_mm_root_dir):
"""
Return the session scoped salt root dir
"""
return session_mm_root_dir.join("conf").ensure(dir=True)
# ----- Master Fixtures --------------------------------------------------------------------------------------------->
@pytest.fixture(scope="session")
def session_mm_master_id():
"""
Returns the session scoped master id
"""
return "mm-master"
@pytest.fixture(scope="session")
def session_mm_master_publish_port():
"""
Returns an unused localhost port for the master publish interface
"""
return get_unused_localhost_port()
@pytest.fixture(scope="session")
def session_mm_master_return_port():
"""
Returns an unused localhost port for the master return interface
"""
return get_unused_localhost_port()
@pytest.fixture(scope="session")
def session_mm_master_engine_port():
"""
Returns an unused localhost port for the pytest session salt master engine
"""
return get_unused_localhost_port()
@pytest.fixture(scope="session")
def session_mm_master_tcp_master_pub_port():
"""
Returns an unused localhost port
"""
return get_unused_localhost_port()
@pytest.fixture(scope="session")
def session_mm_master_tcp_master_pull_port():
"""
Returns an unused localhost port
"""
return get_unused_localhost_port()
@pytest.fixture(scope="session")
def session_mm_master_tcp_master_publish_pull():
"""
Returns an unused localhost port
"""
return get_unused_localhost_port()
@pytest.fixture(scope="session")
def session_mm_master_tcp_master_workers():
"""
Returns an unused localhost port
"""
return get_unused_localhost_port()
@pytest.fixture(scope="session")
def session_mm_master_log_prefix(session_mm_master_id):
return "salt-master/{}".format(session_mm_master_id)
@pytest.fixture(scope="session")
def session_mm_master_config_file(session_mm_conf_dir):
"""
Returns the path to the salt master configuration file
"""
return session_mm_conf_dir.join("master").realpath().strpath
@pytest.fixture(scope="session")
def session_mm_master_default_options(session_master_default_options):
with salt.utils.files.fopen(
os.path.join(RUNTIME_VARS.CONF_DIR, "mm_master")
) as rfh:
config_file_opts = yaml.deserialize(rfh.read())
opts = session_master_default_options.copy()
if config_file_opts:
opts.update(config_file_opts)
return opts
@pytest.fixture(scope="session")
def session_mm_master_config_overrides(
session_master_config_overrides, session_mm_root_dir
):
overrides = session_master_config_overrides.copy()
pytest_stop_sending_events_file = session_mm_root_dir.join(
"pytest_mm_stop_sending_events_file"
).strpath
with salt.utils.files.fopen(pytest_stop_sending_events_file, "w") as wfh:
wfh.write("")
overrides["pytest_stop_sending_events_file"] = pytest_stop_sending_events_file
return overrides
@pytest.fixture(scope="session")
def session_mm_master_config(
session_mm_root_dir,
session_mm_master_default_options,
session_mm_master_config_file,
session_mm_master_publish_port,
session_mm_master_return_port,
session_mm_master_engine_port,
session_mm_master_config_overrides,
session_mm_master_id,
session_base_env_state_tree_root_dir,
session_prod_env_state_tree_root_dir,
session_base_env_pillar_tree_root_dir,
session_prod_env_pillar_tree_root_dir,
running_username,
log_server_port,
log_server_level,
engines_dir,
log_handlers_dir,
session_mm_master_log_prefix,
session_mm_master_tcp_master_pub_port,
session_mm_master_tcp_master_pull_port,
session_mm_master_tcp_master_publish_pull,
session_mm_master_tcp_master_workers,
):
"""
This fixture will return the salt master configuration options after being
overridden with any options passed from ``session_master_config_overrides``
"""
return apply_master_config(
session_mm_master_default_options,
session_mm_root_dir,
session_mm_master_config_file,
session_mm_master_publish_port,
session_mm_master_return_port,
session_mm_master_engine_port,
session_mm_master_config_overrides,
session_mm_master_id,
[session_base_env_state_tree_root_dir.strpath],
[session_prod_env_state_tree_root_dir.strpath],
[session_base_env_pillar_tree_root_dir.strpath],
[session_prod_env_pillar_tree_root_dir.strpath],
running_username,
log_server_port,
log_server_level,
engines_dir,
log_handlers_dir,
session_mm_master_log_prefix,
session_mm_master_tcp_master_pub_port,
session_mm_master_tcp_master_pull_port,
session_mm_master_tcp_master_publish_pull,
session_mm_master_tcp_master_workers,
@pytest.fixture(scope="package")
def salt_mm_minion_config(request, salt_factories, salt_mm_master, salt_mm_sub_master):
return salt_factories.configure_minion(
request, "mm-minion", master_id=salt_mm_master.config["id"]
)
@pytest.fixture(scope="session")
def session_mm_salt_master(
request,
session_mm_conf_dir,
session_mm_master_id,
session_mm_master_config,
log_server, # pylint: disable=unused-argument
session_mm_master_log_prefix,
cli_master_script_name,
_cli_bin_dir,
_salt_fail_hard,
@pytest.fixture(scope="package")
def salt_mm_sub_master_config(request, salt_factories, salt_mm_master):
return salt_factories.configure_master(request, "mm-sub-master")
@pytest.fixture(scope="package")
def salt_mm_sub_minion_config(
request, salt_factories, salt_mm_master, salt_mm_sub_master
):
"""
Returns a running salt-master
"""
return start_daemon(
request,
daemon_name="salt-master",
daemon_id=session_mm_master_id,
daemon_log_prefix=session_mm_master_log_prefix,
daemon_cli_script_name=cli_master_script_name,
daemon_config=session_mm_master_config,
daemon_config_dir=session_mm_conf_dir,
daemon_class=SaltMaster,
bin_dir_path=_cli_bin_dir,
fail_hard=_salt_fail_hard,
event_listener_config_dir=session_mm_conf_dir,
start_timeout=60,
return salt_factories.configure_minion(
request, "mm-sub-minion", master_id=salt_mm_sub_master.config["id"]
)
# <---- Master Fixtures ----------------------------------------------------------------------------------------------
@pytest.fixture(scope="package")
def salt_mm_master(request, salt_factories):
return salt_factories.spawn_master(request, "mm-master")
@pytest.fixture(scope="session")
def session_mm_secondary_root_dir(tempdir):
"""
Return the session scoped salt secondary root dir
"""
return tempdir.mkdir(SESSION_SECONDARY_ROOT_DIR)
@pytest.fixture(scope="session")
def session_mm_secondary_conf_dir(session_mm_secondary_root_dir):
"""
Return the session scoped salt root dir
"""
return session_mm_secondary_root_dir.join("conf").ensure(dir=True)
# ----- Sub Master Fixtures ----------------------------------------------------------------------------------------->
@pytest.fixture(scope="session")
def session_mm_secondary_master_id():
"""
Returns the session scoped master id
"""
return "mm-sub-master"
@pytest.fixture(scope="session")
def session_mm_secondary_master_publish_port():
"""
Returns an unused localhost port for the master publish interface
"""
return get_unused_localhost_port()
@pytest.fixture(scope="session")
def session_mm_secondary_master_return_port():
"""
Returns an unused localhost port for the master return interface
"""
return get_unused_localhost_port()
@pytest.fixture(scope="session")
def session_mm_secondary_master_engine_port():
"""
Returns an unused localhost port for the pytest session salt master engine
"""
return get_unused_localhost_port()
@pytest.fixture(scope="session")
def session_mm_secondary_master_tcp_master_pub_port():
"""
Returns an unused localhost port
"""
return get_unused_localhost_port()
@pytest.fixture(scope="session")
def session_mm_secondary_master_tcp_master_pull_port():
"""
Returns an unused localhost port
"""
return get_unused_localhost_port()
@pytest.fixture(scope="session")
def session_mm_secondary_master_tcp_master_publish_pull():
"""
Returns an unused localhost port
"""
return get_unused_localhost_port()
@pytest.fixture(scope="session")
def session_mm_secondary_master_tcp_master_workers():
"""
Returns an unused localhost port
"""
return get_unused_localhost_port()
@pytest.fixture(scope="session")
def session_mm_secondary_master_log_prefix(session_mm_secondary_master_id):
return "salt-master/{}".format(session_mm_secondary_master_id)
@pytest.fixture(scope="session")
def session_mm_secondary_master_config_file(session_mm_secondary_conf_dir):
"""
Returns the path to the salt master configuration file
"""
return session_mm_secondary_conf_dir.join("master").realpath().strpath
@pytest.fixture(scope="session")
def session_mm_secondary_master_default_options(session_master_default_options):
opts = session_master_default_options.copy()
with salt.utils.files.fopen(
os.path.join(RUNTIME_VARS.CONF_DIR, "mm_sub_master")
) as rfh:
opts.update(yaml.deserialize(rfh.read()))
return opts
@pytest.fixture(scope="session")
def session_mm_secondary_master_config_overrides(
session_master_config_overrides, session_mm_secondary_root_dir
@pytest.fixture(scope="package")
def salt_mm_sub_master(
request, salt_factories, salt_mm_master, salt_mm_sub_master_config
):
overrides = session_master_config_overrides.copy()
pytest_stop_sending_events_file = session_mm_secondary_root_dir.join(
"pytest_mm_stop_sending_events_file"
).strpath
with salt.utils.files.fopen(pytest_stop_sending_events_file, "w") as wfh:
wfh.write("")
overrides["pytest_stop_sending_events_file"] = pytest_stop_sending_events_file
return overrides
@pytest.fixture(scope="session")
def session_mm_secondary_master_config(
session_mm_secondary_root_dir,
session_mm_secondary_master_default_options,
session_mm_secondary_master_config_file,
session_mm_secondary_master_publish_port,
session_mm_secondary_master_return_port,
session_mm_secondary_master_engine_port,
session_mm_secondary_master_config_overrides,
session_mm_secondary_master_id,
session_base_env_state_tree_root_dir,
session_prod_env_state_tree_root_dir,
session_base_env_pillar_tree_root_dir,
session_prod_env_pillar_tree_root_dir,
running_username,
log_server_port,
log_server_level,
engines_dir,
log_handlers_dir,
session_mm_secondary_master_log_prefix,
session_mm_secondary_master_tcp_master_pub_port,
session_mm_secondary_master_tcp_master_pull_port,
session_mm_secondary_master_tcp_master_publish_pull,
session_mm_secondary_master_tcp_master_workers,
):
"""
This fixture will return the salt master configuration options after being
overridden with any options passed from ``session_master_config_overrides``
"""
return apply_master_config(
session_mm_secondary_master_default_options,
session_mm_secondary_root_dir,
session_mm_secondary_master_config_file,
session_mm_secondary_master_publish_port,
session_mm_secondary_master_return_port,
session_mm_secondary_master_engine_port,
session_mm_secondary_master_config_overrides,
session_mm_secondary_master_id,
[session_base_env_state_tree_root_dir.strpath],
[session_prod_env_state_tree_root_dir.strpath],
[session_base_env_pillar_tree_root_dir.strpath],
[session_prod_env_pillar_tree_root_dir.strpath],
running_username,
log_server_port,
log_server_level,
engines_dir,
log_handlers_dir,
session_mm_secondary_master_log_prefix,
session_mm_secondary_master_tcp_master_pub_port,
session_mm_secondary_master_tcp_master_pull_port,
session_mm_secondary_master_tcp_master_publish_pull,
session_mm_secondary_master_tcp_master_workers,
)
@pytest.fixture(scope="session")
def session_mm_secondary_salt_master(
request,
session_mm_secondary_conf_dir,
session_mm_secondary_master_id,
session_mm_secondary_master_config,
log_server, # pylint: disable=unused-argument
session_mm_secondary_master_log_prefix,
cli_master_script_name,
_cli_bin_dir,
_salt_fail_hard,
session_mm_master_config,
session_mm_salt_master,
):
"""
Returns a running salt-master
"""
# The secondary salt master depends on the primarily salt master fixture
# because we need to clone the keys
for keyfile in ("master.pem", "master.pub"):
shutil.copyfile(
os.path.join(session_mm_master_config["pki_dir"], keyfile),
os.path.join(session_mm_secondary_master_config["pki_dir"], keyfile),
os.path.join(salt_mm_master.config["pki_dir"], keyfile),
os.path.join(salt_mm_sub_master_config["pki_dir"], keyfile),
)
return start_daemon(
request,
daemon_name="salt-master",
daemon_id=session_mm_secondary_master_id,
daemon_log_prefix=session_mm_secondary_master_log_prefix,
daemon_cli_script_name=cli_master_script_name,
daemon_config=session_mm_secondary_master_config,
daemon_config_dir=session_mm_secondary_conf_dir,
daemon_class=SaltMaster,
bin_dir_path=_cli_bin_dir,
fail_hard=_salt_fail_hard,
event_listener_config_dir=session_mm_secondary_conf_dir,
start_timeout=60,
return salt_factories.spawn_master(request, "mm-sub-master")
@pytest.fixture(scope="package")
def salt_mm_minion(request, salt_factories, salt_mm_master, salt_mm_sub_master):
return salt_factories.spawn_minion(
request, "mm-minion", master_id=salt_mm_master.config["id"]
)
# <---- Sub Master Fixtures ------------------------------------------------------------------------------------------
# ----- Sub Minion Fixtures --------------------------------------------------------------------------------------------->
@pytest.fixture(scope="session")
def session_mm_secondary_minion_id():
"""
Returns the session scoped minion id
"""
return "mm-sub-minion"
@pytest.fixture(scope="session")
def session_mm_secondary_minion_tcp_pub_port():
"""
Returns an unused localhost port
"""
return get_unused_localhost_port()
@pytest.fixture(scope="session")
def session_mm_secondary_minion_tcp_pull_port():
"""
Returns an unused localhost port
"""
return get_unused_localhost_port()
@pytest.fixture(scope="session")
def session_mm_secondary_minion_log_prefix(session_mm_secondary_minion_id):
return "salt-minion/{}".format(session_mm_secondary_minion_id)
@pytest.fixture(scope="session")
def session_mm_secondary_minion_config_file(session_mm_secondary_conf_dir):
"""
Returns the path to the salt minion configuration file
"""
return session_mm_secondary_conf_dir.join("minion").realpath().strpath
@pytest.fixture(scope="session")
def session_mm_secondary_minion_default_options(
session_secondary_minion_default_options,
):
opts = session_secondary_minion_default_options.copy()
with salt.utils.files.fopen(
os.path.join(RUNTIME_VARS.CONF_DIR, "mm_sub_minion")
) as rfh:
opts.update(yaml.deserialize(rfh.read()))
return opts
@pytest.fixture(scope="session")
def session_mm_secondary_minion_config_overrides(
session_secondary_minion_config_overrides,
session_mm_master_return_port,
session_mm_secondary_master_return_port,
):
if session_secondary_minion_config_overrides:
opts = session_secondary_minion_config_overrides.copy()
else:
opts = {}
opts["master_port"] = None
opts["master"] = [
"localhost:{}".format(session_mm_master_return_port),
"localhost:{}".format(session_mm_secondary_master_return_port),
]
return opts
@pytest.fixture(scope="session")
def session_mm_secondary_minion_config(
session_mm_secondary_root_dir,
session_mm_secondary_minion_config_file,
session_mm_secondary_master_return_port,
session_mm_secondary_minion_default_options,
session_mm_secondary_minion_config_overrides,
session_mm_secondary_minion_id,
running_username,
log_server_port,
log_server_level,
log_handlers_dir,
session_mm_secondary_minion_log_prefix,
session_mm_secondary_minion_tcp_pub_port,
session_mm_secondary_minion_tcp_pull_port,
):
"""
This fixture will return the session salt minion configuration options after being
overridden with any options passed from ``session_secondary_minion_config_overrides``
"""
return apply_minion_config(
session_mm_secondary_minion_default_options,
session_mm_secondary_root_dir,
session_mm_secondary_minion_config_file,
session_mm_secondary_master_return_port,
session_mm_secondary_minion_config_overrides,
session_mm_secondary_minion_id,
running_username,
log_server_port,
log_server_level,
log_handlers_dir,
session_mm_secondary_minion_log_prefix,
session_mm_secondary_minion_tcp_pub_port,
session_mm_secondary_minion_tcp_pull_port,
@pytest.fixture(scope="package")
def salt_mm_sub_minion(request, salt_factories, salt_mm_master, salt_mm_sub_master):
return salt_factories.spawn_minion(
request, "mm-sub-minion", master_id=salt_mm_sub_master.config["id"]
)
@pytest.fixture(scope="session")
def session_mm_secondary_salt_minion(
request,
session_mm_salt_master,
session_mm_secondary_salt_master,
session_mm_secondary_minion_id,
session_mm_secondary_minion_config,
session_mm_secondary_minion_log_prefix,
cli_minion_script_name,
log_server,
_cli_bin_dir,
_salt_fail_hard,
session_mm_secondary_conf_dir,
):
"""
Returns a running salt-minion
"""
return start_daemon(
request,
daemon_name="salt-minion",
daemon_id=session_mm_secondary_minion_id,
daemon_log_prefix=session_mm_secondary_minion_log_prefix,
daemon_cli_script_name=cli_minion_script_name,
daemon_config=session_mm_secondary_minion_config,
daemon_config_dir=session_mm_secondary_conf_dir,
daemon_class=SaltMinion,
bin_dir_path=_cli_bin_dir,
fail_hard=_salt_fail_hard,
event_listener_config_dir=session_mm_secondary_conf_dir,
start_timeout=60,
)
# <---- Minion Fixtures ----------------------------------------------------------------------------------------------
# ----- Minion Fixtures ----------------------------------------------------------------------------------------->
@pytest.fixture(scope="session")
def session_mm_minion_id():
"""
Returns the session scoped minion id
"""
return "mm-minion"
@pytest.fixture(scope="session")
def session_mm_minion_tcp_pub_port():
"""
Returns an unused localhost port
"""
return get_unused_localhost_port()
@pytest.fixture(scope="session")
def session_mm_minion_tcp_pull_port():
"""
Returns an unused localhost port
"""
return get_unused_localhost_port()
@pytest.fixture(scope="session")
def session_mm_minion_log_prefix(session_mm_minion_id):
return "salt-minion/{}".format(session_mm_minion_id)
@pytest.fixture(scope="session")
def session_mm_minion_config_file(session_mm_conf_dir):
"""
Returns the path to the salt minion configuration file
"""
return session_mm_conf_dir.join("minion").realpath().strpath
@pytest.fixture(scope="session")
def session_mm_minion_default_options(session_minion_default_options):
opts = session_minion_default_options.copy()
with salt.utils.files.fopen(
os.path.join(RUNTIME_VARS.CONF_DIR, "mm_sub_minion")
) as rfh:
opts.update(yaml.deserialize(rfh.read()))
return opts
@pytest.fixture(scope="session")
def session_mm_minion_config_overrides(
session_minion_config_overrides,
session_mm_master_return_port,
session_mm_secondary_master_return_port,
):
if session_minion_config_overrides:
opts = session_minion_config_overrides.copy()
else:
opts = {}
opts["master_port"] = None
opts["master"] = [
"localhost:{}".format(session_mm_master_return_port),
"localhost:{}".format(session_mm_secondary_master_return_port),
]
return opts
@pytest.fixture(scope="session")
def session_mm_minion_config(
session_mm_root_dir,
session_mm_minion_config_file,
session_mm_master_return_port,
session_mm_minion_default_options,
session_mm_minion_config_overrides,
session_mm_minion_id,
running_username,
log_server_port,
log_server_level,
log_handlers_dir,
session_mm_minion_log_prefix,
session_mm_minion_tcp_pub_port,
session_mm_minion_tcp_pull_port,
):
"""
This fixture will return the session salt minion configuration options after being
overridden with any options passed from ``session_minion_config_overrides``
"""
return apply_minion_config(
session_mm_minion_default_options,
session_mm_root_dir,
session_mm_minion_config_file,
session_mm_master_return_port,
session_mm_minion_config_overrides,
session_mm_minion_id,
running_username,
log_server_port,
log_server_level,
log_handlers_dir,
session_mm_minion_log_prefix,
session_mm_minion_tcp_pub_port,
session_mm_minion_tcp_pull_port,
)
@pytest.fixture(scope="session")
def session_mm_salt_minion(
request,
session_mm_salt_master,
session_mm_secondary_salt_master,
session_mm_minion_id,
session_mm_minion_config,
session_mm_minion_log_prefix,
cli_minion_script_name,
log_server,
_cli_bin_dir,
_salt_fail_hard,
session_mm_conf_dir,
):
"""
Returns a running salt-minion
"""
return start_daemon(
request,
daemon_name="salt-minion",
daemon_id=session_mm_minion_id,
daemon_log_prefix=session_mm_minion_log_prefix,
daemon_cli_script_name=cli_minion_script_name,
daemon_config=session_mm_minion_config,
daemon_config_dir=session_mm_conf_dir,
daemon_class=SaltMinion,
bin_dir_path=_cli_bin_dir,
fail_hard=_salt_fail_hard,
event_listener_config_dir=session_mm_conf_dir,
start_timeout=60,
)
# <---- Sub Minion Fixtures ------------------------------------------------------------------------------------------
@pytest.fixture(scope="session")
def default_session_daemons(
request,
log_server,
session_mm_salt_master,
session_mm_secondary_salt_master,
session_mm_salt_minion,
session_mm_secondary_salt_minion,
):
request.session.stats_processes.update(
OrderedDict(
(
("Salt MM Master", psutil.Process(session_mm_salt_master.pid)),
("Salt MM Minion", psutil.Process(session_mm_salt_minion.pid)),
(
"Salt MM Sub Master",
psutil.Process(session_mm_secondary_salt_master.pid),
),
(
"Salt MM Sub Minion",
psutil.Process(session_mm_secondary_salt_minion.pid),
),
)
).items()
)
# Run tests
yield
# Stop daemons now(they would be stopped at the end of the test run session
for daemon in (
session_mm_secondary_salt_minion,
session_mm_secondary_salt_master,
session_mm_salt_minion,
session_mm_salt_master,
):
try:
daemon.terminate()
except Exception as exc: # pylint: disable=broad-except
log.warning("Failed to terminate daemon: %s", daemon.__class__.__name__)
@pytest.fixture(scope="session", autouse=True)
def mm_bridge_pytest_and_runtests(
@pytest.fixture(scope="package", autouse=True)
def bridge_pytest_and_runtests(
reap_stray_processes,
session_mm_conf_dir,
session_mm_secondary_conf_dir,
session_base_env_pillar_tree_root_dir,
session_base_env_state_tree_root_dir,
session_prod_env_state_tree_root_dir,
session_mm_master_config,
session_mm_minion_config,
session_mm_secondary_master_config,
session_mm_secondary_minion_config,
default_session_daemons,
base_env_state_tree_root_dir,
prod_env_state_tree_root_dir,
base_env_pillar_tree_root_dir,
prod_env_pillar_tree_root_dir,
salt_factories,
salt_mm_master,
salt_mm_minion,
salt_mm_sub_master,
salt_mm_sub_minion,
):
# Make sure unittest2 uses the pytest generated configuration
RUNTIME_VARS.RUNTIME_CONFIGS["mm_master"] = freeze(salt_mm_master.config)
RUNTIME_VARS.RUNTIME_CONFIGS["mm_minion"] = freeze(salt_mm_minion.config)
RUNTIME_VARS.RUNTIME_CONFIGS["mm_sub_master"] = freeze(salt_mm_sub_master.config)
RUNTIME_VARS.RUNTIME_CONFIGS["mm_sub_minion"] = freeze(salt_mm_sub_minion.config)
# Make sure unittest2 classes know their paths
RUNTIME_VARS.TMP_MM_CONF_DIR = session_mm_conf_dir.realpath().strpath
RUNTIME_VARS.TMP_MM_SUB_CONF_DIR = session_mm_secondary_conf_dir.realpath().strpath
RUNTIME_VARS.TMP_SUB_MINION_CONF_DIR = (
session_mm_secondary_conf_dir.realpath().strpath
RUNTIME_VARS.TMP_MM_CONF_DIR = os.path.dirname(salt_mm_master.config["conf_file"])
RUNTIME_VARS.TMP_MM_MINION_CONF_DIR = os.path.dirname(
salt_mm_minion.config["conf_file"]
)
RUNTIME_VARS.TMP_PILLAR_TREE = (
session_base_env_pillar_tree_root_dir.realpath().strpath
RUNTIME_VARS.TMP_MM_SUB_CONF_DIR = os.path.dirname(
salt_mm_sub_master.config["conf_file"]
)
RUNTIME_VARS.TMP_STATE_TREE = (
session_base_env_state_tree_root_dir.realpath().strpath
)
RUNTIME_VARS.TMP_PRODENV_STATE_TREE = (
session_prod_env_state_tree_root_dir.realpath().strpath
)
# Make sure unittest2 uses the pytest generated configuration
RUNTIME_VARS.RUNTIME_CONFIGS["mm_master"] = freeze(session_mm_master_config)
RUNTIME_VARS.RUNTIME_CONFIGS["mm_minion"] = freeze(session_mm_minion_config)
RUNTIME_VARS.RUNTIME_CONFIGS["mm_sub_master"] = freeze(
session_mm_secondary_master_config
)
RUNTIME_VARS.RUNTIME_CONFIGS["mm_sub_minion"] = freeze(
session_mm_secondary_minion_config
RUNTIME_VARS.TMP_MM_SUB_MINION_CONF_DIR = os.path.dirname(
salt_mm_sub_minion.config["conf_file"]
)

View file

@ -6,15 +6,13 @@
Code to generate Salt CLI scripts for test runs
"""
# Import Python Libs
from __future__ import absolute_import, unicode_literals
import logging
import os
import sys
# Import Pytest Salt libs
from pytestsalt.utils import cli_scripts
from saltfactories.utils import cli_scripts
log = logging.getLogger(__name__)
@ -38,6 +36,7 @@ def get_script_path(bin_dir, script_name):
script_name=script_name,
executable=sys.executable,
code_dir=RUNTIME_VARS.CODE_DIR,
inject_coverage="COVERAGE_PROCESS_START" in os.environ,
inject_sitecustomize="COVERAGE_PROCESS_START" in os.environ,
)
log.info("Returning script path %r", script_path)

View file

@ -3,7 +3,6 @@
Base classes for gitfs/git_pillar integration tests
"""
# Import python libs
from __future__ import absolute_import, print_function, unicode_literals
import copy
@ -19,20 +18,17 @@ import textwrap
import threading
import time
# Import 3rd-party libs
import psutil
import salt.ext.six as six
# Import Salt libs
import salt.utils.files
import salt.utils.path
import salt.utils.yaml
from pytestsalt.utils import SaltDaemonScriptBase as _SaltDaemonScriptBase
from pytestsalt.utils import terminate_process
from salt.fileserver import gitfs
from salt.pillar import git_pillar
# Import Salt Testing libs
from saltfactories.utils.processes.helpers import terminate_process
from saltfactories.utils.processes.salts import (
SaltDaemonScriptBase as _SaltDaemonScriptBase,
)
from tests.support.case import ModuleCase
from tests.support.helpers import (
get_unused_localhost_port,

View file

@ -40,9 +40,9 @@ import salt.utils.files
import salt.utils.platform
import salt.utils.stringutils
import salt.utils.versions
from pytestsalt.utils import get_unused_localhost_port
from salt.ext import six
from salt.ext.six.moves import builtins, range
from saltfactories.utils.ports import get_unused_localhost_port
from tests.support.mock import patch
from tests.support.runtests import RUNTIME_VARS
from tests.support.sminion import create_sminion

View file

@ -200,6 +200,10 @@ class AdaptedConfigurationTestCaseMixin(object):
@staticmethod
def get_config_file_path(filename):
if filename == "master":
return os.path.join(RUNTIME_VARS.TMP_CONF_DIR, filename)
if filename == "minion":
return os.path.join(RUNTIME_VARS.TMP_MINION_CONF_DIR, filename)
if filename == "syndic_master":
return os.path.join(RUNTIME_VARS.TMP_SYNDIC_MASTER_CONF_DIR, "master")
if filename == "syndic":
@ -211,9 +215,9 @@ class AdaptedConfigurationTestCaseMixin(object):
if filename == "mm_sub_master":
return os.path.join(RUNTIME_VARS.TMP_MM_SUB_CONF_DIR, "master")
if filename == "mm_minion":
return os.path.join(RUNTIME_VARS.TMP_MM_CONF_DIR, "minion")
return os.path.join(RUNTIME_VARS.TMP_MM_MINION_CONF_DIR, "minion")
if filename == "mm_sub_minion":
return os.path.join(RUNTIME_VARS.TMP_MM_SUB_CONF_DIR, "minion")
return os.path.join(RUNTIME_VARS.TMP_MM_SUB_MINION_CONF_DIR, "minion")
return os.path.join(RUNTIME_VARS.TMP_CONF_DIR, filename)
@property

View file

@ -10,30 +10,39 @@
Process handling utilities
"""
# Import python libs
from __future__ import absolute_import
import logging
from pytestsalt.fixtures.daemons import Salt as PytestSalt
from pytestsalt.fixtures.daemons import SaltCall as PytestSaltCall
from pytestsalt.fixtures.daemons import SaltKey as PytestSaltKey
from pytestsalt.fixtures.daemons import SaltMaster as PytestSaltMaster
from pytestsalt.fixtures.daemons import SaltMinion as PytestSaltMinion
from pytestsalt.fixtures.daemons import SaltProxy as PytestSaltProxy
from pytestsalt.fixtures.daemons import SaltRun as PytestSaltRun
from pytestsalt.fixtures.daemons import SaltSyndic as PytestSaltSyndic
# Import pytest-salt libs
from pytestsalt.utils import ( # pylint: disable=unused-import
from saltfactories.utils.processes.helpers import ( # pylint: disable=unused-import
collect_child_processes,
terminate_process,
terminate_process_list,
)
# Import tests support libs
from tests.support.cli_scripts import ScriptPathMixin
try:
from pytestsalt.fixtures.daemons import Salt as PytestSalt
from pytestsalt.fixtures.daemons import SaltCall as PytestSaltCall
from pytestsalt.fixtures.daemons import SaltKey as PytestSaltKey
from pytestsalt.fixtures.daemons import SaltMaster as PytestSaltMaster
from pytestsalt.fixtures.daemons import SaltMinion as PytestSaltMinion
from pytestsalt.fixtures.daemons import SaltProxy as PytestSaltProxy
from pytestsalt.fixtures.daemons import SaltRun as PytestSaltRun
from pytestsalt.fixtures.daemons import SaltSyndic as PytestSaltSyndic
except ImportError:
# If this happens, we are running under pytest which uninstalls pytest-salt due to impatabilites
# These imports won't actually work but these classes are only used when running under runtests,
# so, we're just making sure we also don't hit NameError's
from saltfactories.utils.processes.salts import SaltCallCLI as PytestSaltCall
from saltfactories.utils.processes.salts import SaltCLI as PytestSalt
from saltfactories.utils.processes.salts import SaltKeyCLI as PytestSaltKey
from saltfactories.utils.processes.salts import SaltMaster as PytestSaltMaster
from saltfactories.utils.processes.salts import SaltMinion as PytestSaltMinion
from saltfactories.utils.processes.salts import SaltProxyMinion as PytestSaltProxy
from saltfactories.utils.processes.salts import SaltRunCLI as PytestSaltRun
from saltfactories.utils.processes.salts import SaltSyndic as PytestSaltSyndic
log = logging.getLogger(__name__)

View file

@ -45,7 +45,6 @@
.. _`pytest`: http://pytest.org
.. _`nose`: https://nose.readthedocs.org
"""
from __future__ import absolute_import, print_function
import logging
@ -62,7 +61,6 @@ try:
except ImportError:
import salt.utils.win_functions
log = logging.getLogger(__name__)