import samba
import samba.tests
-from samba.tests import TestSkipped, TestCaseInTempDir
-import errno
import os
import re
import subprocess
def _format_message(self, parameters, message):
parameters = list(parameters)
+ parameters = map(str, parameters)
parameters.sort()
return message + '\n\n %s' % ('\n '.join(parameters))
+
def get_documented_parameters(sourcedir):
path = os.path.join(sourcedir, "bin", "default", "docs-xml", "smbdotconf")
if not os.path.exists(os.path.join(path, "parameters.all.xml")):
raise Exception("Unable to find parameters.all.xml")
try:
p = open(os.path.join(path, "parameters.all.xml"), 'r')
- except IOError, e:
+ except IOError as e:
raise Exception("Error opening parameters file")
out = p.read()
p.close()
-def get_implementation_parameters(sourcedir):
- # Reading entries from source code
- f = open(os.path.join(sourcedir, "lib/param/param_table.c"), "r")
- try:
- # burn through the preceding lines
- while True:
- l = f.readline()
- if l.startswith("struct parm_struct parm_table"):
- break
-
- for l in f.readlines():
- if re.match("^\s*\}\;\s*$", l):
- break
- # pull in the param names only
- if re.match(".*P_SEPARATOR.*", l):
- continue
- m = re.match("\s*\.label\s*=\s*\"(.*)\".*", l)
- if not m:
- continue
-
- name = m.group(1)
- yield name
- finally:
- f.close()
-
def get_documented_tuples(sourcedir, omit_no_default=True):
path = os.path.join(sourcedir, "bin", "default", "docs-xml", "smbdotconf")
if not os.path.exists(os.path.join(path, "parameters.all.xml")):
raise Exception("Unable to find parameters.all.xml")
try:
p = open(os.path.join(path, "parameters.all.xml"), 'r')
- except IOError, e:
+ except IOError as e:
raise Exception("Error opening parameters file")
out = p.read()
class SmbDotConfTests(TestCase):
# defines the cases where the defaults may differ from the documentation
- special_cases = set(['log level', 'path', 'ldapsam:trusted', 'spoolss: architecture',
- 'share:fake_fscaps', 'ldapsam:editposix', 'rpc_daemon:DAEMON',
- 'rpc_server:SERVER', 'panic action', 'homedir map', 'NIS homedir',
+ special_cases = set(['log level', 'path',
+ 'panic action', 'homedir map', 'NIS homedir',
'server string', 'netbios name', 'socket options', 'use mmap',
'ctdbd socket', 'printing', 'printcap name', 'queueresume command',
'queuepause command','lpresume command', 'lppause command',
'lprm command', 'lpq command', 'print command', 'template homedir',
- 'spoolss: os_major', 'spoolss: os_minor', 'spoolss: os_build'])
+ 'max open files',
+ 'include system krb5 conf', 'rpc server dynamic port range',
+ 'mit kdc command'])
def setUp(self):
super(SmbDotConfTests, self).setUp()
finally:
f.close()
- def tearDown(self):
- super(SmbDotConfTests, self).tearDown()
- os.unlink(self.smbconf)
+ self.blankconf = os.path.join(self.tempdir, "emptytestsmb.conf")
+ f = open(self.blankconf, 'w')
+ try:
+ f.write("")
+ finally:
+ f.close()
+
+ self.topdir = os.path.abspath(samba.source_tree_topdir())
+
+ try:
+ self.documented = set(get_documented_parameters(self.topdir))
+ except:
+ self.fail("Unable to load documented parameters")
- def test_unknown(self):
- topdir = os.path.abspath(samba.source_tree_topdir())
try:
- documented = set(get_documented_parameters(topdir))
- except e:
+ self.defaults = set(get_documented_tuples(self.topdir))
+ except:
self.fail("Unable to load parameters")
- parameters = set(get_implementation_parameters(topdir))
- # Filter out parametric options, since we can't find them in the parm
- # table
- documented = set([p for p in documented if not ":" in p])
- unknown = documented.difference(parameters)
- if len(unknown) > 0:
- self.fail(self._format_message(unknown,
- "Parameters that are documented but not in the implementation:"))
-
- def test_undocumented(self):
- topdir = os.path.abspath(samba.source_tree_topdir())
+
try:
- documented = set(get_documented_parameters(topdir))
+ self.defaults_all = set(get_documented_tuples(self.topdir, False))
except:
self.fail("Unable to load parameters")
- parameters = set(get_implementation_parameters(topdir))
- undocumented = parameters.difference(documented)
- if len(undocumented) > 0:
- self.fail(self._format_message(undocumented,
- "Parameters that are in the implementation but undocumented:"))
+
+
+ def tearDown(self):
+ super(SmbDotConfTests, self).tearDown()
+ os.unlink(self.smbconf)
+ os.unlink(self.blankconf)
def test_default_s3(self):
self._test_default(['bin/testparm'])
exceptions = ['client lanman auth',
'client plaintext auth',
'registry shares',
- 'idmap backend',
- 'idmap gid',
- 'idmap uid'])
+ 'smb ports',
+ 'rpc server dynamic port range',
+ 'name resolve order'])
+ self._test_empty(['bin/testparm'])
def test_default_s4(self):
self._test_default(['bin/samba-tool', 'testparm'])
self._set_defaults(['bin/samba-tool', 'testparm'])
- self._set_arbitrary(['bin/samba-tool', 'testparm'])
+ self._set_arbitrary(['bin/samba-tool', 'testparm'],
+ exceptions = ['smb ports',
+ 'rpc server dynamic port range',
+ 'name resolve order'])
+ self._test_empty(['bin/samba-tool', 'testparm'])
def _test_default(self, program):
- topdir = os.path.abspath(samba.source_tree_topdir())
- try:
- defaults = set(get_documented_tuples(topdir))
- except:
- self.fail("Unable to load parameters")
- bindir = os.path.join(topdir, "bin")
failset = set()
count = 0
- for tuples in defaults:
+ for tuples in self.defaults:
param, default, context, param_type = tuples
+
if param in self.special_cases:
continue
+ # bad, bad parametric options - we don't have their default values
+ if ':' in param:
+ continue
section = None
if context == "G":
section = "global"
self.fail("%s has no valid context" % param)
p = subprocess.Popen(program + ["-s", self.smbconf,
"--section-name", section, "--parameter-name", param],
- stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=topdir).communicate()
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=self.topdir).communicate()
if p[0].upper().strip() != default.upper():
if not (p[0].upper().strip() == "" and default == '""'):
doc_triple = "%s\n Expected: %s" % (param, default)
"Parameters that do not have matching defaults:"))
def _set_defaults(self, program):
- topdir = os.path.abspath(samba.source_tree_topdir())
- try:
- defaults = set(get_documented_tuples(topdir))
- except:
- self.fail("Unable to load parameters")
- bindir = os.path.join(topdir, "bin")
failset = set()
count = 0
- for tuples in defaults:
+ for tuples in self.defaults:
param, default, context, param_type = tuples
- if param in ['printing']:
+ if param in ['printing', 'rpc server dynamic port range']:
continue
section = None
p = subprocess.Popen(program + ["-s", self.smbconf,
"--section-name", section, "--parameter-name", param,
"--option", "%s = %s" % (param, default)],
- stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=topdir).communicate()
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=self.topdir).communicate()
if p[0].upper().strip() != default.upper():
if not (p[0].upper().strip() == "" and default == '""'):
doc_triple = "%s\n Expected: %s" % (param, default)
def _set_arbitrary(self, program, exceptions=None):
arbitrary = {'string': 'string', 'boolean': 'yes', 'integer': '5',
+ 'boolean-rev': 'yes',
+ 'cmdlist': 'a b c',
+ 'bytes': '10',
+ 'octal': '0123',
+ 'ustring': 'ustring',
'enum':'', 'boolean-auto': '', 'char': 'a', 'list': 'a, b, c'}
+ opposite_arbitrary = {'string': 'string2', 'boolean': 'no', 'integer': '6',
+ 'boolean-rev': 'no',
+ 'cmdlist': 'd e f',
+ 'bytes': '11',
+ 'octal': '0567',
+ 'ustring': 'ustring2',
+ 'enum':'', 'boolean-auto': '', 'char': 'b', 'list': 'd, e, f'}
- topdir = os.path.abspath(samba.source_tree_topdir())
- try:
- defaults = set(get_documented_tuples(topdir, False))
- except Exception,e:
- self.fail("Unable to load parameters" + e)
- bindir = os.path.join(topdir, "bin")
failset = set()
count = 0
- for tuples in defaults:
+ for tuples in self.defaults_all:
param, default, context, param_type = tuples
if param in ['printing', 'copy', 'include', 'log level']:
p = subprocess.Popen(program + ["-s", self.smbconf,
"--section-name", section, "--parameter-name", param,
"--option", "%s = %s" % (param, value_to_use)],
- stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=topdir).communicate()
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=self.topdir).communicate()
if p[0].upper().strip() != value_to_use.upper():
# currently no way to distinguish command lists
if param_type == 'list':
doc_triple = "%s\n Expected: %s" % (param, value_to_use)
failset.add("%s\n Got: %s" % (doc_triple, p[0].upper().strip()))
+ opposite_value = opposite_arbitrary.get(param_type)
+ tempconf = os.path.join(self.tempdir, "tempsmb.conf")
+ g = open(tempconf, 'w')
+ try:
+ towrite = section + "\n"
+ towrite += param + " = " + opposite_value
+ g.write(towrite)
+ finally:
+ g.close()
+
+ p = subprocess.Popen(program + ["-s", tempconf, "--suppress-prompt",
+ "--option", "%s = %s" % (param, value_to_use)],
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=self.topdir).communicate()
+
+ os.unlink(tempconf)
+
+ # testparm doesn't display a value if they are equivalent
+ if (value_to_use.lower() != opposite_value.lower()):
+ for line in p[0].splitlines():
+ if not line.strip().startswith(param):
+ continue
+
+ value_found = line.split("=")[1].upper().strip()
+ if value_found != value_to_use.upper():
+ # currently no way to distinguish command lists
+ if param_type == 'list':
+ if ", ".join(value_found.split()) == value_to_use.upper():
+ continue
+
+ # currently no way to identify octal
+ if param_type == 'integer':
+ try:
+ if int(value_to_use, 8) == int(value_found, 8):
+ continue
+ except:
+ pass
+
+ doc_triple = "%s\n Expected: %s" % (param, value_to_use)
+ failset.add("%s\n Got: %s" % (doc_triple, value_found))
+
+
if len(failset) > 0:
self.fail(self._format_message(failset,
"Parameters that were unexpectedly not set:"))
+
+ def _test_empty(self, program):
+ p = subprocess.Popen(program + ["-s", self.blankconf, "--suppress-prompt"],
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=self.topdir).communicate()
+ output = ""
+
+ for line in p[0].splitlines():
+ if line.strip().startswith('#'):
+ continue
+ if line.strip().startswith("idmap config *"):
+ continue
+ output += line.strip().lower() + '\n'
+
+ if output.strip() != '[global]' and output.strip() != '[globals]':
+ self.fail("Testparm returned unexpected output on an empty smb.conf.")