samba.tests.docs: Support spaces before synonyms.
[metze/samba/wip.git] / source4 / scripting / python / samba / tests / docs.py
1 # Unix SMB/CIFS implementation.
2 # Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007-2012
3 #
4 # Tests for documentation.
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 3 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,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU 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, see <http://www.gnu.org/licenses/>.
18 #
19
20 """Tests for presence of documentation."""
21
22 import samba
23 import samba.tests
24
25 import os
26 import re
27 import subprocess
28
29
30 class TestCase(samba.tests.TestCase):
31
32     def _format_message(self, parameters, message):
33         parameters = list(parameters)
34         parameters.sort()
35         return message + '\n\n    %s' % ('\n    '.join(parameters))
36
37
38 def get_documented_parameters(sourcedir):
39     p = subprocess.Popen(
40         ["xsltproc", "--xinclude", "--param", "smb.context", "ALL", "generate-context.xsl", "parameters.all.xml"],
41         stdout=subprocess.PIPE, cwd=os.path.join(sourcedir, "docs-xml", "smbdotconf"))
42     out, err = p.communicate()
43     assert p.returncode == 0, "returncode was %r" % p.returncode
44     for l in out.splitlines():
45         m = re.match('<samba:parameter .*?name="([^"]*?)"', l)
46         if m:
47             name = m.group(1).replace(" ", "")
48             yield name
49         m = re.match('.*<synonym>(.*)</synonym>.*', l)
50         if m:
51             name = m.group(1).replace(" ", "")
52             yield name
53
54
55 def get_implementation_parameters(sourcedir):
56     # Reading entries from source code
57     f = open(os.path.join(sourcedir, "lib/param/param_table.c"), "r")
58     try:
59         # burn through the preceding lines
60         while True:
61             l = f.readline()
62             if l.startswith("static struct parm_struct parm_table"):
63                 break
64
65         for l in f.readlines():
66             if re.match("^\s*\}\;\s*$", l):
67                 break
68             # pull in the param names only
69             if re.match(".*P_SEPARATOR.*", l):
70                 continue
71             m = re.match("\s*\.label\s*=\s*\"(.*)\".*", l)
72             if not m:
73                 continue
74
75             name = m.group(1)
76             yield name.lower().replace(" ", "")
77     finally:
78         f.close()
79
80
81 class SmbDotConfTests(TestCase):
82
83     def test_unknown(self):
84         topdir = samba.source_tree_topdir()
85         documented = set(get_documented_parameters(topdir))
86         parameters = set(get_implementation_parameters(topdir))
87         # Filter out parametric options, since we can't find them in the parm
88         # table
89         documented = set([p for p in documented if not ":" in p])
90         unknown = documented.difference(parameters)
91         if len(unknown) > 0:
92             self.fail(self._format_message(unknown,
93                 "Parameters that are documented but not in the implementation:"))
94
95     def test_undocumented(self):
96         topdir = samba.source_tree_topdir()
97         documented = set(get_documented_parameters(topdir))
98         parameters = set(get_implementation_parameters(topdir))
99         undocumented = parameters.difference(documented)
100         if len(undocumented) > 0:
101             self.fail(self._format_message(undocumented,
102                 "Parameters that are in the implementation but undocumented:"))