Replace tests/unit/test_doc.py with a pre-commit hook.

We don't need to test docs on all platforms. In turn, we make the check
a pre-commit hook which seems more suited.
This commit is contained in:
Pedro Algarvio 2020-04-20 21:56:50 +01:00
parent a5b9961f78
commit 6a4703146c
No known key found for this signature in database
GPG key ID: BB36BF6584A298FF
5 changed files with 476 additions and 601 deletions

View file

@ -598,3 +598,16 @@ repos:
- -e
- lint-tests-pre-commit
- --
- repo: https://github.com/saltstack/salt-nox-pre-commit
rev: master
hooks:
- id: nox-py2
alias: check-docs
name: Check Docs
files: ^(salt/.*\.py|doc/ref/.*\.rst)$
args:
- -e
- invoke-pre-commit
- --
- docs.check

View file

@ -1,5 +1,8 @@
# -*- coding: utf-8 -*-
from invoke import Collection # pylint: disable=3rd-party-module-not-gated
from . import docs
ns = Collection()
docs = Collection.from_module(docs, name="docs")
ns.add_collection(docs, name="docs")

459
tasks/docs.py Normal file
View file

@ -0,0 +1,459 @@
# -*- coding: utf-8 -*-
"""
tasks.docstrings
~~~~~~~~~~~~~~~~
Check salt code base for for missing or wrong docstrings
"""
import ast
import collections
import os
import pathlib
import re
from invoke import task # pylint: disable=3rd-party-module-not-gated
from tasks import utils
CODE_DIR = pathlib.Path(__file__).resolve().parent.parent
DOCS_DIR = CODE_DIR / "doc"
SALT_CODE_DIR = CODE_DIR / "salt"
os.chdir(str(CODE_DIR))
python_module_to_doc_path = {}
doc_path_to_python_module = {}
check_paths = (
"salt/auth",
"salt/beacons",
"salt/cache",
"salt/cloud",
"salt/engine",
"salt/executors",
"salt/fileserver",
"salt/grains",
"salt/modules",
"salt/netapi",
"salt/output",
"salt/pillar",
"salt/proxy",
"salt/queues",
"salt/renderers",
"salt/returners",
"salt/roster",
"salt/runners",
"salt/sdb",
"salt/serializers",
"salt/states",
"salt/thorium",
"salt/tokens",
"salt/tops",
"salt/wheel",
)
exclude_paths = (
"salt/cloud/cli.py",
"salt/cloud/exceptions.py",
"salt/cloud/libcloudfuncs.py",
)
def build_path_cache():
"""
Build a python module to doc module cache
"""
for path in SALT_CODE_DIR.rglob("*.py"):
path = path.resolve().relative_to(CODE_DIR)
strpath = str(path)
if strpath.endswith("__init__.py"):
continue
if not strpath.startswith(check_paths):
continue
if strpath.startswith(exclude_paths):
continue
parts = list(path.parts)
stub_path = DOCS_DIR / "ref"
# Remove salt from parts
parts.pop(0)
# Remove the package from parts
package = parts.pop(0)
# Remove the module from parts
module = parts.pop()
if package == "cloud":
package = "clouds"
if package == "fileserver":
package = "file_server"
if package == "netapi":
# These are handled differently
if not parts:
# This is rest_wsgi
stub_path = (
stub_path
/ package
/ "all"
/ str(path).replace(".py", ".rst").replace(os.sep, ".")
)
else:
# rest_cherrypy, rest_tornado
subpackage = parts.pop(0)
stub_path = (
stub_path
/ package
/ "all"
/ "salt.netapi.{}.rst".format(subpackage)
)
else:
stub_path = (
stub_path
/ package
/ "all"
/ str(path).replace(".py", ".rst").replace(os.sep, ".")
)
stub_path = stub_path.relative_to(CODE_DIR)
python_module_to_doc_path[path] = stub_path
doc_path_to_python_module[stub_path] = path
build_path_cache()
def build_file_list(files, extension):
# Unfortunately invoke does not support nargs.
# We migth have been passed --files="foo.py bar.py"
# Turn that into a list of paths
_files = []
for path in files:
if not path:
continue
for spath in path.split():
if not spath.endswith(extension):
continue
_files.append(spath)
if not _files:
_files = CODE_DIR.rglob("*{}".format(extension))
else:
_files = [pathlib.Path(fname) for fname in _files]
_files = [path.relative_to(CODE_DIR) for path in _files]
return _files
def build_python_module_paths(files):
_files = []
for path in build_file_list(files, ".py"):
strpath = str(path)
if strpath.endswith("__init__.py"):
continue
if not strpath.startswith(check_paths):
continue
if strpath.startswith(exclude_paths):
continue
_files.append(path)
return _files
def build_docs_paths(files):
return build_file_list(files, ".rst")
@task(iterable=["files"], positional=["files"])
def check_inline_markup(ctx, files):
"""
Check docstring for :doc: usage
We should not be using the ``:doc:`` inline markup option when
cross-referencing locations. Use ``:ref:`` or ``:mod:`` instead.
This task checks for reference to ``:doc:`` usage.
See Issue #12788 for more information.
https://github.com/saltstack/salt/issues/12788
"""
# CD into Salt's repo root directory
ctx.cd(CODE_DIR)
files = build_python_module_paths(files)
exitcode = 0
for path in files:
module = ast.parse(path.read_text(), filename=str(path))
funcdefs = [node for node in module.body if isinstance(node, ast.FunctionDef)]
for funcdef in funcdefs:
docstring = ast.get_docstring(funcdef, clean=True)
if not docstring:
continue
if ":doc:" in docstring:
utils.error(
"The {} function in {} contains ':doc:' usage", funcdef.name, path
)
exitcode += 1
utils.exit_invoke(exitcode)
@task(iterable=["files"])
def check_stubs(ctx, files):
# CD into Salt's repo root directory
ctx.cd(CODE_DIR)
files = build_python_module_paths(files)
exitcode = 0
for path in files:
strpath = str(path)
if strpath.endswith("__init__.py"):
continue
if not strpath.startswith(check_paths):
continue
if strpath.startswith(exclude_paths):
continue
stub_path = python_module_to_doc_path[path]
if not stub_path.exists():
exitcode += 1
utils.error(
"The module at {} does not have a sphinx stub at {}", path, stub_path
)
utils.exit_invoke(exitcode)
@task(iterable=["files"])
def check_virtual(ctx, files):
"""
Check if .rst files for each module contains the text ".. _virtual"
indicating it is a virtual doc page, and, in case a module exists by
the same name, it's going to be shaddowed and not accessible
"""
exitcode = 0
files = build_docs_paths(files)
for path in files:
if path.name == "index.rst":
continue
contents = path.read_text()
if ".. _virtual-" in contents:
try:
python_module = doc_path_to_python_module[path]
utils.error(
"The doc file at {} indicates that it's virtual, yet, there's a python module "
"at {} that will shaddow it.",
path,
python_module,
)
exitcode += 1
except KeyError:
# This is what we're expecting
continue
utils.exit_invoke(exitcode)
@task(iterable=["files"])
def check_module_indexes(ctx, files):
exitcode = 0
files = build_docs_paths(files)
for path in files:
if path.name != "index.rst":
continue
contents = path.read_text()
if ".. autosummary::" not in contents:
continue
module_index_block = re.search(
r"""
\.\.\s+autosummary::\s*\n
(\s+:[a-z]+:.*\n)*
(\s*\n)+
(?P<mods>(\s*[a-z0-9_\.]+\s*\n)+)
""",
contents,
flags=re.VERBOSE,
)
if not module_index_block:
continue
module_index = re.findall(
r"""\s*([a-z0-9_\.]+)\s*\n""", module_index_block.group("mods")
)
if module_index != sorted(module_index):
exitcode += 1
utils.error(
"The autosummary mods in {} are not properly sorted. Please sort them.",
path,
)
module_index_duplicates = [
mod for mod, count in collections.Counter(module_index).items() if count > 1
]
if module_index_duplicates:
exitcode += 1
utils.error(
"Module index {} contains duplicates: {}", path, module_index_duplicates
)
# Let's check if all python modules are included in the index
path_parts = list(path.parts)
# drop doc
path_parts.pop(0)
# drop ref
path_parts.pop(0)
# drop "index.rst"
path_parts.pop()
# drop "all"
path_parts.pop()
package = path_parts.pop(0)
if package == "clouds":
package = "cloud"
if package == "file_server":
package = "fileserver"
if package == "configuration":
package = "log"
path_parts = ["handlers"]
python_package = SALT_CODE_DIR.joinpath(package, *path_parts).relative_to(
CODE_DIR
)
modules = set()
for module in python_package.rglob("*.py"):
if package == "netapi":
if module.stem == "__init__":
continue
if len(module.parts) > 4:
continue
if len(module.parts) > 3:
modules.add(module.parent.stem)
else:
modules.add(module.stem)
elif package == "cloud":
if len(module.parts) < 4:
continue
if module.name == "__init__.py":
continue
modules.add(module.stem)
elif package == "modules":
if len(module.parts) > 3:
# salt.modules.inspeclib
if module.name == "__init__.py":
modules.add(module.parent.stem)
continue
modules.add("{}.{}".format(module.parent.stem, module.stem))
continue
if module.name == "__init__.py":
continue
modules.add(module.stem)
elif module.name == "__init__.py":
continue
elif module.name != "__init__.py":
modules.add(module.stem)
missing_modules_in_index = set(modules) - set(module_index)
if missing_modules_in_index:
exitcode += 1
utils.error(
"The module index at {} is missing the following modules: {}",
path,
", ".join(missing_modules_in_index),
)
extra_modules_in_index = set(module_index) - set(modules)
if extra_modules_in_index:
exitcode += 1
utils.error(
"The module index at {} has extra modules(non existing): {}",
path,
", ".join(extra_modules_in_index),
)
utils.exit_invoke(exitcode)
@task(iterable=["files"])
def check_stray(ctx, files):
exitcode = 0
exclude_paths = (
DOCS_DIR / "_inc",
DOCS_DIR / "ref" / "cli" / "_includes",
DOCS_DIR / "ref" / "cli",
DOCS_DIR / "ref" / "configuration",
DOCS_DIR / "ref" / "file_server" / "backends.rst",
DOCS_DIR / "ref" / "file_server" / "environments.rst",
DOCS_DIR / "ref" / "file_server" / "file_roots.rst",
DOCS_DIR / "ref" / "internals",
DOCS_DIR / "ref" / "modules" / "all" / "salt.modules.inspectlib.rst",
DOCS_DIR / "ref" / "peer.rst",
DOCS_DIR / "ref" / "publisheracl.rst",
DOCS_DIR / "ref" / "python-api.rst",
DOCS_DIR / "ref" / "states" / "aggregate.rst",
DOCS_DIR / "ref" / "states" / "altering_states.rst",
DOCS_DIR / "ref" / "states" / "backup_mode.rst",
DOCS_DIR / "ref" / "states" / "compiler_ordering.rst",
DOCS_DIR / "ref" / "states" / "extend.rst",
DOCS_DIR / "ref" / "states" / "failhard.rst",
DOCS_DIR / "ref" / "states" / "global_state_arguments.rst",
DOCS_DIR / "ref" / "states" / "highstate.rst",
DOCS_DIR / "ref" / "states" / "include.rst",
DOCS_DIR / "ref" / "states" / "layers.rst",
DOCS_DIR / "ref" / "states" / "master_side.rst",
DOCS_DIR / "ref" / "states" / "ordering.rst",
DOCS_DIR / "ref" / "states" / "parallel.rst",
DOCS_DIR / "ref" / "states" / "providers.rst",
DOCS_DIR / "ref" / "states" / "requisites.rst",
DOCS_DIR / "ref" / "states" / "startup.rst",
DOCS_DIR / "ref" / "states" / "testing.rst",
DOCS_DIR / "ref" / "states" / "top.rst",
DOCS_DIR / "ref" / "states" / "vars.rst",
DOCS_DIR / "ref" / "states" / "writing.rst",
DOCS_DIR / "topics",
)
exclude_paths = tuple([str(p.relative_to(CODE_DIR)) for p in exclude_paths])
files = build_docs_paths(files)
for path in files:
if not str(path).startswith(str((DOCS_DIR / "ref").relative_to(CODE_DIR))):
continue
if str(path).startswith(exclude_paths):
continue
if path.name in ("index.rst", "glossary.rst", "faq.rst", "README.rst"):
continue
try:
python_module = doc_path_to_python_module[path]
except KeyError:
contents = path.read_text()
if ".. _virtual-" in contents:
continue
exitcode += 1
utils.error(
"The doc at {} doesn't have a corresponding python module an is considered a stray "
"doc. Please remove it.",
path,
)
utils.exit_invoke(exitcode)
@task(iterable=["files"])
def check(ctx, files):
try:
utils.info("Checking inline :doc: markup")
check_inline_markup(ctx, files)
except SystemExit as exc:
if exc.code != 0:
raise
try:
utils.info("Checking python module stubs")
check_stubs(ctx, files)
except SystemExit as exc:
if exc.code != 0:
raise
try:
utils.info("Checking virtual modules")
check_virtual(ctx, files)
except SystemExit as exc:
if exc.code != 0:
raise
try:
utils.info("Checking doc module indexes")
check_module_indexes(ctx, files)
except SystemExit as exc:
if exc.code != 0:
raise
try:
utils.info("Checking stray docs")
check_stray(ctx, files)
except SystemExit as exc:
if exc.code != 0:
raise

View file

@ -2,6 +2,7 @@
"""
tasks.utils
~~~~~~~~~~~
Invoke utilities
"""

View file

@ -1,601 +0,0 @@
# -*- coding: utf-8 -*-
"""
tests.unit.doc_test
~~~~~~~~~~~~~~~~~~~~
"""
# Import Python libs
from __future__ import absolute_import
import collections
import logging
import os
import re
# Import Salt libs
import salt.modules.cmdmod
import salt.utils.files
import salt.utils.platform
from tests.support.runtests import RUNTIME_VARS
# Import Salt Testing libs
from tests.support.unit import TestCase, skipIf
log = logging.getLogger(__name__)
class DocTestCase(TestCase):
"""
Unit test case for testing doc files and strings.
"""
@skipIf(True, "SLOWTEST skip")
def test_check_for_doc_inline_markup(self):
"""
We should not be using the ``:doc:`` inline markup option when
cross-referencing locations. Use ``:ref:`` or ``:mod:`` instead.
This test checks for reference to ``:doc:`` usage.
See Issue #12788 for more information.
https://github.com/saltstack/salt/issues/12788
"""
salt_dir = RUNTIME_VARS.CODE_DIR
if salt.utils.platform.is_windows():
if salt.utils.path.which("bash"):
# Use grep from git-bash when it exists.
cmd = "bash -c 'grep -r :doc: ./salt/"
grep_call = salt.modules.cmdmod.run_stdout(cmd=cmd, cwd=salt_dir).split(
os.linesep
)
os_sep = "/"
else:
# No grep in Windows, use findstr
# findstr in windows doesn't prepend 'Binary` to binary files, so
# use the '/P' switch to skip files with unprintable characters
cmd = 'findstr /C:":doc:" /S /P {0}\\*'.format(salt_dir)
grep_call = salt.modules.cmdmod.run_stdout(cmd=cmd).split(os.linesep)
os_sep = os.sep
else:
salt_dir += "/"
cmd = "grep -r :doc: " + salt_dir
grep_call = salt.modules.cmdmod.run_stdout(cmd=cmd).split(os.linesep)
os_sep = os.sep
test_ret = {}
for line in grep_call:
# Skip any .pyc files that may be present
if line.startswith("Binary"):
continue
# Only split on colons not followed by a '\' as is the case with
# Windows Drives
regex = re.compile(r":(?!\\)")
try:
key, val = regex.split(line, 1)
except ValueError:
log.error("Could not split line: %s", line)
continue
# Don't test man pages, this file, the tox or nox virtualenv files,
# the page that documents to not use ":doc:", the doc/conf.py file
# or the artifacts directory on nox CI test runs
if (
"man" in key
or ".tox{}".format(os_sep) in key
or ".nox{}".format(os_sep) in key
or "ext{}".format(os_sep) in key
or "artifacts{}".format(os_sep) in key
or key.endswith("test_doc.py")
or key.endswith(os_sep.join(["doc", "conf.py"]))
or key.endswith(os_sep.join(["conventions", "documentation.rst"]))
or key.endswith(
os_sep.join(["doc", "topics", "releases", "2016.11.2.rst"])
)
or key.endswith(
os_sep.join(["doc", "topics", "releases", "2016.11.3.rst"])
)
or key.endswith(
os_sep.join(["doc", "topics", "releases", "2016.3.5.rst"])
)
):
continue
# Set up test return dict
if test_ret.get(key) is None:
test_ret[key] = [val.strip()]
else:
test_ret[key].append(val.strip())
# Allow test results to show files with :doc: ref, rather than truncating
self.maxDiff = None
# test_ret should be empty, otherwise there are :doc: references present
self.assertEqual(test_ret, {})
def _check_doc_files(self, module_skip, module_dir, doc_skip, module_doc_dir):
"""
Ensure various salt modules have associated documentation
"""
salt_dir = RUNTIME_VARS.CODE_DIR
# Build list of module files
module_files = []
skip_module_files = module_skip
full_module_dir = os.path.join(salt_dir, *module_dir)
for file in os.listdir(full_module_dir):
if file.endswith(".py"):
module_name = os.path.splitext(file)[0]
if module_name not in skip_module_files:
module_files.append(module_name)
# Capture modules in subdirectories like inspectlib and rest_cherrypy
elif (
os.path.isdir(os.path.join(full_module_dir, file))
and not file.startswith("_")
and os.path.isfile(os.path.join(full_module_dir, file, "__init__.py"))
):
module_name = file
if module_name not in skip_module_files:
module_files.append(module_name)
# Build list of documentation files
module_docs = []
skip_doc_files = doc_skip
full_module_doc_dir = os.path.join(salt_dir, *module_doc_dir)
doc_prefix = ".".join(module_dir) + "."
for file in os.listdir(full_module_doc_dir):
if file.endswith(".rst"):
doc_name = os.path.splitext(file)[0]
if doc_name.startswith(doc_prefix):
doc_name = doc_name[len(doc_prefix) :]
if doc_name not in skip_doc_files:
module_docs.append(doc_name)
module_index_file = os.path.join(full_module_doc_dir, "index.rst")
with salt.utils.files.fopen(module_index_file, "rb") as fp:
module_index_contents = fp.read().decode("utf-8")
module_index_block = re.search(
r"""
\.\.\s+autosummary::\s*\n
(\s+:[a-z]+:.*\n)*
(\s*\n)+
(?P<mods>(\s*[a-z0-9_\.]+\s*\n)+)
""",
module_index_contents,
flags=re.VERBOSE,
)
module_index = re.findall(
r"""\s*([a-z0-9_\.]+)\s*\n""", module_index_block.group("mods")
)
# Check that every module has associated documentation file
for module in module_files:
self.assertIn(
module,
module_docs,
"module file {0} is missing documentation in {1}".format(
module, full_module_doc_dir
),
)
# Check that every module is listed in the index file
self.assertIn(
module,
module_index,
"module file {0} is missing in {1}".format(module, module_index_file),
)
# Check if .rst file for this module contains the text
# ".. _virtual" indicating it is a virtual doc page
full_module_doc_name = os.path.join(
full_module_doc_dir, doc_prefix + module + ".rst"
)
with salt.utils.files.fopen(full_module_doc_name) as rst_file:
rst_text = rst_file.read()
virtual_string = 'module file "{0}" is also a virtual doc page {1} and is not accessible'
self.assertNotIn(
".. _virtual",
rst_text,
virtual_string.format(module, doc_prefix + module + ".rst"),
)
for doc_file in module_docs:
self.assertIn(
doc_file,
module_files,
"Doc file {0} is missing associated module in {1}".format(
doc_file, full_module_dir
),
)
# Check that a module index is sorted
sorted_module_index = sorted(module_index)
self.assertEqual(
module_index,
sorted_module_index,
msg="Module index is not sorted: {}".format(module_index_file),
)
# Check for duplicates inside of a module index
module_index_duplicates = [
mod for mod, count in collections.Counter(module_index).items() if count > 1
]
if module_index_duplicates:
self.fail(
"Module index {0} contains duplicates: {1}".format(
module_index_file, module_index_duplicates
)
)
# Check for stray module docs
# Do not check files listed in doc_skip
stray_modules = set(module_index).difference(module_files + doc_skip)
if stray_modules:
self.fail(
"Stray module names {0} in the doc index {1}".format(
sorted(list(stray_modules)), module_index_file
)
)
stray_modules = set(module_docs).difference(module_files)
if stray_modules:
self.fail(
"Stray module doc files {0} in the doc folder {1}".format(
sorted(list(stray_modules)), full_module_doc_dir
)
)
def test_auth_doc_files(self):
"""
Ensure auth modules have associated documentation
doc example: doc/ref/auth/all/salt.auth.rest.rst
auth module example: salt/auth/rest.py
"""
skip_files = ["__init__"]
module_dir = ["salt", "auth"]
skip_doc_files = ["index", "all"]
doc_dir = ["doc", "ref", "auth", "all"]
self._check_doc_files(skip_files, module_dir, skip_doc_files, doc_dir)
def test_beacon_doc_files(self):
"""
Ensure beacon modules have associated documentation
doc example: doc/ref/beacons/all/salt.beacon.rest.rst
beacon module example: salt/beacons/rest.py
"""
skip_files = ["__init__"]
module_dir = ["salt", "beacons"]
skip_doc_files = ["index", "all"]
doc_dir = ["doc", "ref", "beacons", "all"]
self._check_doc_files(skip_files, module_dir, skip_doc_files, doc_dir)
def test_cache_doc_files(self):
"""
Ensure cache modules have associated documentation
doc example: doc/ref/cache/all/salt.cache.consul.rst
cache module example: salt/cache/consul.py
"""
skip_module_files = ["__init__"]
module_dir = ["salt", "cache"]
skip_doc_files = ["index", "all"]
doc_dir = ["doc", "ref", "cache", "all"]
self._check_doc_files(skip_module_files, module_dir, skip_doc_files, doc_dir)
def test_cloud_doc_files(self):
"""
Ensure cloud modules have associated documentation
doc example: doc/ref/clouds/all/salt.cloud.gce.rst
cloud module example: salt/cloud/clouds/gce.py
"""
skip_module_files = ["__init__"]
module_dir = ["salt", "cloud", "clouds"]
skip_doc_files = ["index", "all"]
doc_dir = ["doc", "ref", "clouds", "all"]
self._check_doc_files(skip_module_files, module_dir, skip_doc_files, doc_dir)
def test_engine_doc_files(self):
"""
Ensure engine modules have associated documentation
doc example: doc/ref/engines/all/salt.engines.docker_events.rst
engine module example: salt/engines/docker_events.py
"""
skip_module_files = ["__init__"]
module_dir = ["salt", "engines"]
skip_doc_files = ["index", "all"]
doc_dir = ["doc", "ref", "engines", "all"]
self._check_doc_files(skip_module_files, module_dir, skip_doc_files, doc_dir)
def test_executors_doc_files(self):
"""
Ensure executor modules have associated documentation
doc example: doc/ref/executors/all/salt.executors.docker.rst
engine module example: salt/executors/docker.py
"""
skip_module_files = ["__init__"]
module_dir = ["salt", "executors"]
skip_doc_files = ["index", "all"]
doc_dir = ["doc", "ref", "executors", "all"]
self._check_doc_files(skip_module_files, module_dir, skip_doc_files, doc_dir)
def test_fileserver_doc_files(self):
"""
Ensure fileserver modules have associated documentation
doc example: doc/ref/fileserver/all/salt.fileserver.gitfs.rst
module example: salt/fileserver/gitfs.py
"""
skip_module_files = ["__init__"]
module_dir = ["salt", "fileserver"]
skip_doc_files = ["index", "all"]
doc_dir = ["doc", "ref", "file_server", "all"]
self._check_doc_files(skip_module_files, module_dir, skip_doc_files, doc_dir)
def test_grain_doc_files(self):
"""
Ensure grain modules have associated documentation
doc example: doc/ref/grains/all/salt.grains.core.rst
module example: salt/grains/core.py
"""
skip_module_files = ["__init__"]
module_dir = ["salt", "grains"]
skip_doc_files = ["index", "all"]
doc_dir = ["doc", "ref", "grains", "all"]
self._check_doc_files(skip_module_files, module_dir, skip_doc_files, doc_dir)
def test_module_doc_files(self):
"""
Ensure modules have associated documentation
doc example: doc/ref/modules/all/salt.modules.zabbix.rst
execution module example: salt/modules/zabbix.py
"""
skip_module_files = ["__init__"]
module_dir = ["salt", "modules"]
skip_doc_files = [
"index",
"group",
"inspectlib.collector",
"inspectlib.dbhandle",
"inspectlib.entities",
"inspectlib.exceptions",
"inspectlib.fsdb",
"inspectlib.kiwiproc",
"inspectlib.query",
"kernelpkg",
"pkg",
"user",
"service",
"shadow",
"sysctl",
]
doc_dir = ["doc", "ref", "modules", "all"]
self._check_doc_files(skip_module_files, module_dir, skip_doc_files, doc_dir)
def test_netapi_doc_files(self):
"""
Ensure netapi modules have associated documentation
doc example: doc/ref/netapi/all/salt.netapi.rest_cherrypy.rst
module example: salt/netapi/rest_cherrypy
"""
skip_module_files = ["__init__"]
module_dir = ["salt", "netapi"]
skip_doc_files = ["index", "all"]
doc_dir = ["doc", "ref", "netapi", "all"]
self._check_doc_files(skip_module_files, module_dir, skip_doc_files, doc_dir)
def test_output_doc_files(self):
"""
Ensure output modules have associated documentation
doc example: doc/ref/output/all/salt.output.highstate.rst
module example: salt/output/highstate.py
"""
skip_module_files = ["__init__"]
module_dir = ["salt", "output"]
skip_doc_files = ["index", "all"]
doc_dir = ["doc", "ref", "output", "all"]
self._check_doc_files(skip_module_files, module_dir, skip_doc_files, doc_dir)
def test_pillar_doc_files(self):
"""
Ensure pillar modules have associated documentation
doc example: doc/ref/pillar/all/salt.pillar.cobbler.rst
module example: salt/pillar/cobbler.py
"""
skip_module_files = ["__init__"]
module_dir = ["salt", "pillar"]
skip_doc_files = ["index", "all"]
doc_dir = ["doc", "ref", "pillar", "all"]
self._check_doc_files(skip_module_files, module_dir, skip_doc_files, doc_dir)
def test_proxy_doc_files(self):
"""
Ensure proxy modules have associated documentation
doc example: doc/ref/proxy/all/salt.proxy.docker.rst
module example: salt/proxy/docker.py
"""
skip_module_files = ["__init__"]
module_dir = ["salt", "proxy"]
skip_doc_files = ["index", "all"]
doc_dir = ["doc", "ref", "proxy", "all"]
self._check_doc_files(skip_module_files, module_dir, skip_doc_files, doc_dir)
def test_queues_doc_files(self):
"""
Ensure queue modules have associated documentation
doc example: doc/ref/queues/all/salt.queues.sqlite_queue.rst
module example: salt/queues/sqlite_queue.py
"""
skip_module_files = ["__init__"]
module_dir = ["salt", "queues"]
skip_doc_files = ["index", "all"]
doc_dir = ["doc", "ref", "queues", "all"]
self._check_doc_files(skip_module_files, module_dir, skip_doc_files, doc_dir)
def test_renderers_doc_files(self):
"""
Ensure render modules have associated documentation
doc example: doc/ref/renderers/all/salt.renderers.json.rst
module example: salt/renderers/json.py
"""
skip_module_files = ["__init__"]
module_dir = ["salt", "renderers"]
skip_doc_files = ["index", "all"]
doc_dir = ["doc", "ref", "renderers", "all"]
self._check_doc_files(skip_module_files, module_dir, skip_doc_files, doc_dir)
def test_returners_doc_files(self):
"""
Ensure return modules have associated documentation
doc example: doc/ref/returners/all/salt.returners.cassandra_return.rst
module example: salt/returners/cassandra_return.py
"""
skip_module_files = ["__init__"]
module_dir = ["salt", "returners"]
skip_doc_files = ["index", "all"]
doc_dir = ["doc", "ref", "returners", "all"]
self._check_doc_files(skip_module_files, module_dir, skip_doc_files, doc_dir)
def test_runners_doc_files(self):
"""
Ensure runner modules have associated documentation
doc example: doc/ref/runners/all/salt.runners.auth.rst
module example: salt/runners/auth.py
"""
skip_module_files = ["__init__"]
module_dir = ["salt", "runners"]
skip_doc_files = ["index", "all"]
doc_dir = ["doc", "ref", "runners", "all"]
self._check_doc_files(skip_module_files, module_dir, skip_doc_files, doc_dir)
def test_sdb_doc_files(self):
"""
Ensure sdb modules have associated documentation
doc example: doc/ref/sdb/all/salt.sdb.rest.rst
module example: salt/sdb/rest.py
"""
skip_module_files = ["__init__"]
module_dir = ["salt", "sdb"]
skip_doc_files = ["index", "all"]
doc_dir = ["doc", "ref", "sdb", "all"]
self._check_doc_files(skip_module_files, module_dir, skip_doc_files, doc_dir)
def test_serializers_doc_files(self):
"""
Ensure serializer modules have associated documentation
doc example: doc/ref/serializers/all/salt.serializers.yaml.rst
module example: salt/serializers/yaml.py
"""
skip_module_files = ["__init__"]
module_dir = ["salt", "serializers"]
skip_doc_files = ["index", "all"]
doc_dir = ["doc", "ref", "serializers", "all"]
self._check_doc_files(skip_module_files, module_dir, skip_doc_files, doc_dir)
def test_states_doc_files(self):
"""
Ensure states have associated documentation
doc example: doc/ref/states/all/salt.states.zabbix_host.rst
module example: salt/states/zabbix_host.py
"""
skip_module_files = ["__init__"]
module_dir = ["salt", "states"]
skip_doc_files = ["index", "all"]
doc_dir = ["doc", "ref", "states", "all"]
self._check_doc_files(skip_module_files, module_dir, skip_doc_files, doc_dir)
def test_thorium_doc_files(self):
"""
Ensure thorium modules have associated documentation
doc example: doc/ref/thorium/all/salt.thorium.calc.rst
module example: salt/thorium/calc.py
"""
skip_module_files = ["__init__"]
module_dir = ["salt", "thorium"]
skip_doc_files = ["index", "all"]
doc_dir = ["doc", "ref", "thorium", "all"]
self._check_doc_files(skip_module_files, module_dir, skip_doc_files, doc_dir)
def test_token_doc_files(self):
"""
Ensure token modules have associated documentation
doc example: doc/ref/tokens/all/salt.tokens.localfs.rst
module example: salt/tokens/localfs.py
"""
skip_module_files = ["__init__"]
module_dir = ["salt", "tokens"]
skip_doc_files = ["index", "all"]
doc_dir = ["doc", "ref", "tokens", "all"]
self._check_doc_files(skip_module_files, module_dir, skip_doc_files, doc_dir)
def test_tops_doc_files(self):
"""
Ensure top modules have associated documentation
doc example: doc/ref/tops/all/salt.tops.saltclass.rst
module example: salt/tops/saltclass.py
"""
skip_module_files = ["__init__"]
module_dir = ["salt", "tops"]
skip_doc_files = ["index", "all"]
doc_dir = ["doc", "ref", "tops", "all"]
self._check_doc_files(skip_module_files, module_dir, skip_doc_files, doc_dir)
def test_wheel_doc_files(self):
"""
Ensure wheel modules have associated documentation
doc example: doc/ref/wheel/all/salt.wheel.key.rst
module example: salt/wheel/key.py
"""
skip_module_files = ["__init__"]
module_dir = ["salt", "wheel"]
skip_doc_files = ["index", "all"]
doc_dir = ["doc", "ref", "wheel", "all"]
self._check_doc_files(skip_module_files, module_dir, skip_doc_files, doc_dir)