Statistics
| Branch: | Tag: | Revision:

root / test / docs_unittest.py @ ab3e6da8

History | View | Annotate | Download (4.1 kB)

1
#!/usr/bin/python
2
#
3

    
4
# Copyright (C) 2009 Google Inc.
5
#
6
# This program is free software; you can redistribute it and/or modify
7
# it under the terms of the GNU General Public License as published by
8
# the Free Software Foundation; either version 2 of the License, or
9
# (at your option) any later version.
10
#
11
# This program is distributed in the hope that it will be useful, but
12
# WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
# General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License
17
# along with this program; if not, write to the Free Software
18
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
# 02110-1301, USA.
20

    
21

    
22
"""Script for unittesting documentation"""
23

    
24
import unittest
25
import re
26

    
27
from ganeti import _autoconf
28
from ganeti import utils
29
from ganeti import cmdlib
30
from ganeti import build
31
from ganeti.rapi import connector
32

    
33
import testutils
34

    
35

    
36
class TestDocs(unittest.TestCase):
37
  """Documentation tests"""
38

    
39
  @staticmethod
40
  def _ReadDocFile(filename):
41
    return utils.ReadFile("%s/doc/%s" %
42
                          (testutils.GetSourceDir(), filename))
43

    
44
  def testHookDocs(self):
45
    """Check whether all hooks are documented.
46

47
    """
48
    hooksdoc = self._ReadDocFile("hooks.rst")
49

    
50
    for name in dir(cmdlib):
51
      obj = getattr(cmdlib, name)
52

    
53
      if (isinstance(obj, type) and
54
          issubclass(obj, cmdlib.LogicalUnit) and
55
          hasattr(obj, "HPATH")):
56
        self._CheckHook(name, obj, hooksdoc)
57

    
58
  def _CheckHook(self, name, lucls, hooksdoc):
59
    if lucls.HTYPE is None:
60
      return
61

    
62
    # TODO: Improve this test (e.g. find hooks documented but no longer
63
    # existing)
64

    
65
    pattern = r"^:directory:\s*%s\s*$" % re.escape(lucls.HPATH)
66

    
67
    self.assert_(re.findall(pattern, hooksdoc, re.M),
68
                 msg=("Missing documentation for hook %s/%s" %
69
                      (lucls.HTYPE, lucls.HPATH)))
70

    
71

    
72
  def testRapiDocs(self):
73
    """Check whether all RAPI resources are documented.
74

75
    """
76
    rapidoc = self._ReadDocFile("rapi.rst")
77

    
78
    node_name = "[node_name]"
79
    instance_name = "[instance_name]"
80
    job_id = "[job_id]"
81

    
82
    resources = connector.GetHandlers(re.escape(node_name),
83
                                      re.escape(instance_name),
84
                                      re.escape(job_id))
85

    
86
    titles = []
87

    
88
    prevline = None
89
    for line in rapidoc.splitlines():
90
      if re.match(r"^\++$", line):
91
        titles.append(prevline)
92

    
93
      prevline = line
94

    
95
    undocumented = []
96

    
97
    for key, handler in resources.iteritems():
98
      # Regex objects
99
      if hasattr(key, "match"):
100
        found = False
101
        for title in titles:
102
          if (title.startswith("``") and
103
              title.endswith("``") and
104
              key.match(title[2:-2])):
105
            found = True
106
            break
107

    
108
        if not found:
109
          # TODO: Find better way of identifying resource
110
          undocumented.append(str(handler))
111

    
112
      elif ("``%s``" % key) not in titles:
113
        undocumented.append(key)
114

    
115
    self.failIf(undocumented,
116
                msg=("Missing RAPI resource documentation for %s" %
117
                     utils.CommaJoin(undocumented)))
118

    
119

    
120
class TestManpages(unittest.TestCase):
121
  """Manpage tests"""
122

    
123
  @staticmethod
124
  def _ReadManFile(name):
125
    return utils.ReadFile("%s/man/%s.sgml" %
126
                          (testutils.GetSourceDir(), name))
127

    
128
  @staticmethod
129
  def _LoadScript(name):
130
    return build.LoadModule("scripts/%s" % name)
131

    
132
  def test(self):
133
    for script in _autoconf.GNT_SCRIPTS:
134
      self._CheckManpage(script,
135
                         self._ReadManFile(script),
136
                         self._LoadScript(script).commands.keys())
137

    
138
  def _CheckManpage(self, script, mantext, commands):
139
    missing = []
140

    
141
    for cmd in commands:
142
      pattern = "<cmdsynopsis>\s*<command>%s</command>" % re.escape(cmd)
143
      if not re.findall(pattern, mantext, re.S):
144
        missing.append(cmd)
145

    
146
    self.failIf(missing,
147
                msg=("Manpage for '%s' missing documentation for %s" %
148
                     (script, utils.CommaJoin(missing))))
149

    
150

    
151
if __name__ == "__main__":
152
  testutils.GanetiTestProgram()