X-Git-Url: https://code.grnet.gr/git/ganeti-local/blobdiff_plain/6915bc28fe053e92aa16cf2d974d205f1140219c..8f9a87c57f0c6de8a2176f8c988e26d6efb2b50d:/test/docs_unittest.py diff --git a/test/docs_unittest.py b/test/docs_unittest.py index 6e66748..6959616 100755 --- a/test/docs_unittest.py +++ b/test/docs_unittest.py @@ -28,11 +28,15 @@ from ganeti import _autoconf from ganeti import utils from ganeti import cmdlib from ganeti import build +from ganeti import compat from ganeti.rapi import connector import testutils +VALID_URI_RE = re.compile(r"^[-/a-z0-9]*$") + + class TestDocs(unittest.TestCase): """Documentation tests""" @@ -68,6 +72,17 @@ class TestDocs(unittest.TestCase): msg=("Missing documentation for hook %s/%s" % (lucls.HTYPE, lucls.HPATH))) + def _CheckRapiResource(self, uri, fixup, handler): + docline = "%s resource." % uri + self.assertEqual(handler.__doc__.splitlines()[0].strip(), docline, + msg=("First line of %r's docstring is not %r" % + (handler, docline))) + + # Apply fixes before testing + for (rx, value) in fixup.items(): + uri = rx.sub(value, uri) + + self.assertTrue(VALID_URI_RE.match(uri), msg="Invalid URI %r" % uri) def testRapiDocs(self): """Check whether all RAPI resources are documented. @@ -75,13 +90,33 @@ class TestDocs(unittest.TestCase): """ rapidoc = self._ReadDocFile("rapi.rst") - node_name = "[node_name]" - instance_name = "[instance_name]" - job_id = "[job_id]" - - resources = connector.GetHandlers(re.escape(node_name), - re.escape(instance_name), - re.escape(job_id)) + node_name = re.escape("[node_name]") + instance_name = re.escape("[instance_name]") + group_name = re.escape("[group_name]") + job_id = re.escape("[job_id]") + disk_index = re.escape("[disk_index]") + query_res = re.escape("[resource]") + + resources = connector.GetHandlers(node_name, instance_name, group_name, + job_id, disk_index, query_res) + + handler_dups = utils.FindDuplicates(resources.values()) + self.assertFalse(handler_dups, + msg=("Resource handlers used more than once: %r" % + handler_dups)) + + uri_check_fixup = { + re.compile(node_name): "node1examplecom", + re.compile(instance_name): "inst1examplecom", + re.compile(group_name): "group4440", + re.compile(job_id): "9409", + re.compile(disk_index): "123", + re.compile(query_res): "lock", + } + + assert compat.all(VALID_URI_RE.match(value) + for value in uri_check_fixup.values()), \ + "Fixup values must be valid URIs, too" titles = [] @@ -92,29 +127,50 @@ class TestDocs(unittest.TestCase): prevline = line + prefix_exception = frozenset(["/", "/version", "/2"]) + undocumented = [] + used_uris = [] for key, handler in resources.iteritems(): # Regex objects if hasattr(key, "match"): + self.assert_(key.pattern.startswith("^/2/"), + msg="Pattern %r does not start with '^/2/'" % key.pattern) + self.assertEqual(key.pattern[-1], "$") + found = False for title in titles: - if (title.startswith("``") and - title.endswith("``") and - key.match(title[2:-2])): - found = True - break + if title.startswith("``") and title.endswith("``"): + uri = title[2:-2] + if key.match(uri): + self._CheckRapiResource(uri, uri_check_fixup, handler) + used_uris.append(uri) + found = True + break if not found: # TODO: Find better way of identifying resource - undocumented.append(str(handler)) + undocumented.append(key.pattern) - elif ("``%s``" % key) not in titles: - undocumented.append(key) + else: + self.assert_(key.startswith("/2/") or key in prefix_exception, + msg="Path %r does not start with '/2/'" % key) + + if ("``%s``" % key) in titles: + self._CheckRapiResource(key, {}, handler) + used_uris.append(key) + else: + undocumented.append(key) self.failIf(undocumented, msg=("Missing RAPI resource documentation for %s" % - " ,".join(undocumented))) + utils.CommaJoin(undocumented))) + + uri_dups = utils.FindDuplicates(used_uris) + self.failIf(uri_dups, + msg=("URIs matched by more than one resource: %s" % + utils.CommaJoin(uri_dups))) class TestManpages(unittest.TestCase): @@ -122,7 +178,7 @@ class TestManpages(unittest.TestCase): @staticmethod def _ReadManFile(name): - return utils.ReadFile("%s/man/%s.sgml" % + return utils.ReadFile("%s/man/%s.rst" % (testutils.GetSourceDir(), name)) @staticmethod @@ -139,14 +195,14 @@ class TestManpages(unittest.TestCase): missing = [] for cmd in commands: - pattern = "\s*%s" % re.escape(cmd) - if not re.findall(pattern, mantext, re.S): + pattern = r"^(\| )?\*\*%s\*\*" % re.escape(cmd) + if not re.findall(pattern, mantext, re.DOTALL | re.MULTILINE): missing.append(cmd) self.failIf(missing, msg=("Manpage for '%s' missing documentation for %s" % - (script, " ,".join(missing)))) + (script, utils.CommaJoin(missing)))) if __name__ == "__main__": - unittest.main() + testutils.GanetiTestProgram()