Statistics
| Branch: | Tag: | Revision:

root / test / docs_unittest.py @ 34cb5617

History | View | Annotate | Download (4.1 kB)

1 3f991867 Michael Hanselmann
#!/usr/bin/python
2 3f991867 Michael Hanselmann
#
3 3f991867 Michael Hanselmann
4 3f991867 Michael Hanselmann
# Copyright (C) 2009 Google Inc.
5 3f991867 Michael Hanselmann
#
6 3f991867 Michael Hanselmann
# This program is free software; you can redistribute it and/or modify
7 3f991867 Michael Hanselmann
# it under the terms of the GNU General Public License as published by
8 3f991867 Michael Hanselmann
# the Free Software Foundation; either version 2 of the License, or
9 3f991867 Michael Hanselmann
# (at your option) any later version.
10 3f991867 Michael Hanselmann
#
11 3f991867 Michael Hanselmann
# This program is distributed in the hope that it will be useful, but
12 3f991867 Michael Hanselmann
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 3f991867 Michael Hanselmann
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 3f991867 Michael Hanselmann
# General Public License for more details.
15 3f991867 Michael Hanselmann
#
16 3f991867 Michael Hanselmann
# You should have received a copy of the GNU General Public License
17 3f991867 Michael Hanselmann
# along with this program; if not, write to the Free Software
18 3f991867 Michael Hanselmann
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 3f991867 Michael Hanselmann
# 02110-1301, USA.
20 3f991867 Michael Hanselmann
21 3f991867 Michael Hanselmann
22 3f991867 Michael Hanselmann
"""Script for unittesting documentation"""
23 3f991867 Michael Hanselmann
24 3f991867 Michael Hanselmann
import unittest
25 3f991867 Michael Hanselmann
import re
26 3f991867 Michael Hanselmann
27 36bf7973 Michael Hanselmann
from ganeti import _autoconf
28 3f991867 Michael Hanselmann
from ganeti import utils
29 3f991867 Michael Hanselmann
from ganeti import cmdlib
30 e948770c Michael Hanselmann
from ganeti import build
31 bf968b7f Michael Hanselmann
from ganeti.rapi import connector
32 3f991867 Michael Hanselmann
33 3f991867 Michael Hanselmann
import testutils
34 3f991867 Michael Hanselmann
35 3f991867 Michael Hanselmann
36 3f991867 Michael Hanselmann
class TestDocs(unittest.TestCase):
37 3f991867 Michael Hanselmann
  """Documentation tests"""
38 3f991867 Michael Hanselmann
39 3f991867 Michael Hanselmann
  @staticmethod
40 3f991867 Michael Hanselmann
  def _ReadDocFile(filename):
41 3f991867 Michael Hanselmann
    return utils.ReadFile("%s/doc/%s" %
42 3f991867 Michael Hanselmann
                          (testutils.GetSourceDir(), filename))
43 3f991867 Michael Hanselmann
44 3f991867 Michael Hanselmann
  def testHookDocs(self):
45 3f991867 Michael Hanselmann
    """Check whether all hooks are documented.
46 3f991867 Michael Hanselmann

47 3f991867 Michael Hanselmann
    """
48 3f991867 Michael Hanselmann
    hooksdoc = self._ReadDocFile("hooks.rst")
49 3f991867 Michael Hanselmann
50 3f991867 Michael Hanselmann
    for name in dir(cmdlib):
51 3f991867 Michael Hanselmann
      obj = getattr(cmdlib, name)
52 3f991867 Michael Hanselmann
53 3f991867 Michael Hanselmann
      if (isinstance(obj, type) and
54 3f991867 Michael Hanselmann
          issubclass(obj, cmdlib.LogicalUnit) and
55 3f991867 Michael Hanselmann
          hasattr(obj, "HPATH")):
56 3f991867 Michael Hanselmann
        self._CheckHook(name, obj, hooksdoc)
57 3f991867 Michael Hanselmann
58 3f991867 Michael Hanselmann
  def _CheckHook(self, name, lucls, hooksdoc):
59 3f991867 Michael Hanselmann
    if lucls.HTYPE is None:
60 3f991867 Michael Hanselmann
      return
61 3f991867 Michael Hanselmann
62 3f991867 Michael Hanselmann
    # TODO: Improve this test (e.g. find hooks documented but no longer
63 3f991867 Michael Hanselmann
    # existing)
64 3f991867 Michael Hanselmann
65 3f991867 Michael Hanselmann
    pattern = r"^:directory:\s*%s\s*$" % re.escape(lucls.HPATH)
66 3f991867 Michael Hanselmann
67 3f991867 Michael Hanselmann
    self.assert_(re.findall(pattern, hooksdoc, re.M),
68 3f991867 Michael Hanselmann
                 msg=("Missing documentation for hook %s/%s" %
69 3f991867 Michael Hanselmann
                      (lucls.HTYPE, lucls.HPATH)))
70 3f991867 Michael Hanselmann
71 3f991867 Michael Hanselmann
72 bf968b7f Michael Hanselmann
  def testRapiDocs(self):
73 bf968b7f Michael Hanselmann
    """Check whether all RAPI resources are documented.
74 bf968b7f Michael Hanselmann

75 bf968b7f Michael Hanselmann
    """
76 bf968b7f Michael Hanselmann
    rapidoc = self._ReadDocFile("rapi.rst")
77 bf968b7f Michael Hanselmann
78 bf968b7f Michael Hanselmann
    node_name = "[node_name]"
79 bf968b7f Michael Hanselmann
    instance_name = "[instance_name]"
80 bf968b7f Michael Hanselmann
    job_id = "[job_id]"
81 bf968b7f Michael Hanselmann
82 bf968b7f Michael Hanselmann
    resources = connector.GetHandlers(re.escape(node_name),
83 bf968b7f Michael Hanselmann
                                      re.escape(instance_name),
84 bf968b7f Michael Hanselmann
                                      re.escape(job_id))
85 bf968b7f Michael Hanselmann
86 bf968b7f Michael Hanselmann
    titles = []
87 bf968b7f Michael Hanselmann
88 bf968b7f Michael Hanselmann
    prevline = None
89 bf968b7f Michael Hanselmann
    for line in rapidoc.splitlines():
90 bf968b7f Michael Hanselmann
      if re.match(r"^\++$", line):
91 bf968b7f Michael Hanselmann
        titles.append(prevline)
92 bf968b7f Michael Hanselmann
93 bf968b7f Michael Hanselmann
      prevline = line
94 bf968b7f Michael Hanselmann
95 bf968b7f Michael Hanselmann
    undocumented = []
96 bf968b7f Michael Hanselmann
97 bf968b7f Michael Hanselmann
    for key, handler in resources.iteritems():
98 bf968b7f Michael Hanselmann
      # Regex objects
99 bf968b7f Michael Hanselmann
      if hasattr(key, "match"):
100 bf968b7f Michael Hanselmann
        found = False
101 bf968b7f Michael Hanselmann
        for title in titles:
102 bf968b7f Michael Hanselmann
          if (title.startswith("``") and
103 bf968b7f Michael Hanselmann
              title.endswith("``") and
104 bf968b7f Michael Hanselmann
              key.match(title[2:-2])):
105 bf968b7f Michael Hanselmann
            found = True
106 bf968b7f Michael Hanselmann
            break
107 bf968b7f Michael Hanselmann
108 bf968b7f Michael Hanselmann
        if not found:
109 bf968b7f Michael Hanselmann
          # TODO: Find better way of identifying resource
110 bf968b7f Michael Hanselmann
          undocumented.append(str(handler))
111 bf968b7f Michael Hanselmann
112 bf968b7f Michael Hanselmann
      elif ("``%s``" % key) not in titles:
113 bf968b7f Michael Hanselmann
        undocumented.append(key)
114 bf968b7f Michael Hanselmann
115 bf968b7f Michael Hanselmann
    self.failIf(undocumented,
116 bf968b7f Michael Hanselmann
                msg=("Missing RAPI resource documentation for %s" %
117 bf968b7f Michael Hanselmann
                     utils.CommaJoin(undocumented)))
118 bf968b7f Michael Hanselmann
119 bf968b7f Michael Hanselmann
120 36bf7973 Michael Hanselmann
class TestManpages(unittest.TestCase):
121 36bf7973 Michael Hanselmann
  """Manpage tests"""
122 36bf7973 Michael Hanselmann
123 36bf7973 Michael Hanselmann
  @staticmethod
124 36bf7973 Michael Hanselmann
  def _ReadManFile(name):
125 36bf7973 Michael Hanselmann
    return utils.ReadFile("%s/man/%s.sgml" %
126 36bf7973 Michael Hanselmann
                          (testutils.GetSourceDir(), name))
127 36bf7973 Michael Hanselmann
128 36bf7973 Michael Hanselmann
  @staticmethod
129 36bf7973 Michael Hanselmann
  def _LoadScript(name):
130 e948770c Michael Hanselmann
    return build.LoadModule("scripts/%s" % name)
131 36bf7973 Michael Hanselmann
132 36bf7973 Michael Hanselmann
  def test(self):
133 36bf7973 Michael Hanselmann
    for script in _autoconf.GNT_SCRIPTS:
134 36bf7973 Michael Hanselmann
      self._CheckManpage(script,
135 36bf7973 Michael Hanselmann
                         self._ReadManFile(script),
136 36bf7973 Michael Hanselmann
                         self._LoadScript(script).commands.keys())
137 36bf7973 Michael Hanselmann
138 36bf7973 Michael Hanselmann
  def _CheckManpage(self, script, mantext, commands):
139 36bf7973 Michael Hanselmann
    missing = []
140 36bf7973 Michael Hanselmann
141 36bf7973 Michael Hanselmann
    for cmd in commands:
142 36bf7973 Michael Hanselmann
      pattern = "<cmdsynopsis>\s*<command>%s</command>" % re.escape(cmd)
143 36bf7973 Michael Hanselmann
      if not re.findall(pattern, mantext, re.S):
144 36bf7973 Michael Hanselmann
        missing.append(cmd)
145 36bf7973 Michael Hanselmann
146 36bf7973 Michael Hanselmann
    self.failIf(missing,
147 36bf7973 Michael Hanselmann
                msg=("Manpage for '%s' missing documentation for %s" %
148 36bf7973 Michael Hanselmann
                     (script, utils.CommaJoin(missing))))
149 36bf7973 Michael Hanselmann
150 36bf7973 Michael Hanselmann
151 3f991867 Michael Hanselmann
if __name__ == "__main__":
152 3f991867 Michael Hanselmann
  unittest.main()