#!/usr/bin/env python """ TestCmdTests.py: Unit tests for the TestCmd.py module. Copyright 2000-2010 Steven Knight This module is free software, and you may redistribute it and/or modify it under the same terms as Python itself, so long as this copyright message and disclaimer are retained in their original form. IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS CODE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. """ __author__ = "Steven Knight " __revision__ = "TestCmdTests.py 1.3.D001 2010/06/03 12:58:27 knight" import os import shutil import signal import stat from StringIO import StringIO import sys import tempfile import time import types import unittest from UserList import UserList # Strip the current directory so we get the right TestCmd.py module. sys.path = sys.path[1:] import TestCmd def _is_readable(path): # XXX this doesn't take into account UID, it assumes it's our file return os.stat(path)[stat.ST_MODE] & stat.S_IREAD def _is_writable(path): # XXX this doesn't take into account UID, it assumes it's our file return os.stat(path)[stat.ST_MODE] & stat.S_IWRITE def _is_executable(path): # XXX this doesn't take into account UID, it assumes it's our file return os.stat(path)[stat.ST_MODE] & stat.S_IEXEC def _clear_dict(dict, *keys): for key in keys: try: dict[key] = '' # del dict[key] except KeyError: pass import subprocess try: subprocess.Popen.terminate except AttributeError: if sys.platform == 'win32': import win32process def terminate(self): win32process.TerminateProcess(self._handle, 1) else: def terminate(self): os.kill(self.pid, signal.SIGTERM) method = types.MethodType(terminate, None, subprocess.Popen) setattr(subprocess.Popen, 'terminate', method) class ExitError(Exception): pass class TestCmdTestCase(unittest.TestCase): """Base class for TestCmd test cases, with fixture and utility methods.""" def setUp(self): self.orig_cwd = os.getcwd() def tearDown(self): os.chdir(self.orig_cwd) def setup_run_scripts(self): class T: pass t = T() t.script = 'script' t.scriptx = 'scriptx.bat' t.script1 = 'script_1.txt' t.scriptout = 'scriptout' t.scripterr = 'scripterr' fmt = "import os, sys; cwd = os.getcwd(); " + \ "sys.stdout.write('%s: STDOUT: %%s: %%s\\n' %% (cwd, sys.argv[1:])); " + \ "sys.stderr.write('%s: STDERR: %%s: %%s\\n' %% (cwd, sys.argv[1:]))" fmtout = "import os, sys; cwd = os.getcwd(); " + \ "sys.stdout.write('%s: STDOUT: %%s: %%s\\n' %% (cwd, sys.argv[1:]))" fmterr = "import os, sys; cwd = os.getcwd(); " + \ "sys.stderr.write('%s: STDERR: %%s: %%s\\n' %% (cwd, sys.argv[1:]))" text = fmt % (t.script, t.script) textx = fmt % (t.scriptx, t.scriptx) if sys.platform == 'win32': textx = textx.replace('%', '%%') textx = '@python -c "%s"' % textx + ' %1 %2 %3 %4 %5 %6 %7 %8 %9\n' else: textx = '#! /usr/bin/env python\n' + textx + '\n' text1 = 'A first line to be ignored!\n' + fmt % (t.script1, t.script1) textout = fmtout % (t.scriptout) texterr = fmterr % (t.scripterr) run_env = TestCmd.TestCmd(workdir = '') run_env.subdir('sub dir') t.run_env = run_env t.sub_dir = run_env.workpath('sub dir') t.script_path = run_env.workpath('sub dir', t.script) t.scriptx_path = run_env.workpath('sub dir', t.scriptx) t.script1_path = run_env.workpath('sub dir', t.script1) t.scriptout_path = run_env.workpath('sub dir', t.scriptout) t.scripterr_path = run_env.workpath('sub dir', t.scripterr) run_env.write(t.script_path, text) run_env.write(t.scriptx_path, textx) run_env.write(t.script1_path, text1) run_env.write(t.scriptout_path, textout) run_env.write(t.scripterr_path, texterr) os.chmod(t.script_path, 0o644) # XXX UNIX-specific os.chmod(t.scriptx_path, 0o755) # XXX UNIX-specific os.chmod(t.script1_path, 0o644) # XXX UNIX-specific os.chmod(t.scriptout_path, 0o644) # XXX UNIX-specific os.chmod(t.scripterr_path, 0o644) # XXX UNIX-specific t.orig_cwd = os.getcwd() t.workdir = run_env.workpath('sub dir') os.chdir(t.workdir) return t def translate_newlines(self, data): data = data.replace("\r\n", "\n") return data def call_python(self, input, python=None): if python is None: python = sys.executable p = subprocess.Popen(python, stdin=subprocess.PIPE, stderr=subprocess.PIPE, stdout=subprocess.PIPE) stdout, stderr = p.communicate(input) stdout = self.translate_newlines(stdout) stderr = self.translate_newlines(stderr) return stdout, stderr, p.returncode def popen_python(self, input, status=0, stdout="", stderr="", python=None): if python is None: python = sys.executable _stdout, _stderr, _status = self.call_python(input, python) _stdout = self.translate_newlines(_stdout) _stderr = self.translate_newlines(_stderr) assert _status == status, \ "status = %s, expected %s\n" % (str(_status), str(status)) + \ "STDOUT ===================\n" + _stdout + \ "STDERR ===================\n" + _stderr assert _stdout == stdout, \ "Expected STDOUT ==========\n" + stdout + \ "Actual STDOUT ============\n" + _stdout + \ "STDERR ===================\n" + _stderr assert _stderr == stderr, \ "Expected STDERR ==========\n" + stderr + \ "Actual STDERR ============\n" + _stderr def run_match(self, content, *args): expect = "%s: %s: %s: %s\n" % args content = self.translate_newlines(content) assert content == expect, \ "Expected %s ==========\n" % args[1] + expect + \ "Actual %s ============\n" % args[1] + content class __init__TestCase(TestCmdTestCase): def test_init(self): """Test init()""" test = TestCmd.TestCmd() test = TestCmd.TestCmd(description = 'test') test = TestCmd.TestCmd(description = 'test', program = 'foo') test = TestCmd.TestCmd(description = 'test', program = 'foo', universal_newlines=None) class basename_TestCase(TestCmdTestCase): def test_basename(self): """Test basename() [XXX TO BE WRITTEN]""" assert 1 == 1 class cleanup_TestCase(TestCmdTestCase): def test_cleanup(self): """Test cleanup()""" test = TestCmd.TestCmd(workdir = '') wdir = test.workdir test.write('file1', "Test file #1\n") test.cleanup() assert not os.path.exists(wdir) def test_writable(self): """Test cleanup() when the directory isn't writable""" test = TestCmd.TestCmd(workdir = '') wdir = test.workdir test.write('file2', "Test file #2\n") os.chmod(test.workpath('file2'), 0o400) os.chmod(wdir, 0o500) test.cleanup() assert not os.path.exists(wdir) def test_shutil(self): """Test cleanup() when used with shutil""" test = TestCmd.TestCmd(workdir = '') wdir = test.workdir os.chdir(wdir) import shutil save_rmtree = shutil.rmtree def my_rmtree(dir, ignore_errors=0, wdir=wdir, _rmtree=save_rmtree): assert os.getcwd() != wdir return _rmtree(dir, ignore_errors=ignore_errors) try: shutil.rmtree = my_rmtree test.cleanup() finally: shutil.rmtree = save_rmtree def test_atexit(self): """Test cleanup() when atexit is used""" self.popen_python("""from __future__ import print_function import sys sys.path = ['%s'] + sys.path import atexit def my_exitfunc(): print("my_exitfunc()") atexit.register(my_exitfunc) import TestCmd result = TestCmd.TestCmd(workdir = '') sys.exit(0) """ % self.orig_cwd, stdout='my_exitfunc()\n') def test_exitfunc(self): """Test cleanup() when sys.exitfunc is set""" self.popen_python("""from __future__ import print_function import sys sys.path = ['%s'] + sys.path def my_exitfunc(): print("my_exitfunc()") sys.exitfunc = my_exitfunc import TestCmd result = TestCmd.TestCmd(workdir = '') sys.exit(0) """ % self.orig_cwd, stdout='my_exitfunc()\n') class chmod_TestCase(TestCmdTestCase): def test_chmod(self): """Test chmod()""" test = TestCmd.TestCmd(workdir = '', subdir = 'sub') wdir_file1 = os.path.join(test.workdir, 'file1') wdir_sub_file2 = os.path.join(test.workdir, 'sub', 'file2') open(wdir_file1, 'w').write("") open(wdir_sub_file2, 'w').write("") if sys.platform == 'win32': test.chmod(wdir_file1, stat.S_IREAD) test.chmod(['sub', 'file2'], stat.S_IWRITE) file1_mode = stat.S_IMODE(os.stat(wdir_file1)[stat.ST_MODE]) assert file1_mode == 0o444, '0%o' % file1_mode file2_mode = stat.S_IMODE(os.stat(wdir_sub_file2)[stat.ST_MODE]) assert file2_mode == 0o666, '0%o' % file2_mode test.chmod('file1', stat.S_IWRITE) test.chmod(wdir_sub_file2, stat.S_IREAD) file1_mode = stat.S_IMODE(os.stat(wdir_file1)[stat.ST_MODE]) assert file1_mode == 0o666, '0%o' % file1_mode file2_mode = stat.S_IMODE(os.stat(wdir_sub_file2)[stat.ST_MODE]) assert file2_mode == 0o444, '0%o' % file2_mode else: test.chmod(wdir_file1, 0o700) test.chmod(['sub', 'file2'], 0o760) file1_mode = stat.S_IMODE(os.stat(wdir_file1)[stat.ST_MODE]) assert file1_mode == 0o700, '0%o' % file1_mode file2_mode = stat.S_IMODE(os.stat(wdir_sub_file2)[stat.ST_MODE]) assert file2_mode == 0o760, '0%o' % file2_mode test.chmod('file1', 0o765) test.chmod(wdir_sub_file2, 0o567) file1_mode = stat.S_IMODE(os.stat(wdir_file1)[stat.ST_MODE]) assert file1_mode == 0o765, '0%o' % file1_mode file2_mode = stat.S_IMODE(os.stat(wdir_sub_file2)[stat.ST_MODE]) assert file2_mode == 0o567, '0%o' % file2_mode class combine_TestCase(TestCmdTestCase): def test_combine(self): """Test combining stdout and stderr""" run_env = TestCmd.TestCmd(workdir = '') run_env.write('run1', """import sys sys.stdout.write("run1 STDOUT %s\\n" % sys.argv[1:]) sys.stdout.write("run1 STDOUT second line\\n") sys.stderr.write("run1 STDERR %s\\n" % sys.argv[1:]) sys.stderr.write("run1 STDERR second line\\n") sys.stdout.write("run1 STDOUT third line\\n") sys.stderr.write("run1 STDERR third line\\n") """) run_env.write('run2', """import sys sys.stdout.write("run2 STDOUT %s\\n" % sys.argv[1:]) sys.stdout.write("run2 STDOUT second line\\n") sys.stderr.write("run2 STDERR %s\\n" % sys.argv[1:]) sys.stderr.write("run2 STDERR second line\\n") sys.stdout.write("run2 STDOUT third line\\n") sys.stderr.write("run2 STDERR third line\\n") """) cwd = os.getcwd() os.chdir(run_env.workdir) # Everything before this prepared our "source directory." # Now do the real test. try: test = TestCmd.TestCmd(interpreter = 'python', workdir = '', combine = 1) try: output = test.stdout() except IndexError: pass else: raise IndexError("got unexpected output:\n\t`%s'\n" % output) # The underlying system subprocess implementations can combine # stdout and stderr in different orders, so we accomodate both. test.program_set('run1') test.run(arguments = 'foo bar') stdout_lines = """\ run1 STDOUT ['foo', 'bar'] run1 STDOUT second line run1 STDOUT third line """ stderr_lines = """\ run1 STDERR ['foo', 'bar'] run1 STDERR second line run1 STDERR third line """ foo_bar_expect = (stdout_lines + stderr_lines, stderr_lines + stdout_lines) test.program_set('run2') test.run(arguments = 'snafu') stdout_lines = """\ run2 STDOUT ['snafu'] run2 STDOUT second line run2 STDOUT third line """ stderr_lines = """\ run2 STDERR ['snafu'] run2 STDERR second line run2 STDERR third line """ snafu_expect = (stdout_lines + stderr_lines, stderr_lines + stdout_lines) # XXX SHOULD TEST ABSOLUTE NUMBER AS WELL output = test.stdout() output = self.translate_newlines(output) assert output in snafu_expect, output error = test.stderr() assert error == '', error output = test.stdout(run = -1) output = self.translate_newlines(output) assert output in foo_bar_expect, output error = test.stderr(-1) assert error == '', error finally: os.chdir(cwd) class description_TestCase(TestCmdTestCase): def test_description(self): """Test description()""" test = TestCmd.TestCmd() assert test.description is None, 'initialized description?' test = TestCmd.TestCmd(description = 'test') assert test.description == 'test', 'uninitialized description' test.description_set('foo') assert test.description == 'foo', 'did not set description' class diff_TestCase(TestCmdTestCase): def test_diff_re(self): """Test diff_re()""" result = TestCmd.diff_re(["abcde"], ["abcde"]) assert result == [], result result = TestCmd.diff_re(["a.*e"], ["abcde"]) assert result == [], result result = TestCmd.diff_re(["a.*e"], ["xxx"]) assert result == ['1c1', "< 'a.*e'", '---', "> 'xxx'"], result def test_diff_custom_function(self): """Test diff() using a custom function""" self.popen_python("""import sys sys.path = ['%s'] + sys.path import TestCmd def my_diff(a, b): return [ '*****', a, '*****', b, '*****', ] test = TestCmd.TestCmd(diff = my_diff) test.diff("a\\nb1\\nc\\n", "a\\nb2\\nc\\n", "STDOUT") sys.exit(0) """ % self.orig_cwd, stdout = """\ STDOUT========================================================================== ***** ['a', 'b1', 'c'] ***** ['a', 'b2', 'c'] ***** """) def test_diff_string(self): self.popen_python("""import sys sys.path = ['%s'] + sys.path import TestCmd test = TestCmd.TestCmd(diff = 'diff_re') test.diff("a\\nb1\\nc\\n", "a\\nb2\\nc\\n", 'STDOUT') sys.exit(0) """ % self.orig_cwd, stdout = """\ STDOUT========================================================================== 2c2 < 'b1' --- > 'b2' """) def test_error(self): """Test handling a compilation error in TestCmd.diff_re()""" script_input = """import sys sys.path = ['%s'] + sys.path import TestCmd assert TestCmd.diff_re(["a.*(e"], ["abcde"]) sys.exit(0) """ % self.orig_cwd stdout, stderr, status = self.call_python(script_input) assert status == 1, status expect1 = "Regular expression error in '^a.*(e$': missing )\n" expect2 = "Regular expression error in '^a.*(e$': unbalanced parenthesis\n" assert (stderr.find(expect1) != -1 or stderr.find(expect2) != -1), repr(stderr) def test_simple_diff_static_method(self): """Test calling the TestCmd.TestCmd.simple_diff() static method""" self.popen_python("""import sys sys.path = ['%s'] + sys.path import TestCmd result = TestCmd.TestCmd.simple_diff(['a', 'b', 'c', 'e', 'f1'], ['a', 'c', 'd', 'e', 'f2']) expect = ['2d1', '< b', '3a3', '> d', '5c5', '< f1', '---', '> f2'] assert result == expect, result sys.exit(0) """ % self.orig_cwd) def test_context_diff_static_method(self): """Test calling the TestCmd.TestCmd.context_diff() static method""" self.popen_python("""import sys sys.path = ['%s'] + sys.path import TestCmd result = TestCmd.TestCmd.context_diff(['a\\n', 'b\\n', 'c\\n', 'e\\n', 'f1\\n'], ['a\\n', 'c\\n', 'd\\n', 'e\\n', 'f2\\n']) result = list(result) expect = [ '*** \\n', '--- \\n', '***************\\n', '*** 1,5 ****\\n', ' a\\n', '- b\\n', ' c\\n', ' e\\n', '! f1\\n', '--- 1,5 ----\\n', ' a\\n', ' c\\n', '+ d\\n', ' e\\n', '! f2\\n', ] assert result == expect, result sys.exit(0) """ % self.orig_cwd) def test_unified_diff_static_method(self): """Test calling the TestCmd.TestCmd.unified_diff() static method""" self.popen_python("""import sys sys.path = ['%s'] + sys.path import TestCmd result = TestCmd.TestCmd.unified_diff(['a\\n', 'b\\n', 'c\\n', 'e\\n', 'f1\\n'], ['a\\n', 'c\\n', 'd\\n', 'e\\n', 'f2\\n']) result = list(result) expect = [ '--- \\n', '+++ \\n', '@@ -1,5 +1,5 @@\\n', ' a\\n', '-b\\n', ' c\\n', '+d\\n', ' e\\n', '-f1\\n', '+f2\\n' ] assert result == expect, result sys.exit(0) """ % self.orig_cwd) def test_diff_re_static_method(self): """Test calling the TestCmd.TestCmd.diff_re() static method""" self.popen_python("""import sys sys.path = ['%s'] + sys.path import TestCmd result = TestCmd.TestCmd.diff_re(['a', 'b', 'c', '.', 'f1'], ['a', 'c', 'd', 'e', 'f2']) expect = [ '2c2', "< 'b'", '---', "> 'c'", '3c3', "< 'c'", '---', "> 'd'", '5c5', "< 'f1'", '---', "> 'f2'" ] assert result == expect, result sys.exit(0) """ % self.orig_cwd) class diff_stderr_TestCase(TestCmdTestCase): def test_diff_stderr_default(self): """Test diff_stderr() default behavior""" self.popen_python(r"""import sys sys.path = ['%s'] + sys.path import TestCmd test = TestCmd.TestCmd() test.diff_stderr('a\nb1\nc\n', 'a\nb2\nc\n') sys.exit(0) """ % self.orig_cwd, stdout="""\ 2c2 < b1 --- > b2 """) def test_diff_stderr_not_affecting_diff_stdout(self): """Test diff_stderr() not affecting diff_stdout() behavior""" self.popen_python(r"""from __future__ import print_function import sys sys.path = ['%s'] + sys.path import TestCmd test = TestCmd.TestCmd(diff_stderr='diff_re') print("diff_stderr:") test.diff_stderr('a\nb.\nc\n', 'a\nbb\nc\n') print("diff_stdout:") test.diff_stdout('a\nb.\nc\n', 'a\nbb\nc\n') sys.exit(0) """ % self.orig_cwd, stdout="""\ diff_stderr: diff_stdout: 2c2 < b. --- > bb """) def test_diff_stderr_custom_function(self): """Test diff_stderr() using a custom function""" self.popen_python(r"""import sys sys.path = ['%s'] + sys.path import TestCmd def my_diff(a, b): return ["a:"] + a + ["b:"] + b test = TestCmd.TestCmd(diff_stderr=my_diff) test.diff_stderr('abc', 'def') sys.exit(0) """ % self.orig_cwd, stdout="""\ a: abc b: def """) def test_diff_stderr_TestCmd_function(self): """Test diff_stderr() using a TestCmd function""" self.popen_python(r"""import sys sys.path = ['%s'] + sys.path import TestCmd test = TestCmd.TestCmd(diff_stderr = TestCmd.diff_re) test.diff_stderr('a\n.\n', 'b\nc\n') sys.exit(0) """ % self.orig_cwd, stdout="""\ 1c1 < 'a' --- > 'b' """) def test_diff_stderr_static_method(self): """Test diff_stderr() using a static method""" self.popen_python(r"""import sys sys.path = ['%s'] + sys.path import TestCmd test = TestCmd.TestCmd(diff_stderr=TestCmd.TestCmd.diff_re) test.diff_stderr('a\n.\n', 'b\nc\n') sys.exit(0) """ % self.orig_cwd, stdout="""\ 1c1 < 'a' --- > 'b' """) def test_diff_stderr_string(self): """Test diff_stderr() using a string to fetch the diff method""" self.popen_python(r"""import sys sys.path = ['%s'] + sys.path import TestCmd test = TestCmd.TestCmd(diff_stderr='diff_re') test.diff_stderr('a\n.\n', 'b\nc\n') sys.exit(0) """ % self.orig_cwd, stdout="""\ 1c1 < 'a' --- > 'b' """) class diff_stdout_TestCase(TestCmdTestCase): def test_diff_stdout_default(self): """Test diff_stdout() default behavior""" self.popen_python(r"""import sys sys.path = ['%s'] + sys.path import TestCmd test = TestCmd.TestCmd() test.diff_stdout('a\nb1\nc\n', 'a\nb2\nc\n') sys.exit(0) """ % self.orig_cwd, stdout="""\ 2c2 < b1 --- > b2 """) def test_diff_stdout_not_affecting_diff_stderr(self): """Test diff_stdout() not affecting diff_stderr() behavior""" self.popen_python(r"""from __future__ import print_function import sys sys.path = ['%s'] + sys.path import TestCmd test = TestCmd.TestCmd(diff_stdout='diff_re') print("diff_stdout:") test.diff_stdout('a\nb.\nc\n', 'a\nbb\nc\n') print("diff_stderr:") test.diff_stderr('a\nb.\nc\n', 'a\nbb\nc\n') sys.exit(0) """ % self.orig_cwd, stdout="""\ diff_stdout: diff_stderr: 2c2 < b. --- > bb """) def test_diff_stdout_custom_function(self): """Test diff_stdout() using a custom function""" self.popen_python(r"""import sys sys.path = ['%s'] + sys.path import TestCmd def my_diff(a, b): return ["a:"] + a + ["b:"] + b test = TestCmd.TestCmd(diff_stdout=my_diff) test.diff_stdout('abc', 'def') sys.exit(0) """ % self.orig_cwd, stdout="""\ a: abc b: def """) def test_diff_stdout_TestCmd_function(self): """Test diff_stdout() using a TestCmd function""" self.popen_python(r"""import sys sys.path = ['%s'] + sys.path import TestCmd test = TestCmd.TestCmd(diff_stdout = TestCmd.diff_re) test.diff_stdout('a\n.\n', 'b\nc\n') sys.exit(0) """ % self.orig_cwd, stdout="""\ 1c1 < 'a' --- > 'b' """) def test_diff_stdout_static_method(self): """Test diff_stdout() using a static method""" self.popen_python(r"""import sys sys.path = ['%s'] + sys.path import TestCmd test = TestCmd.TestCmd(diff_stdout=TestCmd.TestCmd.diff_re) test.diff_stdout('a\n.\n', 'b\nc\n') sys.exit(0) """ % self.orig_cwd, stdout="""\ 1c1 < 'a' --- > 'b' """) def test_diff_stdout_string(self): """Test diff_stdout() using a string to fetch the diff method""" self.popen_python(r"""import sys sys.path = ['%s'] + sys.path import TestCmd test = TestCmd.TestCmd(diff_stdout='diff_re') test.diff_stdout('a\n.\n', 'b\nc\n') sys.exit(0) """ % self.orig_cwd, stdout="""\ 1c1 < 'a' --- > 'b' """) class exit_TestCase(TestCmdTestCase): def test_exit(self): """Test exit()""" def _test_it(cwd, tempdir, condition, preserved): close_true = {'pass_test': 1, 'fail_test': 0, 'no_result': 0} exit_status = {'pass_test': 0, 'fail_test': 1, 'no_result': 2} result_string = {'pass_test': "PASSED\n", 'fail_test': "FAILED test at line 5 of \n", 'no_result': "NO RESULT for test at line 5 of \n"} global ExitError input = """import sys sys.path = ['%s'] + sys.path import TestCmd test = TestCmd.TestCmd(workdir = '%s') test.%s() """ % (cwd, tempdir, condition) stdout, stderr, status = self.call_python(input, python="python") if close_true[condition]: unexpected = (status != 0) else: unexpected = (status == 0) if unexpected: msg = "Unexpected exit status from python: %s\n" raise ExitError(msg % status + stdout + stderr) if status != exit_status[condition]: msg = "Expected exit status %d, got %d\n" raise ExitError(msg % (exit_status[condition], status)) if stderr != result_string[condition]: msg = "Expected error output:\n%sGot error output:\n%s" raise ExitError(msg % (result_string[condition], stderr)) if preserved: if not os.path.exists(tempdir): msg = "Working directory %s was mistakenly removed\n" raise ExitError(msg % tempdir + stdout) else: if os.path.exists(tempdir): msg = "Working directory %s was mistakenly preserved\n" raise ExitError(msg % tempdir + stdout) run_env = TestCmd.TestCmd(workdir = '') os.chdir(run_env.workdir) # Everything before this prepared our "source directory." # Now do the real test. try: cwd = self.orig_cwd _clear_dict(os.environ, 'PRESERVE', 'PRESERVE_PASS', 'PRESERVE_FAIL', 'PRESERVE_NO_RESULT') _test_it(cwd, 'dir01', 'pass_test', 0) _test_it(cwd, 'dir02', 'fail_test', 0) _test_it(cwd, 'dir03', 'no_result', 0) os.environ['PRESERVE'] = '1' _test_it(cwd, 'dir04', 'pass_test', 1) _test_it(cwd, 'dir05', 'fail_test', 1) _test_it(cwd, 'dir06', 'no_result', 1) os.environ['PRESERVE'] = '' # del os.environ['PRESERVE'] os.environ['PRESERVE_PASS'] = '1' _test_it(cwd, 'dir07', 'pass_test', 1) _test_it(cwd, 'dir08', 'fail_test', 0) _test_it(cwd, 'dir09', 'no_result', 0) os.environ['PRESERVE_PASS'] = '' # del os.environ['PRESERVE_PASS'] os.environ['PRESERVE_FAIL'] = '1' _test_it(cwd, 'dir10', 'pass_test', 0) _test_it(cwd, 'dir11', 'fail_test', 1) _test_it(cwd, 'dir12', 'no_result', 0) os.environ['PRESERVE_FAIL'] = '' # del os.environ['PRESERVE_FAIL'] os.environ['PRESERVE_NO_RESULT'] = '1' _test_it(cwd, 'dir13', 'pass_test', 0) _test_it(cwd, 'dir14', 'fail_test', 0) _test_it(cwd, 'dir15', 'no_result', 1) os.environ['PRESERVE_NO_RESULT'] = '' # del os.environ['PRESERVE_NO_RESULT'] finally: _clear_dict(os.environ, 'PRESERVE', 'PRESERVE_PASS', 'PRESERVE_FAIL', 'PRESERVE_NO_RESULT') class fail_test_TestCase(TestCmdTestCase): def test_fail_test(self): """Test fail_test()""" run_env = TestCmd.TestCmd(workdir = '') run_env.write('run', """import sys sys.stdout.write("run: STDOUT\\n") sys.stderr.write("run: STDERR\\n") """) os.chdir(run_env.workdir) # Everything before this prepared our "source directory." # Now do the real test. self.popen_python("""import sys sys.path = ['%s'] + sys.path import TestCmd TestCmd.fail_test(condition = 1) """ % self.orig_cwd, status = 1, stderr = "FAILED test at line 4 of \n") self.popen_python("""import sys sys.path = ['%s'] + sys.path import TestCmd test = TestCmd.TestCmd(program = 'run', interpreter = 'python', workdir = '') test.run() test.fail_test(condition = (test.status == 0)) """ % self.orig_cwd, status = 1, stderr = "FAILED test of %s\n\tat line 6 of \n" % run_env.workpath('run')) self.popen_python("""import sys sys.path = ['%s'] + sys.path import TestCmd test = TestCmd.TestCmd(program = 'run', interpreter = 'python', description = 'xyzzy', workdir = '') test.run() test.fail_test(condition = (test.status == 0)) """ % self.orig_cwd, status = 1, stderr = "FAILED test of %s [xyzzy]\n\tat line 6 of \n" % run_env.workpath('run')) self.popen_python("""import sys sys.path = ['%s'] + sys.path import TestCmd test = TestCmd.TestCmd(program = 'run', interpreter = 'python', workdir = '') test.run() def xxx(): sys.stderr.write("printed on failure\\n") test.fail_test(condition = (test.status == 0), function = xxx) """ % self.orig_cwd, status = 1, stderr = "printed on failure\nFAILED test of %s\n\tat line 8 of \n" % run_env.workpath('run')) self.popen_python("""import sys sys.path = ['%s'] + sys.path import TestCmd def test1(self): self.run() self.fail_test(condition = (self.status == 0)) def test2(self): test1(self) test2(TestCmd.TestCmd(program = 'run', interpreter = 'python', workdir = '')) """ % self.orig_cwd, status = 1, stderr = "FAILED test of %s\n\tat line 6 of (test1)\n\tfrom line 8 of (test2)\n\tfrom line 9 of \n" % run_env.workpath('run')) self.popen_python("""import sys sys.path = ['%s'] + sys.path import TestCmd def test1(self): self.run() self.fail_test(condition = (self.status == 0), skip = 1) def test2(self): test1(self) test2(TestCmd.TestCmd(program = 'run', interpreter = 'python', workdir = '')) """ % self.orig_cwd, status = 1, stderr = "FAILED test of %s\n\tat line 8 of (test2)\n\tfrom line 9 of \n" % run_env.workpath('run')) class interpreter_TestCase(TestCmdTestCase): def test_interpreter(self): """Test interpreter()""" run_env = TestCmd.TestCmd(workdir = '') run_env.write('run', """import sys sys.stdout.write("run: STDOUT\\n") sys.stderr.write("run: STDERR\\n") """) os.chdir(run_env.workdir) # Everything before this prepared our "source directory." # Now do the real test. test = TestCmd.TestCmd(program = 'run', workdir = '') test.interpreter_set('foo') assert test.interpreter == 'foo', 'did not set interpreter' test.interpreter_set('python') assert test.interpreter == 'python', 'did not set interpreter' test.run() class match_TestCase(TestCmdTestCase): def test_match_default(self): """Test match() default behavior""" test = TestCmd.TestCmd() assert test.match("abcde\n", "a.*e\n") assert test.match("12345\nabcde\n", "1\\d+5\na.*e\n") lines = ["vwxyz\n", "67890\n"] regexes = ["v[^a-u]*z\n", "6[^ ]+0\n"] assert test.match(lines, regexes) def test_match_custom_function(self): """Test match() using a custom function""" def match_length(lines, matches): return len(lines) == len(matches) test = TestCmd.TestCmd(match=match_length) assert not test.match("123\n", "1\n") assert test.match("123\n", "111\n") assert not test.match("123\n123\n", "1\n1\n") assert test.match("123\n123\n", "111\n111\n") lines = ["123\n", "123\n"] regexes = ["1\n", "1\n"] assert test.match(lines, regexes) # due to equal numbers of lines def test_match_TestCmd_function(self): """Test match() using a TestCmd function""" test = TestCmd.TestCmd(match = TestCmd.match_exact) assert not test.match("abcde\n", "a.*e\n") assert test.match("abcde\n", "abcde\n") assert not test.match("12345\nabcde\n", "1\d+5\na.*e\n") assert test.match("12345\nabcde\n", "12345\nabcde\n") lines = ["vwxyz\n", "67890\n"] regexes = ["v[^a-u]*z\n", "6[^ ]+0\n"] assert not test.match(lines, regexes) assert test.match(lines, lines) def test_match_static_method(self): """Test match() using a static method""" test = TestCmd.TestCmd(match=TestCmd.TestCmd.match_exact) assert not test.match("abcde\n", "a.*e\n") assert test.match("abcde\n", "abcde\n") assert not test.match("12345\nabcde\n", "1\d+5\na.*e\n") assert test.match("12345\nabcde\n", "12345\nabcde\n") lines = ["vwxyz\n", "67890\n"] regexes = ["v[^a-u]*z\n", "6[^ ]+0\n"] assert not test.match(lines, regexes) assert test.match(lines, lines) def test_match_string(self): """Test match() using a string to fetch the match method""" test = TestCmd.TestCmd(match='match_exact') assert not test.match("abcde\n", "a.*e\n") assert test.match("abcde\n", "abcde\n") assert not test.match("12345\nabcde\n", "1\d+5\na.*e\n") assert test.match("12345\nabcde\n", "12345\nabcde\n") lines = ["vwxyz\n", "67890\n"] regexes = ["v[^a-u]*z\n", "6[^ ]+0\n"] assert not test.match(lines, regexes) assert test.match(lines, lines) class match_exact_TestCase(TestCmdTestCase): def test_match_exact_function(self): """Test calling the TestCmd.match_exact() function""" assert not TestCmd.match_exact("abcde\\n", "a.*e\\n") assert TestCmd.match_exact("abcde\\n", "abcde\\n") def test_match_exact_instance_method(self): """Test calling the TestCmd.TestCmd().match_exact() instance method""" test = TestCmd.TestCmd() assert not test.match_exact("abcde\\n", "a.*e\\n") assert test.match_exact("abcde\\n", "abcde\\n") def test_match_exact_static_method(self): """Test calling the TestCmd.TestCmd.match_exact() static method""" assert not TestCmd.TestCmd.match_exact("abcde\\n", "a.*e\\n") assert TestCmd.TestCmd.match_exact("abcde\\n", "abcde\\n") def test_evaluation(self): """Test match_exact() evaluation""" test = TestCmd.TestCmd() assert not test.match_exact("abcde\n", "a.*e\n") assert test.match_exact("abcde\n", "abcde\n") assert not test.match_exact(["12345\n", "abcde\n"], ["1[0-9]*5\n", "a.*e\n"]) assert test.match_exact(["12345\n", "abcde\n"], ["12345\n", "abcde\n"]) assert not test.match_exact(UserList(["12345\n", "abcde\n"]), ["1[0-9]*5\n", "a.*e\n"]) assert test.match_exact(UserList(["12345\n", "abcde\n"]), ["12345\n", "abcde\n"]) assert not test.match_exact(["12345\n", "abcde\n"], UserList(["1[0-9]*5\n", "a.*e\n"])) assert test.match_exact(["12345\n", "abcde\n"], UserList(["12345\n", "abcde\n"])) assert not test.match_exact("12345\nabcde\n", "1[0-9]*5\na.*e\n") assert test.match_exact("12345\nabcde\n", "12345\nabcde\n") lines = ["vwxyz\n", "67890\n"] regexes = ["v[^a-u]*z\n", "6[^ ]+0\n"] assert not test.match_exact(lines, regexes) assert test.match_exact(lines, lines) class match_re_dotall_TestCase(TestCmdTestCase): def test_match_re_dotall_function(self): """Test calling the TestCmd.match_re_dotall() function""" assert TestCmd.match_re_dotall("abcde\nfghij\n", "a.*j\n") def test_match_re_dotall_instance_method(self): """Test calling the TestCmd.TestCmd().match_re_dotall() instance method""" test = TestCmd.TestCmd() test.match_re_dotall("abcde\\nfghij\\n", "a.*j\\n") def test_match_re_dotall_static_method(self): """Test calling the TestCmd.TestCmd.match_re_dotall() static method""" assert TestCmd.TestCmd.match_re_dotall("abcde\nfghij\n", "a.*j\n") def test_error(self): """Test handling a compilation error in TestCmd.match_re_dotall()""" run_env = TestCmd.TestCmd(workdir = '') cwd = os.getcwd() os.chdir(run_env.workdir) # Everything before this prepared our "source directory." # Now do the real test. try: script_input = """import sys sys.path = ['%s'] + sys.path import TestCmd assert TestCmd.match_re_dotall("abcde", "a.*(e") sys.exit(0) """ % cwd stdout, stderr, status = self.call_python(script_input) assert status == 1, status expect1 = "Regular expression error in '^a.*(e$': missing )\n" expect2 = "Regular expression error in '^a.*(e$': unbalanced parenthesis\n" assert (stderr.find(expect1) != -1 or stderr.find(expect2) != -1), repr(stderr) finally: os.chdir(cwd) def test_evaluation(self): """Test match_re_dotall() evaluation""" test = TestCmd.TestCmd() assert test.match_re_dotall("abcde\nfghij\n", "a.*e\nf.*j\n") assert test.match_re_dotall("abcde\nfghij\n", "a[^j]*j\n") assert test.match_re_dotall("abcde\nfghij\n", "abcde\nfghij\n") assert test.match_re_dotall(["12345\n", "abcde\n", "fghij\n"], ["1[0-9]*5\n", "a.*e\n", "f.*j\n"]) assert test.match_re_dotall(["12345\n", "abcde\n", "fghij\n"], ["1.*j\n"]) assert test.match_re_dotall(["12345\n", "abcde\n", "fghij\n"], ["12345\n", "abcde\n", "fghij\n"]) assert test.match_re_dotall(UserList(["12345\n", "abcde\n", "fghij\n"]), ["1[0-9]*5\n", "a.*e\n", "f.*j\n"]) assert test.match_re_dotall(UserList(["12345\n", "abcde\n", "fghij\n"]), ["1.*j\n"]) assert test.match_re_dotall(UserList(["12345\n", "abcde\n", "fghij\n"]), ["12345\n", "abcde\n", "fghij\n"]) assert test.match_re_dotall(["12345\n", "abcde\n", "fghij\n"], UserList(["1[0-9]*5\n", "a.*e\n", "f.*j\n"])) assert test.match_re_dotall(["12345\n", "abcde\n", "fghij\n"], UserList(["1.*j\n"])) assert test.match_re_dotall(["12345\n", "abcde\n", "fghij\n"], UserList(["12345\n", "abcde\n", "fghij\n"])) assert test.match_re_dotall("12345\nabcde\nfghij\n", "1[0-9]*5\na.*e\nf.*j\n") assert test.match_re_dotall("12345\nabcde\nfghij\n", "1.*j\n") assert test.match_re_dotall("12345\nabcde\nfghij\n", "12345\nabcde\nfghij\n") lines = ["vwxyz\n", "67890\n"] regexes = ["v[^a-u]*z\n", "6[^ ]+0\n"] assert test.match_re_dotall(lines, regexes) assert test.match_re_dotall(lines, lines) class match_re_TestCase(TestCmdTestCase): def test_match_re_function(self): """Test calling the TestCmd.match_re() function""" assert TestCmd.match_re("abcde\n", "a.*e\n") def test_match_re_instance_method(self): """Test calling the TestCmd.TestCmd().match_re() instance method""" test = TestCmd.TestCmd() assert test.match_re("abcde\n", "a.*e\n") def test_match_re_static_method(self): """Test calling the TestCmd.TestCmd.match_re() static method""" assert TestCmd.TestCmd.match_re("abcde\n", "a.*e\n") def test_error(self): """Test handling a compilation error in TestCmd.match_re()""" run_env = TestCmd.TestCmd(workdir = '') cwd = os.getcwd() os.chdir(run_env.workdir) # Everything before this prepared our "source directory." # Now do the real test. try: script_input = """import sys sys.path = ['%s'] + sys.path import TestCmd assert TestCmd.match_re("abcde\\n", "a.*(e\\n") sys.exit(0) """ % cwd stdout, stderr, status = self.call_python(script_input) assert status == 1, status expect1 = "Regular expression error in '^a.*(e$': missing )\n" expect2 = "Regular expression error in '^a.*(e$': unbalanced parenthesis\n" assert (stderr.find(expect1) != -1 or stderr.find(expect2) != -1), repr(stderr) finally: os.chdir(cwd) def test_evaluation(self): """Test match_re() evaluation""" test = TestCmd.TestCmd() assert test.match_re("abcde\n", "a.*e\n") assert test.match_re("abcde\n", "abcde\n") assert test.match_re(["12345\n", "abcde\n"], ["1[0-9]*5\n", "a.*e\n"]) assert test.match_re(["12345\n", "abcde\n"], ["12345\n", "abcde\n"]) assert test.match_re(UserList(["12345\n", "abcde\n"]), ["1[0-9]*5\n", "a.*e\n"]) assert test.match_re(UserList(["12345\n", "abcde\n"]), ["12345\n", "abcde\n"]) assert test.match_re(["12345\n", "abcde\n"], UserList(["1[0-9]*5\n", "a.*e\n"])) assert test.match_re(["12345\n", "abcde\n"], UserList(["12345\n", "abcde\n"])) assert test.match_re("12345\nabcde\n", "1[0-9]*5\na.*e\n") assert test.match_re("12345\nabcde\n", "12345\nabcde\n") lines = ["vwxyz\n", "67890\n"] regexes = ["v[^a-u]*z\n", "6[^ ]+0\n"] assert test.match_re(lines, regexes) assert test.match_re(lines, lines) class match_stderr_TestCase(TestCmdTestCase): def test_match_stderr_default(self): """Test match_stderr() default behavior""" test = TestCmd.TestCmd() assert test.match_stderr("abcde\n", "a.*e\n") assert test.match_stderr("12345\nabcde\n", "1\\d+5\na.*e\n") lines = ["vwxyz\n", "67890\n"] regexes = ["v[^a-u]*z\n", "6[^ ]+0\n"] assert test.match_stderr(lines, regexes) def test_match_stderr_not_affecting_match_stdout(self): """Test match_stderr() not affecting match_stdout() behavior""" test = TestCmd.TestCmd(match_stderr=TestCmd.TestCmd.match_exact) assert not test.match_stderr("abcde\n", "a.*e\n") assert test.match_stderr("abcde\n", "abcde\n") assert not test.match_stderr("12345\nabcde\n", "1\\d+5\na.*e\n") assert test.match_stderr("12345\nabcde\n", "12345\nabcde\n") lines = ["vwxyz\n", "67890\n"] regexes = ["v[^a-u]*z\n", "6[^ ]+0\n"] assert not test.match_stderr(lines, regexes) assert test.match_stderr(lines, lines) assert test.match_stdout("abcde\n", "a.*e\n") assert test.match_stdout("12345\nabcde\n", "1\\d+5\na.*e\n") lines = ["vwxyz\n", "67890\n"] regexes = ["v[^a-u]*z\n", "6[^ ]+0\n"] assert test.match_stdout(lines, regexes) def test_match_stderr_custom_function(self): """Test match_stderr() using a custom function""" def match_length(lines, matches): return len(lines) == len(matches) test = TestCmd.TestCmd(match_stderr=match_length) assert not test.match_stderr("123\n", "1\n") assert test.match_stderr("123\n", "111\n") assert not test.match_stderr("123\n123\n", "1\n1\n") assert test.match_stderr("123\n123\n", "111\n111\n") lines = ["123\n", "123\n"] regexes = ["1\n", "1\n"] assert test.match_stderr(lines, regexes) # equal numbers of lines def test_match_stderr_TestCmd_function(self): """Test match_stderr() using a TestCmd function""" test = TestCmd.TestCmd(match_stderr = TestCmd.match_exact) assert not test.match_stderr("abcde\n", "a.*e\n") assert test.match_stderr("abcde\n", "abcde\n") assert not test.match_stderr("12345\nabcde\n", "1\d+5\na.*e\n") assert test.match_stderr("12345\nabcde\n", "12345\nabcde\n") lines = ["vwxyz\n", "67890\n"] regexes = ["v[^a-u]*z\n", "6[^ ]+0\n"] assert not test.match_stderr(lines, regexes) assert test.match_stderr(lines, lines) def test_match_stderr_static_method(self): """Test match_stderr() using a static method""" test = TestCmd.TestCmd(match_stderr=TestCmd.TestCmd.match_exact) assert not test.match_stderr("abcde\n", "a.*e\n") assert test.match_stderr("abcde\n", "abcde\n") assert not test.match_stderr("12345\nabcde\n", "1\d+5\na.*e\n") assert test.match_stderr("12345\nabcde\n", "12345\nabcde\n") lines = ["vwxyz\n", "67890\n"] regexes = ["v[^a-u]*z\n", "6[^ ]+0\n"] assert not test.match_stderr(lines, regexes) assert test.match_stderr(lines, lines) def test_match_stderr_string(self): """Test match_stderr() using a string to fetch the match method""" test = TestCmd.TestCmd(match_stderr='match_exact') assert not test.match_stderr("abcde\n", "a.*e\n") assert test.match_stderr("abcde\n", "abcde\n") assert not test.match_stderr("12345\nabcde\n", "1\d+5\na.*e\n") assert test.match_stderr("12345\nabcde\n", "12345\nabcde\n") lines = ["vwxyz\n", "67890\n"] regexes = ["v[^a-u]*z\n", "6[^ ]+0\n"] assert not test.match_stderr(lines, regexes) assert test.match_stderr(lines, lines) class match_stdout_TestCase(TestCmdTestCase): def test_match_stdout_default(self): """Test match_stdout() default behavior""" test = TestCmd.TestCmd() assert test.match_stdout("abcde\n", "a.*e\n") assert test.match_stdout("12345\nabcde\n", "1\\d+5\na.*e\n") lines = ["vwxyz\n", "67890\n"] regexes = ["v[^a-u]*z\n", "6[^ ]+0\n"] assert test.match_stdout(lines, regexes) def test_match_stdout_not_affecting_match_stderr(self): """Test match_stdout() not affecting match_stderr() behavior""" test = TestCmd.TestCmd(match_stdout=TestCmd.TestCmd.match_exact) assert not test.match_stdout("abcde\n", "a.*e\n") assert test.match_stdout("abcde\n", "abcde\n") assert not test.match_stdout("12345\nabcde\n", "1\\d+5\na.*e\n") assert test.match_stdout("12345\nabcde\n", "12345\nabcde\n") lines = ["vwxyz\n", "67890\n"] regexes = ["v[^a-u]*z\n", "6[^ ]+0\n"] assert not test.match_stdout(lines, regexes) assert test.match_stdout(lines, lines) assert test.match_stderr("abcde\n", "a.*e\n") assert test.match_stderr("12345\nabcde\n", "1\\d+5\na.*e\n") lines = ["vwxyz\n", "67890\n"] regexes = ["v[^a-u]*z\n", "6[^ ]+0\n"] assert test.match_stderr(lines, regexes) def test_match_stdout_custom_function(self): """Test match_stdout() using a custom function""" def match_length(lines, matches): return len(lines) == len(matches) test = TestCmd.TestCmd(match_stdout=match_length) assert not test.match_stdout("123\n", "1\n") assert test.match_stdout("123\n", "111\n") assert not test.match_stdout("123\n123\n", "1\n1\n") assert test.match_stdout("123\n123\n", "111\n111\n") lines = ["123\n", "123\n"] regexes = ["1\n", "1\n"] assert test.match_stdout(lines, regexes) # equal numbers of lines def test_match_stdout_TestCmd_function(self): """Test match_stdout() using a TestCmd function""" test = TestCmd.TestCmd(match_stdout = TestCmd.match_exact) assert not test.match_stdout("abcde\n", "a.*e\n") assert test.match_stdout("abcde\n", "abcde\n") assert not test.match_stdout("12345\nabcde\n", "1\d+5\na.*e\n") assert test.match_stdout("12345\nabcde\n", "12345\nabcde\n") lines = ["vwxyz\n", "67890\n"] regexes = ["v[^a-u]*z\n", "6[^ ]+0\n"] assert not test.match_stdout(lines, regexes) assert test.match_stdout(lines, lines) def test_match_stdout_static_method(self): """Test match_stdout() using a static method""" test = TestCmd.TestCmd(match_stdout=TestCmd.TestCmd.match_exact) assert not test.match_stdout("abcde\n", "a.*e\n") assert test.match_stdout("abcde\n", "abcde\n") assert not test.match_stdout("12345\nabcde\n", "1\d+5\na.*e\n") assert test.match_stdout("12345\nabcde\n", "12345\nabcde\n") lines = ["vwxyz\n", "67890\n"] regexes = ["v[^a-u]*z\n", "6[^ ]+0\n"] assert not test.match_stdout(lines, regexes) assert test.match_stdout(lines, lines) def test_match_stdout_string(self): """Test match_stdout() using a string to fetch the match method""" test = TestCmd.TestCmd(match_stdout='match_exact') assert not test.match_stdout("abcde\n", "a.*e\n") assert test.match_stdout("abcde\n", "abcde\n") assert not test.match_stdout("12345\nabcde\n", "1\d+5\na.*e\n") assert test.match_stdout("12345\nabcde\n", "12345\nabcde\n") lines = ["vwxyz\n", "67890\n"] regexes = ["v[^a-u]*z\n", "6[^ ]+0\n"] assert not test.match_stdout(lines, regexes) assert test.match_stdout(lines, lines) class no_result_TestCase(TestCmdTestCase): def test_no_result(self): """Test no_result()""" run_env = TestCmd.TestCmd(workdir = '') run_env.write('run', """import sys sys.stdout.write("run: STDOUT\\n") sys.stderr.write("run: STDERR\\n") """) os.chdir(run_env.workdir) # Everything before this prepared our "source directory." # Now do the real test. self.popen_python("""import sys sys.path = ['%s'] + sys.path import TestCmd TestCmd.no_result(condition = 1) """ % self.orig_cwd, status = 2, stderr = "NO RESULT for test at line 4 of \n") self.popen_python("""import sys sys.path = ['%s'] + sys.path import TestCmd test = TestCmd.TestCmd(program = 'run', interpreter = 'python', workdir = '') test.run() test.no_result(condition = (test.status == 0)) """ % self.orig_cwd, status = 2, stderr = "NO RESULT for test of %s\n\tat line 6 of \n" % run_env.workpath('run')) self.popen_python("""import sys sys.path = ['%s'] + sys.path import TestCmd test = TestCmd.TestCmd(program = 'run', interpreter = 'python', description = 'xyzzy', workdir = '') test.run() test.no_result(condition = (test.status == 0)) """ % self.orig_cwd, status = 2, stderr = "NO RESULT for test of %s [xyzzy]\n\tat line 6 of \n" % run_env.workpath('run')) self.popen_python("""import sys sys.path = ['%s'] + sys.path import TestCmd test = TestCmd.TestCmd(program = 'run', interpreter = 'python', workdir = '') test.run() def xxx(): sys.stderr.write("printed on no result\\n") test.no_result(condition = (test.status == 0), function = xxx) """ % self.orig_cwd, status = 2, stderr = "printed on no result\nNO RESULT for test of %s\n\tat line 8 of \n" % run_env.workpath('run')) self.popen_python("""import sys sys.path = ['%s'] + sys.path import TestCmd def test1(self): self.run() self.no_result(condition = (self.status == 0)) def test2(self): test1(self) test2(TestCmd.TestCmd(program = 'run', interpreter = 'python', workdir = '')) """ % self.orig_cwd, status = 2, stderr = "NO RESULT for test of %s\n\tat line 6 of (test1)\n\tfrom line 8 of (test2)\n\tfrom line 9 of \n" % run_env.workpath('run')) self.popen_python("""import sys sys.path = ['%s'] + sys.path import TestCmd def test1(self): self.run() self.no_result(condition = (self.status == 0), skip = 1) def test2(self): test1(self) test2(TestCmd.TestCmd(program = 'run', interpreter = 'python', workdir = '')) """ % self.orig_cwd, status = 2, stderr = "NO RESULT for test of %s\n\tat line 8 of (test2)\n\tfrom line 9 of \n" % run_env.workpath('run')) class pass_test_TestCase(TestCmdTestCase): def test_pass_test(self): """Test pass_test()""" run_env = TestCmd.TestCmd(workdir = '') run_env.write('run', """import sys sys.stdout.write("run: STDOUT\\n") sys.stderr.write("run: STDERR\\n") """) os.chdir(run_env.workdir) # Everything before this prepared our "source directory." # Now do the real test. self.popen_python("""import sys sys.path = ['%s'] + sys.path import TestCmd TestCmd.pass_test(condition = 1) """ % self.orig_cwd, stderr = "PASSED\n") self.popen_python("""import sys sys.path = ['%s'] + sys.path import TestCmd test = TestCmd.TestCmd(program = 'run', interpreter = 'python', workdir = '') test.run() test.pass_test(condition = (test.status == 0)) """ % self.orig_cwd, stderr = "PASSED\n") self.popen_python("""import sys sys.path = ['%s'] + sys.path import TestCmd test = TestCmd.TestCmd(program = 'run', interpreter = 'python', workdir = '') test.run() def brag(): sys.stderr.write("printed on success\\n") test.pass_test(condition = (test.status == 0), function = brag) """ % self.orig_cwd, stderr = "printed on success\nPASSED\n") # TODO(sgk): SHOULD ALSO TEST FAILURE CONDITIONS class preserve_TestCase(TestCmdTestCase): def test_preserve(self): """Test preserve()""" def cleanup_test(test, cond=None, stdout=""): io = StringIO() save = sys.stdout sys.stdout = io try: if cond: test.cleanup(cond) else: test.cleanup() o = io.getvalue() assert o == stdout, "o = `%s', stdout = `%s'" % (o, stdout) finally: sys.stdout = save test = TestCmd.TestCmd(workdir = '') wdir = test.workdir try: test.write('file1', "Test file #1\n") #test.cleanup() cleanup_test(test, ) assert not os.path.exists(wdir) finally: if os.path.exists(wdir): shutil.rmtree(wdir, ignore_errors = 1) test._dirlist.remove(wdir) test = TestCmd.TestCmd(workdir = '') wdir = test.workdir try: test.write('file2', "Test file #2\n") test.preserve('pass_test') cleanup_test(test, 'pass_test', "Preserved directory %s\n" % wdir) assert os.path.isdir(wdir) cleanup_test(test, 'fail_test') assert not os.path.exists(wdir) finally: if os.path.exists(wdir): shutil.rmtree(wdir, ignore_errors = 1) test._dirlist.remove(wdir) test = TestCmd.TestCmd(workdir = '') wdir = test.workdir try: test.write('file3', "Test file #3\n") test.preserve('fail_test') cleanup_test(test, 'fail_test', "Preserved directory %s\n" % wdir) assert os.path.isdir(wdir) cleanup_test(test, 'pass_test') assert not os.path.exists(wdir) finally: if os.path.exists(wdir): shutil.rmtree(wdir, ignore_errors = 1) test._dirlist.remove(wdir) test = TestCmd.TestCmd(workdir = '') wdir = test.workdir try: test.write('file4', "Test file #4\n") test.preserve('fail_test', 'no_result') cleanup_test(test, 'fail_test', "Preserved directory %s\n" % wdir) assert os.path.isdir(wdir) cleanup_test(test, 'no_result', "Preserved directory %s\n" % wdir) assert os.path.isdir(wdir) cleanup_test(test, 'pass_test') assert not os.path.exists(wdir) finally: if os.path.exists(wdir): shutil.rmtree(wdir, ignore_errors = 1) test._dirlist.remove(wdir) test = TestCmd.TestCmd(workdir = '') wdir = test.workdir try: test.preserve() cleanup_test(test, 'pass_test', "Preserved directory %s\n" % wdir) assert os.path.isdir(wdir) cleanup_test(test, 'fail_test', "Preserved directory %s\n" % wdir) assert os.path.isdir(wdir) cleanup_test(test, 'no_result', "Preserved directory %s\n" % wdir) assert os.path.isdir(wdir) finally: if os.path.exists(wdir): shutil.rmtree(wdir, ignore_errors = 1) test._dirlist.remove(wdir) class program_TestCase(TestCmdTestCase): def test_program(self): """Test program()""" test = TestCmd.TestCmd() assert test.program is None, 'initialized program?' test = TestCmd.TestCmd(program = 'test') assert test.program == os.path.join(os.getcwd(), 'test'), 'uninitialized program' test.program_set('foo') assert test.program == os.path.join(os.getcwd(), 'foo'), 'did not set program' class read_TestCase(TestCmdTestCase): def test_read(self): """Test read()""" test = TestCmd.TestCmd(workdir = '', subdir = 'foo') wdir_file1 = os.path.join(test.workdir, 'file1') wdir_file2 = os.path.join(test.workdir, 'file2') wdir_foo_file3 = os.path.join(test.workdir, 'foo', 'file3') wdir_file4 = os.path.join(test.workdir, 'file4') wdir_file5 = os.path.join(test.workdir, 'file5') open(wdir_file1, 'wb').write("") open(wdir_file2, 'wb').write("Test\nfile\n#2.\n") open(wdir_foo_file3, 'wb').write("Test\nfile\n#3.\n") open(wdir_file4, 'wb').write("Test\nfile\n#4.\n") open(wdir_file5, 'wb').write("Test\r\nfile\r\n#5.\r\n") try: contents = test.read('no_file') except IOError: # expect "No such file or directory" pass except: raise try: test.read(test.workpath('file_x'), mode = 'w') except ValueError: # expect "mode must begin with 'r' pass except: raise def _file_matches(file, contents, expected): assert contents == expected, \ "Expected contents of " + str(file) + "==========\n" + \ expected + \ "Actual contents of " + str(file) + "============\n" + \ contents _file_matches(wdir_file1, test.read('file1'), "") _file_matches(wdir_file2, test.read('file2'), "Test\nfile\n#2.\n") _file_matches(wdir_foo_file3, test.read(['foo', 'file3']), "Test\nfile\n#3.\n") _file_matches(wdir_foo_file3, test.read(UserList(['foo', 'file3'])), "Test\nfile\n#3.\n") _file_matches(wdir_file4, test.read('file4', mode = 'r'), "Test\nfile\n#4.\n") _file_matches(wdir_file5, test.read('file5', mode = 'rb'), "Test\r\nfile\r\n#5.\r\n") class rmdir_TestCase(TestCmdTestCase): def test_rmdir(self): """Test rmdir()""" test = TestCmd.TestCmd(workdir = '') try: test.rmdir(['no', 'such', 'dir']) except EnvironmentError: pass else: raise Exception("did not catch expected EnvironmentError") test.subdir(['sub'], ['sub', 'dir'], ['sub', 'dir', 'one']) s = test.workpath('sub') s_d = test.workpath('sub', 'dir') s_d_o = test.workpath('sub', 'dir', 'one') try: test.rmdir(['sub']) except EnvironmentError: pass else: raise Exception("did not catch expected EnvironmentError") assert os.path.isdir(s_d_o), "%s is gone?" % s_d_o try: test.rmdir(['sub']) except EnvironmentError: pass else: raise Exception("did not catch expected EnvironmentError") assert os.path.isdir(s_d_o), "%s is gone?" % s_d_o test.rmdir(['sub', 'dir', 'one']) assert not os.path.exists(s_d_o), "%s exists?" % s_d_o assert os.path.isdir(s_d), "%s is gone?" % s_d test.rmdir(['sub', 'dir']) assert not os.path.exists(s_d), "%s exists?" % s_d assert os.path.isdir(s), "%s is gone?" % s test.rmdir('sub') assert not os.path.exists(s), "%s exists?" % s class run_TestCase(TestCmdTestCase): def test_run(self): """Test run()""" t = self.setup_run_scripts() # Everything before this prepared our "source directory." # Now do the real test. try: test = TestCmd.TestCmd(program = t.script, interpreter = 'python', workdir = '', subdir = 'script_subdir') test.run() self.run_match(test.stdout(), t.script, "STDOUT", t.workdir, repr([])) self.run_match(test.stderr(), t.script, "STDERR", t.workdir, repr([])) test.run(arguments = 'arg1 arg2 arg3') self.run_match(test.stdout(), t.script, "STDOUT", t.workdir, repr(['arg1', 'arg2', 'arg3'])) self.run_match(test.stderr(), t.script, "STDERR", t.workdir, repr(['arg1', 'arg2', 'arg3'])) test.run(program = t.scriptx, arguments = 'foo') self.run_match(test.stdout(), t.scriptx, "STDOUT", t.workdir, repr(['foo'])) self.run_match(test.stderr(), t.scriptx, "STDERR", t.workdir, repr(['foo'])) test.run(chdir = os.curdir, arguments = 'x y z') self.run_match(test.stdout(), t.script, "STDOUT", test.workdir, repr(['x', 'y', 'z'])) self.run_match(test.stderr(), t.script, "STDERR", test.workdir, repr(['x', 'y', 'z'])) test.run(chdir = 'script_subdir') script_subdir = test.workpath('script_subdir') self.run_match(test.stdout(), t.script, "STDOUT", script_subdir, repr([])) self.run_match(test.stderr(), t.script, "STDERR", script_subdir, repr([])) test.run(program = t.script1, interpreter = ['python', '-x']) self.run_match(test.stdout(), t.script1, "STDOUT", t.workdir, repr([])) self.run_match(test.stderr(), t.script1, "STDERR", t.workdir, repr([])) try: test.run(chdir = 'no_subdir') except OSError: pass test.run(program = 'no_script', interpreter = 'python') assert test.status != None, test.status try: test.run(program = 'no_script', interpreter = 'no_interpreter') except OSError: # Python versions that use subprocess throw an OSError # exception when they try to execute something that # isn't there. pass else: # Python versions that use os.popen3() or the Popen3 # class run things through the shell, which just returns # a non-zero exit status. assert test.status != None, test.status testx = TestCmd.TestCmd(program = t.scriptx, workdir = '', subdir = 't.scriptx_subdir') testx.run() self.run_match(testx.stdout(), t.scriptx, "STDOUT", t.workdir, repr([])) self.run_match(testx.stderr(), t.scriptx, "STDERR", t.workdir, repr([])) testx.run(arguments = 'foo bar') self.run_match(testx.stdout(), t.scriptx, "STDOUT", t.workdir, repr(['foo', 'bar'])) self.run_match(testx.stderr(), t.scriptx, "STDERR", t.workdir, repr(['foo', 'bar'])) testx.run(program = t.script, interpreter = 'python', arguments = 'bar') self.run_match(testx.stdout(), t.script, "STDOUT", t.workdir, repr(['bar'])) self.run_match(testx.stderr(), t.script, "STDERR", t.workdir, repr(['bar'])) testx.run(chdir = os.curdir, arguments = 'baz') self.run_match(testx.stdout(), t.scriptx, "STDOUT", testx.workdir, repr(['baz'])) self.run_match(testx.stderr(), t.scriptx, "STDERR", testx.workdir, repr(['baz'])) testx.run(chdir = 't.scriptx_subdir') t.scriptx_subdir = testx.workpath('t.scriptx_subdir') self.run_match(testx.stdout(), t.scriptx, "STDOUT", t.scriptx_subdir, repr([])) self.run_match(testx.stderr(), t.scriptx, "STDERR", t.scriptx_subdir, repr([])) testx.run(program = t.script1, interpreter = ('python', '-x')) self.run_match(testx.stdout(), t.script1, "STDOUT", t.workdir, repr([])) self.run_match(testx.stderr(), t.script1, "STDERR", t.workdir, repr([])) s = os.path.join('.', t.scriptx) testx.run(program = [s]) self.run_match(testx.stdout(), t.scriptx, "STDOUT", t.workdir, repr([])) self.run_match(testx.stderr(), t.scriptx, "STDERR", t.workdir, repr([])) try: testx.run(chdir = 'no_subdir') except OSError: pass try: testx.run(program = 'no_program') except OSError: # Python versions that use subprocess throw an OSError # exception when they try to execute something that # isn't there. pass else: # Python versions that use os.popen3() or the Popen3 # class run things through the shell, which just returns # a non-zero exit status. assert test.status != None test1 = TestCmd.TestCmd(program = t.script1, interpreter = ['python', '-x'], workdir = '') test1.run() self.run_match(test1.stdout(), t.script1, "STDOUT", t.workdir, repr([])) self.run_match(test1.stderr(), t.script1, "STDERR", t.workdir, repr([])) finally: os.chdir(t.orig_cwd) def test_run_subclass(self): """Test run() through a subclass with different signatures""" t = self.setup_run_scripts() # Everything before this prepared our "source directory." # Now do the real test. class MyTestCmdSubclass(TestCmd.TestCmd): def start(self, additional_argument=None, **kw): return TestCmd.TestCmd.start(self, **kw) try: test = MyTestCmdSubclass(program = t.script, interpreter = 'python', workdir = '', subdir = 'script_subdir') test.run() self.run_match(test.stdout(), t.script, "STDOUT", t.workdir, repr([])) self.run_match(test.stderr(), t.script, "STDERR", t.workdir, repr([])) finally: os.chdir(t.orig_cwd) class run_verbose_TestCase(TestCmdTestCase): def test_run_verbose(self): """Test the run() method's verbose attribute""" # Prepare our "source directory." t = self.setup_run_scripts() save_stdout = sys.stderr save_stderr = sys.stderr try: # Test calling TestCmd() with an explicit verbose = 1. test = TestCmd.TestCmd(program = t.script, interpreter = 'python', workdir = '', verbose = 1) sys.stdout = StringIO() sys.stderr = StringIO() test.run(arguments = ['arg1 arg2']) o = sys.stdout.getvalue() assert o == '', o e = sys.stderr.getvalue() expect = 'python "%s" "arg1 arg2"\n' % t.script_path assert expect == e, (expect, e) testx = TestCmd.TestCmd(program = t.scriptx, workdir = '', verbose = 1) sys.stdout = StringIO() sys.stderr = StringIO() testx.run(arguments = ['arg1 arg2']) expect = '"%s" "arg1 arg2"\n' % t.scriptx_path o = sys.stdout.getvalue() assert o == '', o e = sys.stderr.getvalue() assert expect == e, (expect, e) # Test calling TestCmd() with an explicit verbose = 2. outerr_fmt = """\ ============ STATUS: 0 ============ BEGIN STDOUT (len=%s): %s============ END STDOUT ============ BEGIN STDERR (len=%s) %s============ END STDERR """ out_fmt = """\ ============ STATUS: 0 ============ BEGIN STDOUT (len=%s): %s============ END STDOUT """ err_fmt = """\ ============ STATUS: 0 ============ BEGIN STDERR (len=%s) %s============ END STDERR """ test = TestCmd.TestCmd(program = t.script, interpreter = 'python', workdir = '', verbose = 2) sys.stdout = StringIO() sys.stderr = StringIO() test.run(arguments = ['arg1 arg2']) line_fmt = "script: %s: %s: ['arg1 arg2']\n" stdout_line = line_fmt % ('STDOUT', t.sub_dir) stderr_line = line_fmt % ('STDERR', t.sub_dir) expect = outerr_fmt % (len(stdout_line), stdout_line, len(stderr_line), stderr_line) o = sys.stdout.getvalue() assert expect == o, (expect, o) expect = 'python "%s" "arg1 arg2"\n' % t.script_path e = sys.stderr.getvalue() assert e == expect, (e, expect) testx = TestCmd.TestCmd(program = t.scriptx, workdir = '', verbose = 2) sys.stdout = StringIO() sys.stderr = StringIO() testx.run(arguments = ['arg1 arg2']) line_fmt = "scriptx.bat: %s: %s: ['arg1 arg2']\n" stdout_line = line_fmt % ('STDOUT', t.sub_dir) stderr_line = line_fmt % ('STDERR', t.sub_dir) expect = outerr_fmt % (len(stdout_line), stdout_line, len(stderr_line), stderr_line) o = sys.stdout.getvalue() assert expect == o, (expect, o) expect = '"%s" "arg1 arg2"\n' % t.scriptx_path e = sys.stderr.getvalue() assert e == expect, (e, expect) # Test calling TestCmd() with an explicit verbose = 3. test = TestCmd.TestCmd(program = t.scriptout, interpreter = 'python', workdir = '', verbose = 2) sys.stdout = StringIO() sys.stderr = StringIO() test.run(arguments = ['arg1 arg2']) line_fmt = "scriptout: %s: %s: ['arg1 arg2']\n" stdout_line = line_fmt % ('STDOUT', t.sub_dir) expect = out_fmt % (len(stdout_line), stdout_line) o = sys.stdout.getvalue() assert expect == o, (expect, o) e = sys.stderr.getvalue() expect = 'python "%s" "arg1 arg2"\n' % (t.scriptout_path) assert e == expect, (e, expect) test = TestCmd.TestCmd(program = t.scriptout, interpreter = 'python', workdir = '', verbose = 3) sys.stdout = StringIO() sys.stderr = StringIO() test.run(arguments = ['arg1 arg2']) line_fmt = "scriptout: %s: %s: ['arg1 arg2']\n" stdout_line = line_fmt % ('STDOUT', t.sub_dir) expect = outerr_fmt % (len(stdout_line), stdout_line, '0', '') o = sys.stdout.getvalue() assert expect == o, (expect, o) e = sys.stderr.getvalue() expect = 'python "%s" "arg1 arg2"\n' % (t.scriptout_path) assert e == expect, (e, expect) # Test letting TestCmd() pick up verbose = 2 from the environment. os.environ['TESTCMD_VERBOSE'] = '2' test = TestCmd.TestCmd(program = t.script, interpreter = 'python', workdir = '') sys.stdout = StringIO() sys.stderr = StringIO() test.run(arguments = ['arg1 arg2']) line_fmt = "script: %s: %s: ['arg1 arg2']\n" stdout_line = line_fmt % ('STDOUT', t.sub_dir) stderr_line = line_fmt % ('STDERR', t.sub_dir) expect = outerr_fmt % (len(stdout_line), stdout_line, len(stderr_line), stderr_line) o = sys.stdout.getvalue() assert expect == o, (expect, o) expect = 'python "%s" "arg1 arg2"\n' % t.script_path e = sys.stderr.getvalue() assert e == expect, (e, expect) testx = TestCmd.TestCmd(program = t.scriptx, workdir = '') sys.stdout = StringIO() sys.stderr = StringIO() testx.run(arguments = ['arg1 arg2']) line_fmt = "scriptx.bat: %s: %s: ['arg1 arg2']\n" stdout_line = line_fmt % ('STDOUT', t.sub_dir) stderr_line = line_fmt % ('STDERR', t.sub_dir) expect = outerr_fmt % (len(stdout_line), stdout_line, len(stderr_line), stderr_line) o = sys.stdout.getvalue() assert expect == o, (expect, o) expect = '"%s" "arg1 arg2"\n' % t.scriptx_path e = sys.stderr.getvalue() assert e == expect, (e, expect) # Test letting TestCmd() pick up verbose = 1 from the environment. os.environ['TESTCMD_VERBOSE'] = '1' test = TestCmd.TestCmd(program = t.script, interpreter = 'python', workdir = '', verbose = 1) sys.stdout = StringIO() sys.stderr = StringIO() test.run(arguments = ['arg1 arg2']) o = sys.stdout.getvalue() assert o == '', o e = sys.stderr.getvalue() expect = 'python "%s" "arg1 arg2"\n' % t.script_path assert expect == e, (expect, e) testx = TestCmd.TestCmd(program = t.scriptx, workdir = '', verbose = 1) sys.stdout = StringIO() sys.stderr = StringIO() testx.run(arguments = ['arg1 arg2']) expect = '"%s" "arg1 arg2"\n' % t.scriptx_path o = sys.stdout.getvalue() assert o == '', o e = sys.stderr.getvalue() assert expect == e, (expect, e) finally: sys.stdout = save_stdout sys.stderr = save_stderr os.chdir(t.orig_cwd) os.environ['TESTCMD_VERBOSE'] = '' class set_diff_function_TestCase(TestCmdTestCase): def test_set_diff_function(self): """Test set_diff_function()""" self.popen_python(r"""import sys sys.path = ['%s'] + sys.path import TestCmd test = TestCmd.TestCmd() test.diff("a\n", "a\n") test.set_diff_function('diff_re') test.diff(".\n", "a\n") sys.exit(0) """ % self.orig_cwd) def test_set_diff_function_stdout(self): """Test set_diff_function(): stdout""" self.popen_python("""from __future__ import print_function import sys sys.path = ['%s'] + sys.path import TestCmd test = TestCmd.TestCmd() print("diff:") test.diff("a\\n", "a\\n") print("diff_stdout:") test.diff_stdout("a\\n", "a\\n") test.set_diff_function(stdout='diff_re') print("diff:") test.diff(".\\n", "a\\n") print("diff_stdout:") test.diff_stdout(".\\n", "a\\n") sys.exit(0) """ % self.orig_cwd, stdout="""\ diff: diff_stdout: diff: 1c1 < . --- > a diff_stdout: """) def test_set_diff_function_stderr(self): """Test set_diff_function(): stderr """ self.popen_python("""from __future__ import print_function import sys sys.path = ['%s'] + sys.path import TestCmd test = TestCmd.TestCmd() print("diff:") test.diff("a\\n", "a\\n") print("diff_stderr:") test.diff_stderr("a\\n", "a\\n") test.set_diff_function(stderr='diff_re') print("diff:") test.diff(".\\n", "a\\n") print("diff_stderr:") test.diff_stderr(".\\n", "a\\n") sys.exit(0) """ % self.orig_cwd, stdout="""\ diff: diff_stderr: diff: 1c1 < . --- > a diff_stderr: """) class set_match_function_TestCase(TestCmdTestCase): def test_set_match_function(self): """Test set_match_function()""" test = TestCmd.TestCmd() assert test.match("abcde\n", "a.*e\n") assert test.match("abcde\n", "abcde\n") test.set_match_function('match_exact') assert not test.match("abcde\n", "a.*e\n") assert test.match("abcde\n", "abcde\n") def test_set_match_function_stdout(self): """Test set_match_function(): stdout """ test = TestCmd.TestCmd() assert test.match("abcde\n", "a.*e\n") assert test.match("abcde\n", "abcde\n") assert test.match_stdout("abcde\n", "a.*e\n") assert test.match_stdout("abcde\n", "abcde\n") test.set_match_function(stdout='match_exact') assert test.match("abcde\n", "a.*e\n") assert test.match("abcde\n", "abcde\n") assert not test.match_stdout("abcde\n", "a.*e\n") assert test.match_stdout("abcde\n", "abcde\n") def test_set_match_function_stderr(self): """Test set_match_function(): stderr """ test = TestCmd.TestCmd() assert test.match("abcde\n", "a.*e\n") assert test.match("abcde\n", "abcde\n") assert test.match_stderr("abcde\n", "a.*e\n") assert test.match_stderr("abcde\n", "abcde\n") test.set_match_function(stderr='match_exact') assert test.match("abcde\n", "a.*e\n") assert test.match("abcde\n", "abcde\n") assert not test.match_stderr("abcde\n", "a.*e\n") assert test.match_stderr("abcde\n", "abcde\n") class sleep_TestCase(TestCmdTestCase): def test_sleep(self): """Test sleep()""" test = TestCmd.TestCmd() start = time.time() test.sleep() end = time.time() diff = end - start assert diff > 0.9, "only slept %f seconds (start %f, end %f), not default" % (diff, start, end) start = time.time() test.sleep(3) end = time.time() diff = end - start assert diff > 2.9, "only slept %f seconds (start %f, end %f), not 3" % (diff, start, end) class stderr_TestCase(TestCmdTestCase): def test_stderr(self): """Test stderr()""" run_env = TestCmd.TestCmd(workdir = '') run_env.write('run1', """import sys sys.stdout.write("run1 STDOUT %s\\n" % sys.argv[1:]) sys.stdout.write("run1 STDOUT second line\\n") sys.stderr.write("run1 STDERR %s\\n" % sys.argv[1:]) sys.stderr.write("run1 STDERR second line\\n") """) run_env.write('run2', """import sys sys.stdout.write("run2 STDOUT %s\\n" % sys.argv[1:]) sys.stdout.write("run2 STDOUT second line\\n") sys.stderr.write("run2 STDERR %s\\n" % sys.argv[1:]) sys.stderr.write("run2 STDERR second line\\n") """) os.chdir(run_env.workdir) # Everything before this prepared our "source directory." # Now do the real test. test = TestCmd.TestCmd(interpreter = 'python', workdir = '') try: output = test.stderr() except IndexError: pass else: raise IndexError("got unexpected output:\n" + output) test.program_set('run1') test.run(arguments = 'foo bar') test.program_set('run2') test.run(arguments = 'snafu') # XXX SHOULD TEST ABSOLUTE NUMBER AS WELL output = test.stderr() assert output == "run2 STDERR ['snafu']\nrun2 STDERR second line\n", output output = test.stderr(run = -1) assert output == "run1 STDERR ['foo', 'bar']\nrun1 STDERR second line\n", output class command_args_TestCase(TestCmdTestCase): def test_command_args(self): """Test command_args()""" run_env = TestCmd.TestCmd(workdir = '') os.chdir(run_env.workdir) # Everything before this prepared our "source directory." # Now do the real test. test = TestCmd.TestCmd(workdir = '') r = test.command_args('prog') expect = [run_env.workpath('prog')] assert r == expect, (expect, r) r = test.command_args(test.workpath('new_prog')) expect = [test.workpath('new_prog')] assert r == expect, (expect, r) r = test.command_args('prog', 'python') expect = ['python', run_env.workpath('prog')] assert r == expect, (expect, r) r = test.command_args('prog', 'python', 'arg1 arg2') expect = ['python', run_env.workpath('prog'), 'arg1', 'arg2'] assert r == expect, (expect, r) test.program_set('default_prog') default_prog = run_env.workpath('default_prog') r = test.command_args() expect = [default_prog] assert r == expect, (expect, r) r = test.command_args(interpreter='PYTHON') expect = ['PYTHON', default_prog] assert r == expect, (expect, r) r = test.command_args(interpreter='PYTHON', arguments='arg3 arg4') expect = ['PYTHON', default_prog, 'arg3', 'arg4'] assert r == expect, (expect, r) test.interpreter_set('default_python') r = test.command_args() expect = ['default_python', default_prog] assert r == expect, (expect, r) r = test.command_args(arguments='arg5 arg6') expect = ['default_python', default_prog, 'arg5', 'arg6'] assert r == expect, (expect, r) r = test.command_args('new_prog_1') expect = [run_env.workpath('new_prog_1')] assert r == expect, (expect, r) r = test.command_args(program='new_prog_2') expect = [run_env.workpath('new_prog_2')] assert r == expect, (expect, r) class start_TestCase(TestCmdTestCase): def setup_run_scripts(self): t = TestCmdTestCase.setup_run_scripts(self) t.recv_script = 'script_recv' t.recv_script_path = t.run_env.workpath(t.sub_dir, t.recv_script) t.recv_out_path = t.run_env.workpath('script_recv.out') text = """\ import os import sys class Unbuffered: def __init__(self, file): self.file = file def write(self, arg): self.file.write(arg) self.file.flush() def __getattr__(self, attr): return getattr(self.file, attr) sys.stdout = Unbuffered(sys.stdout) sys.stderr = Unbuffered(sys.stderr) sys.stdout.write('script_recv: STDOUT\\n') sys.stderr.write('script_recv: STDERR\\n') logfp = open(r'%s', 'wb') while 1: line = sys.stdin.readline() if not line: break logfp.write('script_recv: ' + line) sys.stdout.write('script_recv: STDOUT: ' + line) sys.stderr.write('script_recv: STDERR: ' + line) logfp.close() """ % t.recv_out_path t.run_env.write(t.recv_script_path, text) os.chmod(t.recv_script_path, 0o644) # XXX UNIX-specific return t def test_start(self): """Test start()""" t = self.setup_run_scripts() # Everything before this prepared our "source directory." # Now do the real test. try: test = TestCmd.TestCmd(program = t.script, interpreter = 'python', workdir = '', subdir = 'script_subdir') p = test.start() self.run_match(p.stdout.read(), t.script, "STDOUT", t.workdir, repr([])) self.run_match(p.stderr.read(), t.script, "STDERR", t.workdir, repr([])) p.wait() p = test.start(arguments='arg1 arg2 arg3') self.run_match(p.stdout.read(), t.script, "STDOUT", t.workdir, repr(['arg1', 'arg2', 'arg3'])) self.run_match(p.stderr.read(), t.script, "STDERR", t.workdir, repr(['arg1', 'arg2', 'arg3'])) p.wait() p = test.start(program=t.scriptx, arguments='foo') self.run_match(p.stdout.read(), t.scriptx, "STDOUT", t.workdir, repr(['foo'])) self.run_match(p.stderr.read(), t.scriptx, "STDERR", t.workdir, repr(['foo'])) p.wait() p = test.start(program=t.script1, interpreter=['python', '-x']) self.run_match(p.stdout.read(), t.script1, "STDOUT", t.workdir, repr([])) self.run_match(p.stderr.read(), t.script1, "STDERR", t.workdir, repr([])) p.wait() p = test.start(program='no_script', interpreter='python') status = p.wait() assert status != None, status try: p = test.start(program='no_script', interpreter='no_interpreter') except OSError: # Python versions that use subprocess throw an OSError # exception when they try to execute something that # isn't there. pass else: status = p.wait() # Python versions that use os.popen3() or the Popen3 # class run things through the shell, which just returns # a non-zero exit status. assert status != None, status testx = TestCmd.TestCmd(program = t.scriptx, workdir = '', subdir = 't.scriptx_subdir') p = testx.start() self.run_match(p.stdout.read(), t.scriptx, "STDOUT", t.workdir, repr([])) self.run_match(p.stderr.read(), t.scriptx, "STDERR", t.workdir, repr([])) p.wait() p = testx.start(arguments='foo bar') self.run_match(p.stdout.read(), t.scriptx, "STDOUT", t.workdir, repr(['foo', 'bar'])) self.run_match(p.stderr.read(), t.scriptx, "STDERR", t.workdir, repr(['foo', 'bar'])) p.wait() p = testx.start(program=t.script, interpreter='python', arguments='bar') self.run_match(p.stdout.read(), t.script, "STDOUT", t.workdir, repr(['bar'])) self.run_match(p.stderr.read(), t.script, "STDERR", t.workdir, repr(['bar'])) p.wait() p = testx.start(program=t.script1, interpreter=('python', '-x')) self.run_match(p.stdout.read(), t.script1, "STDOUT", t.workdir, repr([])) self.run_match(p.stderr.read(), t.script1, "STDERR", t.workdir, repr([])) p.wait() s = os.path.join('.', t.scriptx) p = testx.start(program=[s]) self.run_match(p.stdout.read(), t.scriptx, "STDOUT", t.workdir, repr([])) self.run_match(p.stderr.read(), t.scriptx, "STDERR", t.workdir, repr([])) p.wait() try: testx.start(program='no_program') except OSError: # Python versions that use subprocess throw an OSError # exception when they try to execute something that # isn't there. pass else: # Python versions that use os.popen3() or the Popen3 # class run things through the shell, which just dies # trying to execute the non-existent program before # we can wait() for it. try: p = p.wait() except OSError: pass test1 = TestCmd.TestCmd(program = t.script1, interpreter = ['python', '-x'], workdir = '') p = test1.start() self.run_match(p.stdout.read(), t.script1, "STDOUT", t.workdir, repr([])) self.run_match(p.stderr.read(), t.script1, "STDERR", t.workdir, repr([])) p.wait() finally: os.chdir(t.orig_cwd) def test_finish(self): """Test finish()""" t = self.setup_run_scripts() # Everything before this prepared our "source directory." # Now do the real test. try: test = TestCmd.TestCmd(program = t.recv_script, interpreter = 'python', workdir = '', subdir = 'script_subdir') test.start(stdin=1) test.finish() expect_stdout = """\ script_recv: STDOUT """ expect_stderr = """\ script_recv: STDERR """ stdout = test.stdout() assert stdout == expect_stdout, stdout stderr = test.stderr() assert stderr == expect_stderr, stderr p = test.start(stdin=1) p.send('input\n') test.finish(p) expect_stdout = """\ script_recv: STDOUT script_recv: STDOUT: input """ expect_stderr = """\ script_recv: STDERR script_recv: STDERR: input """ stdout = test.stdout() assert stdout == expect_stdout, stdout stderr = test.stderr() assert stderr == expect_stderr, stderr p = test.start(combine=1, stdin=1) p.send('input\n') test.finish(p) expect_stdout = """\ script_recv: STDOUT script_recv: STDERR script_recv: STDOUT: input script_recv: STDERR: input """ expect_stderr = "" stdout = test.stdout() assert stdout == expect_stdout, stdout stderr = test.stderr() assert stderr == expect_stderr, stderr finally: os.chdir(t.orig_cwd) def test_recv(self): """Test the recv() method of objects returned by start()""" t = self.setup_run_scripts() # Everything before this prepared our "source directory." # Now do the real test. try: test = TestCmd.TestCmd(program = t.script, interpreter = 'python', workdir = '', subdir = 'script_subdir') p = test.start() stdout = p.recv() while stdout == '': import time time.sleep(1) stdout = p.recv() self.run_match(stdout, t.script, "STDOUT", t.workdir, repr([])) p.wait() finally: os.chdir(t.orig_cwd) def test_recv_err(self): """Test the recv_err() method of objects returned by start()""" t = self.setup_run_scripts() # Everything before this prepared our "source directory." # Now do the real test. try: test = TestCmd.TestCmd(program = t.script, interpreter = 'python', workdir = '', subdir = 'script_subdir') p = test.start() stderr = p.recv_err() while stderr == '': import time time.sleep(1) stderr = p.recv_err() self.run_match(stderr, t.script, "STDERR", t.workdir, repr([])) p.wait() finally: os.chdir(t.orig_cwd) def test_send(self): """Test the send() method of objects returned by start()""" t = self.setup_run_scripts() # Everything before this prepared our "source directory." # Now do the real test. try: test = TestCmd.TestCmd(program = t.recv_script, interpreter = 'python', workdir = '', subdir = 'script_subdir') p = test.start(stdin=1) input = 'stdin.write() input to the receive script\n' p.stdin.write(input) p.stdin.close() p.wait() result = open(t.recv_out_path, 'rb').read() expect = 'script_recv: ' + input assert result == expect, repr(result) p = test.start(stdin=1) input = 'send() input to the receive script\n' p.send(input) p.stdin.close() p.wait() result = open(t.recv_out_path, 'rb').read() expect = 'script_recv: ' + input assert result == expect, repr(result) finally: os.chdir(t.orig_cwd) # TODO(sgk): figure out how to eliminate the race conditions here. def __FLAKY__test_send_recv(self): """Test the send_recv() method of objects returned by start()""" t = self.setup_run_scripts() # Everything before this prepared our "source directory." # Now do the real test. try: test = TestCmd.TestCmd(program = t.recv_script, interpreter = 'python', workdir = '', subdir = 'script_subdir') def do_send_recv(p, input): send, stdout, stderr = p.send_recv(input) stdout = self.translate_newlines(stdout) stderr = self.translate_newlines(stderr) return send, stdout, stderr p = test.start(stdin=1) input = 'input to the receive script\n' send, stdout, stderr = do_send_recv(p, input) # Buffering issues and a race condition prevent this from # being completely deterministic, so check for both null # output and the first write() on each stream. assert stdout in ("", "script_recv: STDOUT\n"), stdout assert stderr in ("", "script_recv: STDERR\n"), stderr send, stdout, stderr = do_send_recv(p, input) assert stdout in ("", "script_recv: STDOUT\n"), stdout assert stderr in ("", "script_recv: STDERR\n"), stderr p.stdin.close() stdout = self.translate_newlines(p.recv()) stderr = self.translate_newlines(p.recv_err()) assert stdout in ("", "script_recv: STDOUT\n"), stdout assert stderr in ("", "script_recv: STDERR\n"), stderr p.wait() stdout = self.translate_newlines(p.recv()) stderr = self.translate_newlines(p.recv_err()) expect_stdout = """\ script_recv: STDOUT script_recv: STDOUT: input to the receive script script_recv: STDOUT: input to the receive script """ expect_stderr = """\ script_recv: STDERR script_recv: STDERR: input to the receive script script_recv: STDERR: input to the receive script """ assert stdout == expect_stdout, stdout assert stderr == expect_stderr, stderr result = open(t.recv_out_path, 'rb').read() expect = ('script_recv: ' + input) * 2 assert result == expect, (result, stdout, stderr) finally: os.chdir(t.orig_cwd) class stdin_TestCase(TestCmdTestCase): def test_stdin(self): """Test stdin()""" run_env = TestCmd.TestCmd(workdir = '') run_env.write('run', """from __future__ import print_function import fileinput for line in fileinput.input(): print('Y'.join(line[:-1].split('X'))) """) run_env.write('input', "X on X this X line X\n") os.chdir(run_env.workdir) # Everything before this prepared our "source directory." # Now do the real test. test = TestCmd.TestCmd(program = 'run', interpreter = 'python', workdir = '') test.run(arguments = 'input') assert test.stdout() == "Y on Y this Y line Y\n" test.run(stdin = "X is X here X tooX\n") assert test.stdout() == "Y is Y here Y tooY\n" test.run(stdin = """X here X X there X """) assert test.stdout() == "Y here Y\nY there Y\n" test.run(stdin = ["X line X\n", "X another X\n"]) assert test.stdout() == "Y line Y\nY another Y\n" class stdout_TestCase(TestCmdTestCase): def test_stdout(self): """Test stdout()""" run_env = TestCmd.TestCmd(workdir = '') run_env.write('run1', """import sys sys.stdout.write("run1 STDOUT %s\\n" % sys.argv[1:]) sys.stdout.write("run1 STDOUT second line\\n") sys.stderr.write("run1 STDERR %s\\n" % sys.argv[1:]) sys.stderr.write("run1 STDERR second line\\n") """) run_env.write('run2', """import sys sys.stdout.write("run2 STDOUT %s\\n" % sys.argv[1:]) sys.stdout.write("run2 STDOUT second line\\n") sys.stderr.write("run2 STDERR %s\\n" % sys.argv[1:]) sys.stderr.write("run2 STDERR second line\\n") """) os.chdir(run_env.workdir) # Everything before this prepared our "source directory." # Now do the real test. test = TestCmd.TestCmd(interpreter = 'python', workdir = '') try: output = test.stdout() except IndexError: pass else: raise IndexError("got unexpected output:\n\t`%s'\n" % output) test.program_set('run1') test.run(arguments = 'foo bar') test.program_set('run2') test.run(arguments = 'snafu') # XXX SHOULD TEST ABSOLUTE NUMBER AS WELL output = test.stdout() assert output == "run2 STDOUT ['snafu']\nrun2 STDOUT second line\n", output output = test.stdout(run = -1) assert output == "run1 STDOUT ['foo', 'bar']\nrun1 STDOUT second line\n", output class subdir_TestCase(TestCmdTestCase): def test_subdir(self): """Test subdir()""" test = TestCmd.TestCmd(workdir = '', subdir = ['no', 'such', 'subdir']) assert not os.path.exists(test.workpath('no')) test = TestCmd.TestCmd(workdir = '', subdir = 'foo') assert test.subdir('bar') == 1 assert test.subdir(['foo', 'succeed']) == 1 if os.name != "nt": os.chmod(test.workpath('foo'), 0o500) assert test.subdir(['foo', 'fail']) == 0 assert test.subdir(['sub', 'dir', 'ectory'], 'sub') == 1 assert test.subdir('one', UserList(['one', 'two']), ['one', 'two', 'three']) == 3 assert os.path.isdir(test.workpath('foo')) assert os.path.isdir(test.workpath('bar')) assert os.path.isdir(test.workpath('foo', 'succeed')) if os.name != "nt": assert not os.path.exists(test.workpath('foo', 'fail')) assert os.path.isdir(test.workpath('sub')) assert not os.path.exists(test.workpath('sub', 'dir')) assert not os.path.exists(test.workpath('sub', 'dir', 'ectory')) assert os.path.isdir(test.workpath('one', 'two', 'three')) class symlink_TestCase(TestCmdTestCase): def test_symlink(self): """Test symlink()""" try: os.symlink except AttributeError: return test = TestCmd.TestCmd(workdir = '', subdir = 'foo') wdir_file1 = os.path.join(test.workdir, 'file1') wdir_target1 = os.path.join(test.workdir, 'target1') wdir_foo_file2 = os.path.join(test.workdir, 'foo', 'file2') wdir_target2 = os.path.join(test.workdir, 'target2') wdir_foo_target2 = os.path.join(test.workdir, 'foo', 'target2') test.symlink('target1', 'file1') assert os.path.islink(wdir_file1) assert not os.path.exists(wdir_file1) open(wdir_target1, 'w').write("") assert os.path.exists(wdir_file1) test.symlink('target2', ['foo', 'file2']) assert os.path.islink(wdir_foo_file2) assert not os.path.exists(wdir_foo_file2) open(wdir_target2, 'w').write("") assert not os.path.exists(wdir_foo_file2) open(wdir_foo_target2, 'w').write("") assert os.path.exists(wdir_foo_file2) class tempdir_TestCase(TestCmdTestCase): def setUp(self): TestCmdTestCase.setUp(self) self._tempdir = tempfile.mktemp() os.mkdir(self._tempdir) os.chdir(self._tempdir) def tearDown(self): TestCmdTestCase.tearDown(self) os.rmdir(self._tempdir) def test_tempdir(self): """Test tempdir()""" test = TestCmd.TestCmd() tdir1 = test.tempdir() assert os.path.isdir(tdir1) test.workdir_set(None) test.cleanup() assert not os.path.exists(tdir1) test = TestCmd.TestCmd() tdir2 = test.tempdir('temp') assert os.path.isdir(tdir2) tdir3 = test.tempdir() assert os.path.isdir(tdir3) test.workdir_set(None) test.cleanup() assert not os.path.exists(tdir2) assert not os.path.exists(tdir3) timeout_script = """\ import sys import time seconds = int(sys.argv[1]) sys.stdout.write('sleeping %s\\n' % seconds) sys.stdout.flush() time.sleep(seconds) sys.stdout.write('slept %s\\n' % seconds) sys.stdout.flush() sys.exit(0) """ class timeout_TestCase(TestCmdTestCase): def test_initialization(self): """Test initialization timeout""" test = TestCmd.TestCmd(workdir='', timeout=2) test.write('sleep.py', timeout_script) test.run([sys.executable, test.workpath('sleep.py'), '4']) assert test.stderr() == '', test.stderr() assert test.stdout() == 'sleeping 4\n', test.stdout() test.run([sys.executable, test.workpath('sleep.py'), '4']) assert test.stderr() == '', test.stderr() assert test.stdout() == 'sleeping 4\n', test.stdout() def test_cancellation(self): """Test timer cancellation after firing""" test = TestCmd.TestCmd(workdir='', timeout=4) test.write('sleep.py', timeout_script) test.run([sys.executable, test.workpath('sleep.py'), '6']) assert test.stderr() == '', test.stderr() assert test.stdout() == 'sleeping 6\n', test.stdout() test.run([sys.executable, test.workpath('sleep.py'), '2']) assert test.stderr() == '', test.stderr() assert test.stdout() == 'sleeping 2\nslept 2\n', test.stdout() test.run([sys.executable, test.workpath('sleep.py'), '6']) assert test.stderr() == '', test.stderr() assert test.stdout() == 'sleeping 6\n', test.stdout() def test_run(self): """Test run() timeout""" test = TestCmd.TestCmd(workdir='', timeout=8) test.write('sleep.py', timeout_script) test.run([sys.executable, test.workpath('sleep.py'), '2'], timeout=4) assert test.stderr() == '', test.stderr() assert test.stdout() == 'sleeping 2\nslept 2\n', test.stdout() test.run([sys.executable, test.workpath('sleep.py'), '6'], timeout=4) assert test.stderr() == '', test.stderr() assert test.stdout() == 'sleeping 6\n', test.stdout() def test_set_timeout(self): """Test set_timeout()""" test = TestCmd.TestCmd(workdir='', timeout=2) test.write('sleep.py', timeout_script) test.run([sys.executable, test.workpath('sleep.py'), '4']) assert test.stderr() == '', test.stderr() assert test.stdout() == 'sleeping 4\n', test.stdout() test.set_timeout(None) test.run([sys.executable, test.workpath('sleep.py'), '4']) assert test.stderr() == '', test.stderr() assert test.stdout() == 'sleeping 4\nslept 4\n', test.stdout() test.set_timeout(6) test.run([sys.executable, test.workpath('sleep.py'), '4']) assert test.stderr() == '', test.stderr() assert test.stdout() == 'sleeping 4\nslept 4\n', test.stdout() test.run([sys.executable, test.workpath('sleep.py'), '8']) assert test.stderr() == '', test.stderr() assert test.stdout() == 'sleeping 8\n', test.stdout() class unlink_TestCase(TestCmdTestCase): def test_unlink(self): """Test unlink()""" test = TestCmd.TestCmd(workdir = '', subdir = 'foo') wdir_file1 = os.path.join(test.workdir, 'file1') wdir_file2 = os.path.join(test.workdir, 'file2') wdir_foo_file3a = os.path.join(test.workdir, 'foo', 'file3a') wdir_foo_file3b = os.path.join(test.workdir, 'foo', 'file3b') wdir_foo_file4 = os.path.join(test.workdir, 'foo', 'file4') wdir_file5 = os.path.join(test.workdir, 'file5') open(wdir_file1, 'w').write("") open(wdir_file2, 'w').write("") open(wdir_foo_file3a, 'w').write("") open(wdir_foo_file3b, 'w').write("") open(wdir_foo_file4, 'w').write("") open(wdir_file5, 'w').write("") try: contents = test.unlink('no_file') except OSError: # expect "No such file or directory" pass except: raise test.unlink("file1") assert not os.path.exists(wdir_file1) test.unlink(wdir_file2) assert not os.path.exists(wdir_file2) test.unlink(['foo', 'file3a']) assert not os.path.exists(wdir_foo_file3a) test.unlink(UserList(['foo', 'file3b'])) assert not os.path.exists(wdir_foo_file3b) test.unlink([test.workdir, 'foo', 'file4']) assert not os.path.exists(wdir_foo_file4) # Make it so we can't unlink file5. # For UNIX, remove write permission from the dir and the file. # For Windows, open the file. os.chmod(test.workdir, 0o500) os.chmod(wdir_file5, 0o400) f = open(wdir_file5, 'r') try: try: test.unlink('file5') except OSError: # expect "Permission denied" pass except: raise finally: os.chmod(test.workdir, 0o700) os.chmod(wdir_file5, 0o600) f.close() class touch_TestCase(TestCmdTestCase): def test_touch(self): """Test touch()""" test = TestCmd.TestCmd(workdir = '', subdir = 'sub') wdir_file1 = os.path.join(test.workdir, 'file1') wdir_sub_file2 = os.path.join(test.workdir, 'sub', 'file2') open(wdir_file1, 'w').write("") open(wdir_sub_file2, 'w').write("") file1_old_time = os.path.getmtime(wdir_file1) file2_old_time = os.path.getmtime(wdir_sub_file2) test.sleep() test.touch(wdir_file1) file1_new_time = os.path.getmtime(wdir_file1) assert file1_new_time > file1_old_time test.touch('file1', file1_old_time) result = os.path.getmtime(wdir_file1) # Sub-second granularity of file systems may still vary. # On Windows, the two times may be off by a microsecond. assert int(result) == int(file1_old_time), (result, file1_old_time) test.touch(['sub', 'file2']) file2_new_time = os.path.getmtime(wdir_sub_file2) assert file2_new_time > file2_old_time class verbose_TestCase(TestCmdTestCase): def test_verbose(self): """Test verbose()""" test = TestCmd.TestCmd() assert test.verbose == 0, 'verbose already initialized?' test = TestCmd.TestCmd(verbose = 1) assert test.verbose == 1, 'did not initialize verbose' test.verbose = 2 assert test.verbose == 2, 'did not set verbose' class workdir_TestCase(TestCmdTestCase): def test_workdir(self): """Test workdir()""" run_env = TestCmd.TestCmd(workdir = '') os.chdir(run_env.workdir) # Everything before this prepared our "source directory." # Now do the real test. test = TestCmd.TestCmd() assert test.workdir is None test = TestCmd.TestCmd(workdir = None) assert test.workdir is None test = TestCmd.TestCmd(workdir = '') assert test.workdir != None assert os.path.isdir(test.workdir) test = TestCmd.TestCmd(workdir = 'dir') assert test.workdir != None assert os.path.isdir(test.workdir) no_such_subdir = os.path.join('no', 'such', 'subdir') try: test = TestCmd.TestCmd(workdir = no_such_subdir) except OSError: # expect "No such file or directory" pass except: raise test = TestCmd.TestCmd(workdir = 'foo') workdir_foo = test.workdir assert workdir_foo != None test.workdir_set('bar') workdir_bar = test.workdir assert workdir_bar != None try: test.workdir_set(no_such_subdir) except OSError: pass # expect "No such file or directory" except: raise assert workdir_bar == test.workdir assert os.path.isdir(workdir_foo) assert os.path.isdir(workdir_bar) class workdirs_TestCase(TestCmdTestCase): def test_workdirs(self): """Test workdirs()""" test = TestCmd.TestCmd() assert test.workdir is None test.workdir_set('') wdir1 = test.workdir test.workdir_set('') wdir2 = test.workdir assert os.path.isdir(wdir1) assert os.path.isdir(wdir2) test.cleanup() assert not os.path.exists(wdir1) assert not os.path.exists(wdir2) class workpath_TestCase(TestCmdTestCase): def test_workpath(self): """Test workpath()""" test = TestCmd.TestCmd() assert test.workdir is None test = TestCmd.TestCmd(workdir = '') wpath = test.workpath('foo', 'bar') assert wpath == os.path.join(test.workdir, 'foo', 'bar') class readable_TestCase(TestCmdTestCase): def test_readable(self): """Test readable()""" test = TestCmd.TestCmd(workdir = '', subdir = 'foo') test.write('file1', "Test file #1\n") test.write(['foo', 'file2'], "Test file #2\n") try: symlink = os.symlink except AttributeError: pass else: symlink('no_such_file', test.workpath('dangling_symlink')) test.readable(test.workdir, 0) # XXX skip these tests if euid == 0? assert not _is_readable(test.workdir) assert not _is_readable(test.workpath('file1')) assert not _is_readable(test.workpath('foo')) assert not _is_readable(test.workpath('foo', 'file2')) test.readable(test.workdir, 1) assert _is_readable(test.workdir) assert _is_readable(test.workpath('file1')) assert _is_readable(test.workpath('foo')) assert _is_readable(test.workpath('foo', 'file2')) test.readable(test.workdir, 0) # XXX skip these tests if euid == 0? assert not _is_readable(test.workdir) assert not _is_readable(test.workpath('file1')) assert not _is_readable(test.workpath('foo')) assert not _is_readable(test.workpath('foo', 'file2')) test.readable(test.workpath('file1'), 1) assert _is_readable(test.workpath('file1')) test.readable(test.workpath('file1'), 0) assert not _is_readable(test.workpath('file1')) test.readable(test.workdir, 1) class writable_TestCase(TestCmdTestCase): def test_writable(self): """Test writable()""" test = TestCmd.TestCmd(workdir = '', subdir = 'foo') test.write('file1', "Test file #1\n") test.write(['foo', 'file2'], "Test file #2\n") try: symlink = os.symlink except AttributeError: pass else: symlink('no_such_file', test.workpath('dangling_symlink')) test.writable(test.workdir, 0) # XXX skip these tests if euid == 0? assert not _is_writable(test.workdir) assert not _is_writable(test.workpath('file1')) assert not _is_writable(test.workpath('foo')) assert not _is_writable(test.workpath('foo', 'file2')) test.writable(test.workdir, 1) assert _is_writable(test.workdir) assert _is_writable(test.workpath('file1')) assert _is_writable(test.workpath('foo')) assert _is_writable(test.workpath('foo', 'file2')) test.writable(test.workdir, 0) # XXX skip these tests if euid == 0? assert not _is_writable(test.workdir) assert not _is_writable(test.workpath('file1')) assert not _is_writable(test.workpath('foo')) assert not _is_writable(test.workpath('foo', 'file2')) test.writable(test.workpath('file1'), 1) assert _is_writable(test.workpath('file1')) test.writable(test.workpath('file1'), 0) assert not _is_writable(test.workpath('file1')) class executable_TestCase(TestCmdTestCase): def test_executable(self): """Test executable()""" test = TestCmd.TestCmd(workdir = '', subdir = 'foo') test.write('file1', "Test file #1\n") test.write(['foo', 'file2'], "Test file #2\n") try: symlink = os.symlink except AttributeError: pass else: symlink('no_such_file', test.workpath('dangling_symlink')) def make_executable(fname): st = os.stat(fname) os.chmod(fname, stat.S_IMODE(st[stat.ST_MODE]|0o100)) def make_non_executable(fname): st = os.stat(fname) os.chmod(fname, stat.S_IMODE(st[stat.ST_MODE]&~0o100)) test.executable(test.workdir, 0) # XXX skip these tests if euid == 0? assert not _is_executable(test.workdir) make_executable(test.workdir) assert not _is_executable(test.workpath('file1')) assert not _is_executable(test.workpath('foo')) make_executable(test.workpath('foo')) assert not _is_executable(test.workpath('foo', 'file2')) make_non_executable(test.workpath('foo')) make_non_executable(test.workdir) test.executable(test.workdir, 1) assert _is_executable(test.workdir) assert _is_executable(test.workpath('file1')) assert _is_executable(test.workpath('foo')) assert _is_executable(test.workpath('foo', 'file2')) test.executable(test.workdir, 0) # XXX skip these tests if euid == 0? assert not _is_executable(test.workdir) make_executable(test.workdir) assert not _is_executable(test.workpath('file1')) assert not _is_executable(test.workpath('foo')) make_executable(test.workpath('foo')) assert not _is_executable(test.workpath('foo', 'file2')) test.executable(test.workpath('file1'), 1) assert _is_executable(test.workpath('file1')) test.executable(test.workpath('file1'), 0) assert not _is_executable(test.workpath('file1')) test.executable(test.workdir, 1) class write_TestCase(TestCmdTestCase): def test_write(self): """Test write()""" test = TestCmd.TestCmd(workdir = '', subdir = 'foo') test.write('file1', "Test file #1\n") test.write(['foo', 'file2'], "Test file #2\n") try: test.write(['bar', 'file3'], "Test file #3 (should not get created)\n") except IOError: # expect "No such file or directory" pass except: raise test.write(test.workpath('file4'), "Test file #4.\n") test.write(test.workpath('foo', 'file5'), "Test file #5.\n") try: test.write(test.workpath('bar', 'file6'), "Test file #6 (should not get created)\n") except IOError: # expect "No such file or directory" pass except: raise try: test.write('file7', "Test file #8.\n", mode = 'r') except ValueError: # expect "mode must begin with 'w' pass except: raise test.write('file8', "Test file #8.\n", mode = 'w') test.write('file9', "Test file #9.\r\n", mode = 'wb') if os.name != "nt": os.chmod(test.workdir, 0o500) try: test.write('file10', "Test file #10 (should not get created).\n") except IOError: # expect "Permission denied" pass except: raise assert os.path.isdir(test.workpath('foo')) assert not os.path.exists(test.workpath('bar')) assert os.path.isfile(test.workpath('file1')) assert os.path.isfile(test.workpath('foo', 'file2')) assert not os.path.exists(test.workpath('bar', 'file3')) assert os.path.isfile(test.workpath('file4')) assert os.path.isfile(test.workpath('foo', 'file5')) assert not os.path.exists(test.workpath('bar', 'file6')) assert not os.path.exists(test.workpath('file7')) assert os.path.isfile(test.workpath('file8')) assert os.path.isfile(test.workpath('file9')) if os.name != "nt": assert not os.path.exists(test.workpath('file10')) assert open(test.workpath('file8'), 'r').read() == "Test file #8.\n" assert open(test.workpath('file9'), 'rb').read() == "Test file #9.\r\n" class variables_TestCase(TestCmdTestCase): def test_variables(self): """Test global variables""" run_env = TestCmd.TestCmd(workdir = '') variables = [ 'fail_test', 'no_result', 'pass_test', 'match_exact', 'match_re', 'match_re_dotall', 'python', '_python_', 'TestCmd', ] script = "from __future__ import print_function\n" + \ "import TestCmd\n" + \ '\n'.join([ "print(TestCmd.%s\n)" % v for v in variables ]) run_env.run(program=sys.executable, stdin=script) stderr = run_env.stderr() assert stderr == "", stderr script = "from __future__ import print_function\n" + \ "from TestCmd import *\n" + \ '\n'.join([ "print(%s)" % v for v in variables ]) run_env.run(program=sys.executable, stdin=script) stderr = run_env.stderr() assert stderr == "", stderr if __name__ == "__main__": tclasses = [ __init__TestCase, basename_TestCase, cleanup_TestCase, chmod_TestCase, combine_TestCase, command_args_TestCase, description_TestCase, diff_TestCase, diff_stderr_TestCase, diff_stdout_TestCase, exit_TestCase, fail_test_TestCase, interpreter_TestCase, match_TestCase, match_exact_TestCase, match_re_dotall_TestCase, match_re_TestCase, match_stderr_TestCase, match_stdout_TestCase, no_result_TestCase, pass_test_TestCase, preserve_TestCase, program_TestCase, read_TestCase, rmdir_TestCase, run_TestCase, run_verbose_TestCase, set_diff_function_TestCase, set_match_function_TestCase, sleep_TestCase, start_TestCase, stderr_TestCase, stdin_TestCase, stdout_TestCase, subdir_TestCase, symlink_TestCase, tempdir_TestCase, timeout_TestCase, unlink_TestCase, touch_TestCase, verbose_TestCase, workdir_TestCase, workdirs_TestCase, workpath_TestCase, writable_TestCase, write_TestCase, variables_TestCase, ] if sys.platform != 'win32': tclasses.extend([ executable_TestCase, readable_TestCase, ]) suite = unittest.TestSuite() for tclass in tclasses: names = unittest.getTestCaseNames(tclass, 'test_') suite.addTests([ tclass(n) for n in names ]) if not unittest.TextTestRunner().run(suite).wasSuccessful(): sys.exit(1) # Local Variables: # tab-width:4 # indent-tabs-mode:nil # End: # vim: set expandtab tabstop=4 shiftwidth=4: