ctdb-docs: Update "ctdb reloadnodes" documentation
[Samba.git] / selftest / run.py
blob8a0e7ca6c414ee6d9a78ed515a7ba211b03cad7d
1 #!/usr/bin/python -u
2 # Bootstrap Samba and run a number of tests against it.
3 # Copyright (C) 2012 Jelmer Vernooij <jelmer@samba.org>
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
18 """Test command running."""
20 import datetime
21 import os
22 import subprocess
23 from samba import subunit
24 from iso8601 import iso8601
25 import sys
26 import tempfile
27 import warnings
29 # expand strings from %ENV
30 def expand_environment_strings(s, vars):
31 # we use a reverse sort so we do the longer ones first
32 for k in sorted(vars.keys(), reverse=True):
33 v = vars[k]
34 s = s.replace("$%s" % k, v)
35 return s
38 def expand_command_list(cmd):
39 if not "$LISTOPT" in cmd:
40 return None
41 return cmd.replace("$LISTOPT", "--list")
44 def expand_command_run(cmd, supports_loadfile, supports_idlist, subtests=None):
45 """Expand a test command.
47 :param cmd: Command to expand
48 :param supports_loadfile: Whether command supports loadfile
49 :param supports_idlist: Whether the command supports running specific
50 subtests
51 :param subtests: List of subtests to run - None for all subtests
52 :return: Tuple with command to run and temporary file to remove after
53 running (or None)
54 """
55 # Generate a file with the individual tests to run, if the
56 # test runner for this test suite supports it.
57 if subtests is None:
58 return (cmd.replace("$LOADLIST", ""), None)
59 if supports_loadfile:
60 (fd, listid_file) = tempfile.mkstemp()
61 f = os.fdopen(fd, 'w')
62 try:
63 for test in subtests:
64 f.write(test+"\n")
65 finally:
66 f.close()
67 return (
68 cmd.replace("$LOADLIST", "--load-list=%s" % listid_file),
69 listid_file)
70 elif supports_idlist:
71 cmd += " " + " ".join(subtests)
72 return (cmd, None)
73 else:
74 warnings.warn(
75 "Running subtests requested, but command does not support "
76 "this.")
77 return (cmd, None)
80 def exported_envvars_str(vars, names):
81 out = ""
82 for n in names:
83 if not n in vars:
84 continue
85 out += "%s=%s\n" % (n, vars[n])
86 return out
89 def now():
90 """Return datetime instance for current time in UTC.
91 """
92 return datetime.datetime.utcnow().replace(tzinfo=iso8601.Utc())
95 def run_testsuite_command(name, cmd, subunit_ops, env=None, outf=None):
96 """Run a testsuite command.
98 :param name: Name of the testsuite
99 :param cmd: Command to run
100 :param subunit_ops: Subunit ops to use for reporting results
101 :param env: Environment the test is run in
102 :param outf: File-like object to write standard out to (defaults to sys.stdout)
103 :return: Exit code or None if the test failed to run completely
105 if outf is None:
106 outf = sys.stdout
107 subunit_ops.start_testsuite(name)
108 subunit_ops.progress(None, subunit.PROGRESS_PUSH)
109 subunit_ops.time(now())
110 try:
111 exitcode = subprocess.call(cmd, shell=True, stdout=outf)
112 except Exception, e:
113 subunit_ops.time(now())
114 subunit_ops.progress(None, subunit.PROGRESS_POP)
115 subunit_ops.end_testsuite(name, "error", "Unable to run %r: %s" % (cmd, e))
116 return None
118 subunit_ops.time(now())
119 subunit_ops.progress(None, subunit.PROGRESS_POP)
121 if env is not None:
122 envlog = env.get_log()
123 if envlog != "":
124 outf.write("envlog: %s\n" % envlog)
126 outf.write("command: %s\n" % cmd)
127 outf.write("expanded command: %s\n" % expand_environment_strings(cmd, os.environ))
129 if exitcode == 0:
130 subunit_ops.end_testsuite(name, "success")
131 else:
132 subunit_ops.end_testsuite(name, "failure", "Exit code was %d" % exitcode)
134 return exitcode