Tests: avoid adding python options that are functions in the env
[nivanova/samba-autobuild/.git] / selftest / run.py
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>
4
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.
9
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.
14
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/>.
17
18 """Test command running."""
19
20 import datetime
21 from subunit import iso8601
22 import os
23 import subprocess
24 import subunit
25 import sys
26 import tempfile
27 import warnings
28
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
36
37
38 def expand_command_list(cmd):
39     if not "$LISTOPT" in cmd:
40         return None
41     return cmd.replace("$LISTOPT", "--list")
42
43
44 def expand_command_run(cmd, supports_loadfile, supports_idlist, subtests=None):
45     """Expand a test command.
46
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)
78
79
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
87
88
89 def now():
90     """Return datetime instance for current time in UTC.
91     """
92     return datetime.datetime.utcnow().replace(tzinfo=iso8601.Utc())
93
94
95 def run_testsuite_command(name, cmd, subunit_ops, env=None, outf=None):
96     """Run a testsuite command.
97
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
104     """
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
117
118     subunit_ops.time(now())
119     subunit_ops.progress(None, subunit.PROGRESS_POP)
120
121     if env is not None:
122         envlog = env.get_log()
123         if envlog != "":
124             outf.write("envlog: %s\n" % envlog)
125
126     outf.write("command: %s\n" % cmd)
127     outf.write("expanded command: %s\n" % expand_environment_strings(cmd, os.environ))
128
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)
133
134     return exitcode