test_sysmod.py 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. import fnmatch
  2. import re
  3. import pytest
  4. from tests.support.helpers import slowTest
  5. @slowTest
  6. @pytest.mark.windows_whitelisted
  7. def test_valid_docs(salt_call_cli):
  8. """
  9. Make sure no functions are exposed that don't have valid docstrings
  10. """
  11. allow_failure = (
  12. "cmd.win_runas",
  13. "cp.recv",
  14. "cp.recv_chunked",
  15. "glance.warn_until",
  16. "ipset.long_range",
  17. "libcloud_compute.get_driver",
  18. "libcloud_dns.get_driver",
  19. "libcloud_loadbalancer.get_driver",
  20. "libcloud_storage.get_driver",
  21. "log.critical",
  22. "log.debug",
  23. "log.error",
  24. "log.exception",
  25. "log.info",
  26. "log.warning",
  27. "lowpkg.bin_pkg_info",
  28. "lxc.run_cmd",
  29. "mantest.install",
  30. "mantest.search",
  31. "nspawn.restart",
  32. "nspawn.stop",
  33. "pkg.expand_repo_def",
  34. "pip.iteritems",
  35. "pip.parse_version",
  36. "peeringdb.clean_kwargs",
  37. "runtests_decorators.depends",
  38. "runtests_decorators.depends_will_fallback",
  39. "runtests_decorators.missing_depends",
  40. "runtests_decorators.missing_depends_will_fallback",
  41. "state.apply",
  42. "status.list2cmdline",
  43. "swift.head",
  44. "test.rand_str",
  45. "travisci.parse_qs",
  46. "vsphere.clean_kwargs",
  47. "vsphere.disconnect",
  48. "vsphere.get_service_instance_via_proxy",
  49. "vsphere.gets_service_instance_via_proxy",
  50. "vsphere.supports_proxies",
  51. "vsphere.test_vcenter_connection",
  52. "vsphere.wraps",
  53. )
  54. allow_failure_glob = (
  55. "runtests_decorators.*",
  56. "runtests_helpers.*",
  57. "vsphere.*",
  58. )
  59. missing_example = set()
  60. missing_docstring = set()
  61. ret = salt_call_cli.run("sys.doc")
  62. assert ret.exitcode == 0, ret
  63. example_regex = re.compile(r"([E|e]xample(?:s)?)+(?:.*):?")
  64. for fun, docstring in ret.json.items():
  65. if fun in allow_failure:
  66. continue
  67. else:
  68. for pat in allow_failure_glob:
  69. if fnmatch.fnmatch(fun, pat):
  70. matched_glob = True
  71. break
  72. else:
  73. matched_glob = False
  74. if matched_glob:
  75. continue
  76. if not isinstance(docstring, str):
  77. missing_docstring.add(fun)
  78. elif isinstance(docstring, dict) and not example_regex.search(docstring):
  79. missing_example.add(fun)
  80. missing_docstring_error = "The following functions do not have a docstring: {}".format(
  81. ",".join([repr(func) for func in sorted(missing_docstring)])
  82. )
  83. assert not missing_docstring, missing_docstring_error
  84. missing_example_error = "The following functions do not have a CLI example: {}".format(
  85. ",".join([repr(func) for func in sorted(missing_example)])
  86. )
  87. assert not missing_example, missing_example_error