summaryrefslogtreecommitdiff
path: root/selftest
diff options
context:
space:
mode:
authorJelmer Vernooij <jelmer@samba.org>2012-03-11 20:58:00 +0100
committerJelmer Vernooij <jelmer@samba.org>2012-03-11 23:57:04 +0100
commit6f9c333f95956138fbd8245a4cf3f285ca601181 (patch)
treeb6e2653adfa04206d5d912d74134b828757ce3a1 /selftest
parentf5bb26edb36936b08dc2384cf6aa1dee73a355c8 (diff)
downloadsamba-6f9c333f95956138fbd8245a4cf3f285ca601181.tar.gz
samba-6f9c333f95956138fbd8245a4cf3f285ca601181.tar.bz2
samba-6f9c333f95956138fbd8245a4cf3f285ca601181.zip
selftest.py: Move some infrastructure for running commands to selftest.run, with tests.
Diffstat (limited to 'selftest')
-rw-r--r--selftest/run.py55
-rwxr-xr-xselftest/selftest.py51
-rw-r--r--selftest/tests/test_run.py93
3 files changed, 162 insertions, 37 deletions
diff --git a/selftest/run.py b/selftest/run.py
index 20ede65532..24fbc339e6 100644
--- a/selftest/run.py
+++ b/selftest/run.py
@@ -15,7 +15,14 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
+"""Test command running."""
+
+import datetime
+import iso8601
import os
+import subprocess
+import subunit
+import sys
import tempfile
import warnings
@@ -77,3 +84,51 @@ def exported_envvars_str(vars, names):
continue
out += "%s=%s\n" % (n, vars[n])
return out
+
+
+def now():
+ """Return datetime instance for current time in UTC.
+ """
+ return datetime.datetime.utcnow().replace(tzinfo=iso8601.iso8601.Utc())
+
+
+def run_testsuite_command(name, cmd, subunit_ops, env=None, outf=None):
+ """Run a testsuite command.
+
+ :param name: Name of the testsuite
+ :param cmd: Command to run
+ :param subunit_ops: Subunit ops to use for reporting results
+ :param env: Environment the test is run in
+ :param outf: File-like object to write standard out to (defaults to sys.stdout)
+ :return: Exit code or None if the test failed to run completely
+ """
+ if outf is None:
+ outf = sys.stdout
+ subunit_ops.start_testsuite(name)
+ subunit_ops.progress(None, subunit.PROGRESS_PUSH)
+ subunit_ops.time(now())
+ try:
+ exitcode = subprocess.call(cmd, shell=True, stdout=outf)
+ except Exception, e:
+ subunit_ops.time(now())
+ subunit_ops.progress(None, subunit.PROGRESS_POP)
+ subunit_ops.end_testsuite(name, "error", "Unable to run %r: %s" % (cmd, e))
+ return None
+
+ subunit_ops.time(now())
+ subunit_ops.progress(None, subunit.PROGRESS_POP)
+
+ if env is not None:
+ envlog = env.get_log()
+ if envlog != "":
+ outf.write("envlog: %s\n" % envlog)
+
+ outf.write("command: %s\n" % cmd)
+ outf.write("expanded command: %s\n" % expand_environment_strings(cmd, os.environ))
+
+ if exitcode == 0:
+ subunit_ops.end_testsuite(name, "success")
+ else:
+ subunit_ops.end_testsuite(name, "failure", "Exit code was %d" % exitcode)
+
+ return exitcode
diff --git a/selftest/selftest.py b/selftest/selftest.py
index 1b2044134c..f35541a3e5 100755
--- a/selftest/selftest.py
+++ b/selftest/selftest.py
@@ -18,8 +18,6 @@
import atexit
from cStringIO import StringIO
-import datetime
-import iso8601
import os
import sys
import signal
@@ -39,10 +37,11 @@ from selftest import (
)
from selftest.client import write_clientconf
from selftest.run import (
- expand_environment_strings,
expand_command_list,
expand_command_run,
exported_envvars_str,
+ now,
+ run_testsuite_command,
)
from selftest.target import (
EnvironmentManager,
@@ -53,9 +52,6 @@ from selftest.target import (
includes = ()
excludes = ()
-def now():
- return datetime.datetime.utcnow().replace(tzinfo=iso8601.iso8601.Utc())
-
def read_excludes(fn):
excludes.extend(testlist.read_test_regexes(fn))
@@ -123,42 +119,20 @@ def cleanup_pcap(pcap_file, exit_code):
os.unlink(pcap_file)
-def run_testsuite(envname, name, cmd):
+def run_testsuite(name, cmd, subunit_ops, env=None):
"""Run a single testsuite.
- :param envname: Name of the environment to ru nin
+ :param env: Environment to run in
:param name: Name of the testsuite
:param cmd: Name of the (fully expanded) command to run
:return: exitcode of the command
"""
pcap_file = setup_pcap(name)
- subunit_ops.start_testsuite(name)
- subunit_ops.progress(None, subunit.PROGRESS_PUSH)
- subunit_ops.time(now())
- try:
- exitcode = subprocess.call(cmd, shell=True)
- except Exception, e:
- subunit_ops.time(now())
- subunit_ops.progress(None, subunit.PROGRESS_POP)
- subunit_ops.end_testsuite(name, "error", "Unable to run %r: %s" % (cmd, e))
+ exitcode = run_testsuite_command(name, cmd, subunit_ops, env)
+ if exitcode is None:
sys.exit(1)
- subunit_ops.time(now())
- subunit_ops.progress(None, subunit.PROGRESS_POP)
-
- envlog = env_manager.getlog_env(envname)
- if envlog != "":
- sys.stdout.write("envlog: %s\n" % envlog)
-
- sys.stdout.write("command: %s\n" % cmd)
- sys.stdout.write("expanded command: %s\n" % expand_environment_strings(cmd, os.environ))
-
- if exitcode == 0:
- subunit_ops.end_testsuite(name, "success")
- else:
- subunit_ops.end_testsuite(name, "failure", "Exit code was %d" % exitcode)
-
cleanup_pcap(pcap_file, exitcode)
if not opts.socket_wrapper_keep_pcap and pcap_file is not None:
@@ -169,6 +143,7 @@ def run_testsuite(envname, name, cmd):
return exitcode
+
if opts.list and opts.testenv:
sys.stderr.write("--list and --testenv are mutually exclusive\n")
sys.exit(1)
@@ -273,9 +248,10 @@ else:
# must terminate in this time, and testenv will only stay alive this
# long
-server_maxtime = 7500
if os.environ.get("SMBD_MAXTIME", ""):
server_maxtime = int(os.environ["SMBD_MAXTIME"])
+else:
+ server_maxtime = 7500
def has_socket_wrapper(bindir):
@@ -466,7 +442,7 @@ def switch_env(name, prefix):
elif name in os.environ:
del os.environ[name]
- return testenv_vars
+ return env
# This 'global' file needs to be empty when we start
dns_host_file_path = os.path.join(prefix_abs, "dns_host_file")
@@ -476,7 +452,8 @@ if os.path.exists(dns_host_file_path):
if opts.testenv:
testenv_name = os.environ.get("SELFTEST_TESTENV", testenv_default)
- testenv_vars = switch_env(testenv_name, prefix)
+ env = switch_env(testenv_name, prefix)
+ testenv_vars = env.get_vars()
os.environ["PIDDIR"] = testenv_vars["PIDDIR"]
os.environ["ENVNAME"] = testenv_name
@@ -515,7 +492,7 @@ elif opts.list:
else:
for (name, envname, cmd, supports_loadfile, supports_idlist, subtests) in todo:
try:
- envvars = switch_env(envname, prefix)
+ env = switch_env(envname, prefix)
except UnsupportedEnvironment:
subunit_ops.start_testsuite(name)
subunit_ops.end_testsuite(name, "skip",
@@ -531,7 +508,7 @@ else:
cmd, tmpf = expand_command_run(cmd, supports_loadfile, supports_idlist,
subtests)
- run_testsuite(envname, name, cmd)
+ run_testsuite(name, cmd, subunit_ops, env=env)
if tmpf is not None:
os.remove(tmpf)
diff --git a/selftest/tests/test_run.py b/selftest/tests/test_run.py
index 894ceaa7fc..de5f4b121b 100644
--- a/selftest/tests/test_run.py
+++ b/selftest/tests/test_run.py
@@ -19,13 +19,18 @@
"""Tests for selftest.run."""
+import datetime
import os
+import subunit
+import tempfile
from selftest.run import (
expand_command_list,
expand_environment_strings,
expand_command_run,
exported_envvars_str,
+ now,
+ run_testsuite_command,
)
from selftest.tests import TestCase
@@ -92,3 +97,91 @@ class ExportedEnvvarsStrTests(TestCase):
def test_vars_unknown(self):
self.assertEquals("foo=1\n",
exported_envvars_str({"foo": "1", "bla": "2"}, ["foo", "bar"]))
+
+
+
+class NowTests(TestCase):
+
+ def test_basic(self):
+ self.assertIsInstance(now(), datetime.datetime)
+ self.assertIsNot(now().tzinfo, None)
+
+
+class MockSubunitOps(object):
+
+ def __init__(self):
+ self.calls = []
+
+ def start_testsuite(self, name):
+ self.calls.append(("start-testsuite", name))
+
+ def progress(self, count, whence):
+ self.calls.append(("progress", count, whence))
+
+ def time(self, t):
+ self.calls.append(("time", ))
+
+ def end_testsuite(self, name, result, details=None):
+ self.calls.append(("end-testsuite", name, result, details))
+
+
+class RunTestsuiteCommandTests(TestCase):
+
+ def test_success_no_env(self):
+ outf = tempfile.TemporaryFile()
+ subunit_ops = MockSubunitOps()
+ exit_code = run_testsuite_command("thetestsuitename", "echo doing something", subunit_ops, outf=outf)
+ self.assertEquals([
+ ("start-testsuite", "thetestsuitename"),
+ ("progress", None, subunit.PROGRESS_PUSH),
+ ("time", ),
+ ("time", ),
+ ("progress", None, subunit.PROGRESS_POP),
+ ("end-testsuite", "thetestsuitename", "success", None),
+ ], subunit_ops.calls)
+ self.assertEquals(0, exit_code)
+ outf.seek(0)
+ self.assertEquals("""\
+doing something
+command: echo doing something
+expanded command: echo doing something
+""", outf.read())
+
+ def test_failure(self):
+ outf = tempfile.TemporaryFile()
+ subunit_ops = MockSubunitOps()
+ exit_code = run_testsuite_command("thetestsuitename", "exit 3", subunit_ops, outf=outf)
+ self.assertEquals([
+ ("start-testsuite", "thetestsuitename"),
+ ("progress", None, subunit.PROGRESS_PUSH),
+ ("time", ),
+ ("time", ),
+ ("progress", None, subunit.PROGRESS_POP),
+ ("end-testsuite", "thetestsuitename", "failure", "Exit code was 3"),
+ ], subunit_ops.calls)
+ self.assertEquals(3, exit_code)
+ outf.seek(0)
+ self.assertEquals("""\
+command: exit 3
+expanded command: exit 3
+""", outf.read())
+
+ def test_error(self):
+ outf = tempfile.TemporaryFile()
+ subunit_ops = MockSubunitOps()
+ exit_code = run_testsuite_command("thetestsuitename",
+ "thisisacommandthatdoesnotexist 2>/dev/null", subunit_ops, outf=outf)
+ self.assertEquals([
+ ("start-testsuite", "thetestsuitename"),
+ ("progress", None, subunit.PROGRESS_PUSH),
+ ("time", ),
+ ("time", ),
+ ("progress", None, subunit.PROGRESS_POP),
+ ("end-testsuite", "thetestsuitename", "failure", "Exit code was 127"),
+ ], subunit_ops.calls)
+ self.assertEquals(127, exit_code)
+ outf.seek(0)
+ self.assertEquals("""\
+command: thisisacommandthatdoesnotexist 2>/dev/null
+expanded command: thisisacommandthatdoesnotexist 2>/dev/null
+""", outf.read())