build: Change bin/default/python -> bin/python symlink to bin/default/python_modules
[bbaumbach/samba-autobuild/.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 from samba.tests import TestSkipped
25
26 import errno
27 import os
28 import re
29 import subprocess
30
31
32 class TestCase(samba.tests.TestCase):
33
34     def _format_message(self, parameters, message):
35         parameters = list(parameters)
36         parameters.sort()
37         return message + '\n\n    %s' % ('\n    '.join(parameters))
38
39
40 class NoXsltProc(Exception):
41
42     def __init__(self):
43         Exception.__init__(self, "'xsltproc' is not installed")
44
45
46 def get_documented_parameters(sourcedir):
47     path = os.path.join(sourcedir, "bin", "default", "docs-xml", "smbdotconf")
48     if not os.path.exists(os.path.join(path, "parameters.all.xml")):
49         raise Exception("Unable to find parameters.all.xml")
50     try:
51         p = subprocess.Popen(
52             ["xsltproc", "--xinclude", "--param", "smb.context", "ALL", os.path.join(sourcedir, "docs-xml", "smbdotconf", "generate-context.xsl"), "parameters.all.xml"],
53             stderr=subprocess.STDOUT, stdout=subprocess.PIPE,
54             cwd=path)
55     except OSError, e:
56         if e.errno == errno.ENOENT:
57             raise NoXsltProc()
58         raise
59     out, err = p.communicate()
60     assert p.returncode == 0, "returncode was %r" % p.returncode
61     for l in out.splitlines():
62         m = re.match('<samba:parameter .*?name="([^"]*?)"', l)
63         if "removed=\"1\"" in l:
64             continue
65         if m:
66             name = m.group(1)
67             yield name
68         m = re.match('.*<synonym>(.*)</synonym>.*', l)
69         if m:
70             name = m.group(1)
71             yield name
72
73
74 def get_implementation_parameters(sourcedir):
75     # Reading entries from source code
76     f = open(os.path.join(sourcedir, "lib/param/param_table.c"), "r")
77     try:
78         # burn through the preceding lines
79         while True:
80             l = f.readline()
81             if l.startswith("static struct parm_struct parm_table"):
82                 break
83
84         for l in f.readlines():
85             if re.match("^\s*\}\;\s*$", l):
86                 break
87             # pull in the param names only
88             if re.match(".*P_SEPARATOR.*", l):
89                 continue
90             m = re.match("\s*\.label\s*=\s*\"(.*)\".*", l)
91             if not m:
92                 continue
93
94             name = m.group(1)
95             yield name
96     finally:
97         f.close()
98
99
100 class SmbDotConfTests(TestCase):
101
102     def test_unknown(self):
103         topdir = samba.source_tree_topdir()
104         try:
105             documented = set(get_documented_parameters(topdir))
106         except NoXsltProc:
107             raise TestSkipped("'xsltproc' is missing, unable to load parameters")
108         parameters = set(get_implementation_parameters(topdir))
109         # Filter out parametric options, since we can't find them in the parm
110         # table
111         documented = set([p for p in documented if not ":" in p])
112         unknown = documented.difference(parameters)
113         if len(unknown) > 0:
114             self.fail(self._format_message(unknown,
115                 "Parameters that are documented but not in the implementation:"))
116
117     def test_undocumented(self):
118         topdir = samba.source_tree_topdir()
119         try:
120             documented = set(get_documented_parameters(topdir))
121         except NoXsltProc:
122             raise TestSkipped("'xsltproc' is missing, unable to load parameters")
123         parameters = set(get_implementation_parameters(topdir))
124         undocumented = parameters.difference(documented)
125         if len(undocumented) > 0:
126             self.fail(self._format_message(undocumented,
127                 "Parameters that are in the implementation but undocumented:"))