mirror of
https://github.com/saltstack/salt.git
synced 2025-04-17 10:10:20 +00:00
Merge pull request #39666 from terminalmage/test_valid_docs
Rewrite the test_valid_docs test
This commit is contained in:
commit
df013c5f31
6 changed files with 102 additions and 79 deletions
|
@ -679,7 +679,13 @@ class SMinion(MinionBase):
|
|||
|
||||
def gen_modules(self, initial_load=False):
|
||||
'''
|
||||
Load all of the modules for the minion
|
||||
Tell the minion to reload the execution modules
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' sys.reload_modules
|
||||
'''
|
||||
self.opts['pillar'] = salt.pillar.get_pillar(
|
||||
self.opts,
|
||||
|
@ -734,7 +740,13 @@ class MasterMinion(object):
|
|||
|
||||
def gen_modules(self, initial_load=False):
|
||||
'''
|
||||
Load all of the modules for the minion
|
||||
Tell the minion to reload the execution modules
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' sys.reload_modules
|
||||
'''
|
||||
self.utils = salt.loader.utils(self.opts)
|
||||
self.functions = salt.loader.minion_mods(
|
||||
|
|
|
@ -421,8 +421,10 @@ def reload_modules():
|
|||
|
||||
salt '*' sys.reload_modules
|
||||
'''
|
||||
# This is handled inside the minion.py file, the function is caught before
|
||||
# it ever gets here
|
||||
# This function is actually handled inside the minion.py file, the function
|
||||
# is caught before it ever gets here. Therefore, the docstring above is
|
||||
# only for the online docs, and ANY CHANGES made to it must also be made in
|
||||
# each of the gen_modules() funcs in minion.py.
|
||||
return True
|
||||
|
||||
|
||||
|
|
|
@ -1138,6 +1138,13 @@ class TestDaemon(object):
|
|||
TMP_PRODENV_STATE_TREE
|
||||
]
|
||||
}
|
||||
master_opts.setdefault('reactor', []).append(
|
||||
{
|
||||
'salt/minion/*/start': [
|
||||
os.path.join(FILES, 'reactor-sync-minion.sls')
|
||||
],
|
||||
}
|
||||
)
|
||||
for opts_dict in (master_opts, syndic_master_opts):
|
||||
if 'ext_pillar' not in opts_dict:
|
||||
opts_dict['ext_pillar'] = []
|
||||
|
|
|
@ -9,12 +9,16 @@
|
|||
|
||||
# Import python libs
|
||||
from __future__ import absolute_import
|
||||
import fnmatch
|
||||
import os
|
||||
import re
|
||||
import tempfile
|
||||
|
||||
# Import salt libs
|
||||
import salt.utils
|
||||
|
||||
# Import 3rd-party libs
|
||||
import salt.ext.six as six
|
||||
|
||||
SYS_TMP_DIR = os.path.realpath(
|
||||
# Avoid ${TMPDIR} and gettempdir() on MacOS as they yield a base path too long
|
||||
|
@ -29,9 +33,75 @@ TMP = os.path.join(SYS_TMP_DIR, 'salt-tests-tmpdir')
|
|||
def get_salt_temp_dir():
|
||||
return TMP
|
||||
|
||||
|
||||
def get_salt_temp_dir_for_path(*path):
|
||||
return os.path.join(TMP, *path)
|
||||
|
||||
|
||||
def get_sys_temp_dir_for_path(*path):
|
||||
return os.path.join(SYS_TMP_DIR, *path)
|
||||
|
||||
|
||||
def get_invalid_docs():
|
||||
'''
|
||||
Outputs the functions which do not have valid CLI example, or are missing a
|
||||
docstring.
|
||||
'''
|
||||
allow_failure = (
|
||||
'cmd.win_runas',
|
||||
'cp.recv',
|
||||
'glance.warn_until',
|
||||
'ipset.long_range',
|
||||
'libcloud_dns.get_driver',
|
||||
'log.critical',
|
||||
'log.debug',
|
||||
'log.error',
|
||||
'log.exception',
|
||||
'log.info',
|
||||
'log.warning',
|
||||
'lowpkg.bin_pkg_info',
|
||||
'lxc.run_cmd',
|
||||
'nspawn.restart',
|
||||
'nspawn.stop',
|
||||
'pkg.expand_repo_def',
|
||||
'pip.iteritems',
|
||||
'runtests_decorators.depends',
|
||||
'runtests_decorators.depends_will_fallback',
|
||||
'runtests_decorators.missing_depends',
|
||||
'runtests_decorators.missing_depends_will_fallback',
|
||||
'state.apply',
|
||||
'status.list2cmdline',
|
||||
'swift.head',
|
||||
'travisci.parse_qs',
|
||||
'vsphere.clean_kwargs',
|
||||
'vsphere.disconnect',
|
||||
'vsphere.get_service_instance_via_proxy',
|
||||
'vsphere.gets_service_instance_via_proxy',
|
||||
'vsphere.supports_proxies',
|
||||
'vsphere.test_vcenter_connection',
|
||||
'vsphere.wraps',
|
||||
)
|
||||
allow_failure_glob = (
|
||||
'runtests_helpers.*',
|
||||
)
|
||||
nodoc = set()
|
||||
noexample = set()
|
||||
for fun, docstring in six.iteritems(__salt__['sys.doc']()):
|
||||
if fun in allow_failure:
|
||||
continue
|
||||
else:
|
||||
for pat in allow_failure_glob:
|
||||
if fnmatch.fnmatch(fun, pat):
|
||||
matched_glob = True
|
||||
break
|
||||
else:
|
||||
matched_glob = False
|
||||
if matched_glob:
|
||||
continue
|
||||
if not isinstance(docstring, six.string_types):
|
||||
nodoc.add(fun)
|
||||
elif not re.search(r'([E|e]xample(?:s)?)+(?:.*):?', docstring):
|
||||
noexample.add(fun)
|
||||
|
||||
return {'missing_docstring': sorted(nodoc),
|
||||
'missing_cli_example': sorted(noexample)}
|
||||
|
|
3
tests/integration/files/reactor-sync-minion.sls
Normal file
3
tests/integration/files/reactor-sync-minion.sls
Normal file
|
@ -0,0 +1,3 @@
|
|||
sync_minion:
|
||||
local.saltutil.sync_all:
|
||||
- tgt: {{ data['id'] }}
|
|
@ -2,10 +2,6 @@
|
|||
|
||||
# Import python libs
|
||||
from __future__ import absolute_import
|
||||
import logging
|
||||
import re
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
# Import Salt Testing libs
|
||||
from salttesting.helpers import ensure_in_syspath
|
||||
|
@ -14,9 +10,6 @@ ensure_in_syspath('../../')
|
|||
# Import salt libs
|
||||
import integration
|
||||
|
||||
# Import 3rd-party libs
|
||||
import salt.ext.six as six
|
||||
|
||||
|
||||
class SysModuleTest(integration.ModuleCase):
|
||||
'''
|
||||
|
@ -26,79 +19,15 @@ class SysModuleTest(integration.ModuleCase):
|
|||
'''
|
||||
Make sure no functions are exposed that don't have valid docstrings
|
||||
'''
|
||||
mods = self.run_function('sys.list_modules')
|
||||
nodoc = set()
|
||||
noexample = set()
|
||||
allow_failure = (
|
||||
'cp.recv',
|
||||
'libcloud_dns.get_driver',
|
||||
'lxc.run_cmd',
|
||||
'ipset.long_range',
|
||||
'pkg.expand_repo_def',
|
||||
'runtests_decorators.depends',
|
||||
'runtests_decorators.depends_will_fallback',
|
||||
'runtests_decorators.missing_depends',
|
||||
'runtests_decorators.missing_depends_will_fallback',
|
||||
'swift.head',
|
||||
'glance.warn_until',
|
||||
'yumpkg.expand_repo_def',
|
||||
'yumpkg5.expand_repo_def',
|
||||
'container_resource.run',
|
||||
'nspawn.stop',
|
||||
'nspawn.restart',
|
||||
'lowpkg.bin_pkg_info',
|
||||
'state.apply',
|
||||
'pip.iteritems',
|
||||
'cmd.win_runas',
|
||||
'status.list2cmdline'
|
||||
)
|
||||
|
||||
batches = 2
|
||||
mod_count = len(mods)
|
||||
batch_size = mod_count / float(batches)
|
||||
if batch_size.is_integer():
|
||||
batch_size = int(batch_size)
|
||||
else:
|
||||
# Check if the module count is evenly divisible by the number of
|
||||
# batches. If not, increase the batch_size by the number of batches
|
||||
# being run. This ensures that we get the correct number of
|
||||
# batches, and that we don't end up running sys.doc an extra time
|
||||
# to cover the remainder. For example, if we had a batch count of 2
|
||||
# and 121 modules, if we just divided by 2 we'd end up running
|
||||
# sys.doc 3 times.
|
||||
batch_size = int(batch_size) + batches
|
||||
|
||||
log.debug('test_valid_docs batch size = %s', batch_size)
|
||||
start = 0
|
||||
end = batch_size
|
||||
while start <= mod_count:
|
||||
log.debug('running sys.doc on mods[%s:%s]', start, end)
|
||||
docs = self.run_function('sys.doc', mods[start:end])
|
||||
if docs == 'VALUE TRIMMED':
|
||||
self.fail(
|
||||
'sys.doc output trimmed. It may be necessary to increase '
|
||||
'the number of batches'
|
||||
)
|
||||
for fun in docs:
|
||||
if fun.startswith('runtests_helpers'):
|
||||
continue
|
||||
if fun in allow_failure:
|
||||
continue
|
||||
if not isinstance(docs[fun], six.string_types):
|
||||
nodoc.add(fun)
|
||||
elif not re.search(r'([E|e]xample(?:s)?)+(?:.*)::?', docs[fun]):
|
||||
noexample.add(fun)
|
||||
start += batch_size
|
||||
end += batch_size
|
||||
|
||||
if not nodoc and not noexample:
|
||||
ret = self.run_function('runtests_helpers.get_invalid_docs')
|
||||
if ret == {'missing_docstring': [], 'missing_cli_example': []}:
|
||||
return
|
||||
|
||||
raise AssertionError(
|
||||
'There are some functions which do not have a docstring or do not '
|
||||
'have an example:\nNo docstring:\n{0}\nNo example:\n{1}\n'.format(
|
||||
'\n'.join([' - {0}'.format(f) for f in sorted(nodoc)]),
|
||||
'\n'.join([' - {0}'.format(f) for f in sorted(noexample)]),
|
||||
'\n'.join([' - {0}'.format(f) for f in ret['missing_docstring']]),
|
||||
'\n'.join([' - {0}'.format(f) for f in ret['missing_cli_example']]),
|
||||
)
|
||||
)
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue