Merge pull request #39666 from terminalmage/test_valid_docs

Rewrite the test_valid_docs test
This commit is contained in:
Pedro Algarvio 2017-02-26 20:14:32 +00:00 committed by GitHub
commit df013c5f31
6 changed files with 102 additions and 79 deletions

View file

@ -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(

View file

@ -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

View file

@ -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'] = []

View file

@ -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)}

View file

@ -0,0 +1,3 @@
sync_minion:
local.saltutil.sync_all:
- tgt: {{ data['id'] }}

View file

@ -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']]),
)
)