181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org""" 281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgTestCmd.py: a testing framework for commands and scripts. 381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgThe TestCmd module provides a framework for portable automated testing 581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgof executable commands and scripts (in any language, not just Python), 681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgespecially commands and scripts that require file system interaction. 781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgIn addition to running tests and evaluating conditions, the TestCmd 981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgmodule manages and cleans up one or more temporary workspace 1081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgdirectories, and provides methods for creating files and directories in 1181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgthose workspace directories from in-line data, here-documents), allowing 1281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgtests to be completely self-contained. 1381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 1481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgA TestCmd environment object is created via the usual invocation: 1581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 1681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org import TestCmd 1781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test = TestCmd.TestCmd() 1881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 1981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgThere are a bunch of keyword arguments available at instantiation: 2081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 2181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test = TestCmd.TestCmd(description = 'string', 2281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org program = 'program_or_script_to_test', 2381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org interpreter = 'script_interpreter', 2481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org workdir = 'prefix', 2581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org subdir = 'subdir', 2681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org verbose = Boolean, 2781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org match = default_match_function, 2881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org diff = default_diff_function, 2981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org combine = Boolean) 3081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 3181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgThere are a bunch of methods that let you do different things: 3281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 3381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.verbose_set(1) 3481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 3581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.description_set('string') 3681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 3781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.program_set('program_or_script_to_test') 3881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 3981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.interpreter_set('script_interpreter') 4081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.interpreter_set(['script_interpreter', 'arg']) 4181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 4281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.workdir_set('prefix') 4381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.workdir_set('') 4481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 4581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.workpath('file') 4681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.workpath('subdir', 'file') 4781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 4881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.subdir('subdir', ...) 4981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 5081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.rmdir('subdir', ...) 5181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 5281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.write('file', "contents\n") 5381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.write(['subdir', 'file'], "contents\n") 5481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 5581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.read('file') 5681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.read(['subdir', 'file']) 5781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.read('file', mode) 5881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.read(['subdir', 'file'], mode) 5981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 6081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.writable('dir', 1) 6181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.writable('dir', None) 6281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 6381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.preserve(condition, ...) 6481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 6581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.cleanup(condition) 6681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 6781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.command_args(program = 'program_or_script_to_run', 6881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org interpreter = 'script_interpreter', 6981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org arguments = 'arguments to pass to program') 7081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 7181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.run(program = 'program_or_script_to_run', 7281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org interpreter = 'script_interpreter', 7381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org arguments = 'arguments to pass to program', 7481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org chdir = 'directory_to_chdir_to', 7581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org stdin = 'input to feed to the program\n') 7681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org universal_newlines = True) 7781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 7881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org p = test.start(program = 'program_or_script_to_run', 7981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org interpreter = 'script_interpreter', 8081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org arguments = 'arguments to pass to program', 8181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org universal_newlines = None) 8281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 8381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.finish(self, p) 8481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 8581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.pass_test() 8681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.pass_test(condition) 8781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.pass_test(condition, function) 8881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 8981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.fail_test() 9081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.fail_test(condition) 9181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.fail_test(condition, function) 9281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.fail_test(condition, function, skip) 9381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 9481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.no_result() 9581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.no_result(condition) 9681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.no_result(condition, function) 9781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.no_result(condition, function, skip) 9881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 9981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.stdout() 10081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.stdout(run) 10181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 10281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.stderr() 10381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.stderr(run) 10481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 10581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.symlink(target, link) 10681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 10781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.banner(string) 10881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.banner(string, width) 10981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 11081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.diff(actual, expected) 11181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 11281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.match(actual, expected) 11381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 11481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.match_exact("actual 1\nactual 2\n", "expected 1\nexpected 2\n") 11581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.match_exact(["actual 1\n", "actual 2\n"], 11681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org ["expected 1\n", "expected 2\n"]) 11781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 11881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.match_re("actual 1\nactual 2\n", regex_string) 11981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.match_re(["actual 1\n", "actual 2\n"], list_of_regexes) 12081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 12181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.match_re_dotall("actual 1\nactual 2\n", regex_string) 12281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.match_re_dotall(["actual 1\n", "actual 2\n"], list_of_regexes) 12381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 12481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.tempdir() 12581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.tempdir('temporary-directory') 12681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 12781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.sleep() 12881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.sleep(seconds) 12981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 13081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.where_is('foo') 13181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.where_is('foo', 'PATH1:PATH2') 13281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.where_is('foo', 'PATH1;PATH2', '.suffix3;.suffix4') 13381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 13481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.unlink('file') 13581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.unlink('subdir', 'file') 13681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 13781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgThe TestCmd module provides pass_test(), fail_test(), and no_result() 13881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgunbound functions that report test results for use with the Aegis change 13981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgmanagement system. These methods terminate the test immediately, 14081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgreporting PASSED, FAILED, or NO RESULT respectively, and exiting with 14181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgstatus 0 (success), 1 or 2 respectively. This allows for a distinction 14281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgbetween an actual failed test and a test that could not be properly 14381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgevaluated because of an external condition (such as a full file system 14481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgor incorrect permissions). 14581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 14681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org import TestCmd 14781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 14881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org TestCmd.pass_test() 14981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org TestCmd.pass_test(condition) 15081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org TestCmd.pass_test(condition, function) 15181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 15281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org TestCmd.fail_test() 15381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org TestCmd.fail_test(condition) 15481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org TestCmd.fail_test(condition, function) 15581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org TestCmd.fail_test(condition, function, skip) 15681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 15781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org TestCmd.no_result() 15881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org TestCmd.no_result(condition) 15981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org TestCmd.no_result(condition, function) 16081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org TestCmd.no_result(condition, function, skip) 16181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 16281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgThe TestCmd module also provides unbound functions that handle matching 16381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgin the same way as the match_*() methods described above. 16481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 16581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org import TestCmd 16681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 16781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test = TestCmd.TestCmd(match = TestCmd.match_exact) 16881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 16981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test = TestCmd.TestCmd(match = TestCmd.match_re) 17081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 17181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test = TestCmd.TestCmd(match = TestCmd.match_re_dotall) 17281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 17381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgThe TestCmd module provides unbound functions that can be used for the 17481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org"diff" argument to TestCmd.TestCmd instantiation: 17581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 17681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org import TestCmd 17781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 17881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test = TestCmd.TestCmd(match = TestCmd.match_re, 17981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org diff = TestCmd.diff_re) 18081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 18181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test = TestCmd.TestCmd(diff = TestCmd.simple_diff) 18281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 18381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgThe "diff" argument can also be used with standard difflib functions: 18481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 18581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org import difflib 18681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 18781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test = TestCmd.TestCmd(diff = difflib.context_diff) 18881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 18981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test = TestCmd.TestCmd(diff = difflib.unified_diff) 19081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 19181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgLastly, the where_is() method also exists in an unbound function 19281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgversion. 19381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 19481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org import TestCmd 19581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 19681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org TestCmd.where_is('foo') 19781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org TestCmd.where_is('foo', 'PATH1:PATH2') 19881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org TestCmd.where_is('foo', 'PATH1;PATH2', '.suffix3;.suffix4') 19981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org""" 20081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 201c3836fd58fdfa6f8bb2c70e40e6aaf11dfaa76d5sgk@chromium.org# Copyright 2000-2010 Steven Knight 20281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org# This module is free software, and you may redistribute it and/or modify 20381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org# it under the same terms as Python itself, so long as this copyright message 20481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org# and disclaimer are retained in their original form. 20581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org# 20681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org# IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, 20781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org# SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF 20881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org# THIS CODE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 20981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org# DAMAGE. 21081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org# 21181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org# THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT 21281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 21381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org# PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, 21481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org# AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, 21581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 21681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 21781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org__author__ = "Steven Knight <knight at baldmt dot com>" 218c3836fd58fdfa6f8bb2c70e40e6aaf11dfaa76d5sgk@chromium.org__revision__ = "TestCmd.py 0.37.D001 2010/01/11 16:55:50 knight" 219c3836fd58fdfa6f8bb2c70e40e6aaf11dfaa76d5sgk@chromium.org__version__ = "0.37" 22081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 22181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgimport errno 22281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgimport os 22381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgimport os.path 22481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgimport re 22581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgimport shutil 22681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgimport stat 22781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgimport string 22881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgimport sys 22981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgimport tempfile 23081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgimport time 23181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgimport traceback 23281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgimport types 23381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgimport UserList 23481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 23581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org__all__ = [ 23681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 'diff_re', 23781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 'fail_test', 23881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 'no_result', 23981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 'pass_test', 24081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 'match_exact', 24181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 'match_re', 24281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 'match_re_dotall', 24381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 'python_executable', 24481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 'TestCmd' 24581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org] 24681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 24781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgtry: 24881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org import difflib 24981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgexcept ImportError: 25081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org __all__.append('simple_diff') 25181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 25281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgdef is_List(e): 25381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return type(e) is types.ListType \ 25481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org or isinstance(e, UserList.UserList) 25581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 25681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgtry: 25781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org from UserString import UserString 25881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgexcept ImportError: 25981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org class UserString: 26081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org pass 26181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 26281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgif hasattr(types, 'UnicodeType'): 26381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def is_String(e): 26481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return type(e) is types.StringType \ 26581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org or type(e) is types.UnicodeType \ 26681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org or isinstance(e, UserString) 26781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgelse: 26881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def is_String(e): 26981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return type(e) is types.StringType or isinstance(e, UserString) 27081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 27181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgtempfile.template = 'testcmd.' 27281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgif os.name in ('posix', 'nt'): 27381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org tempfile.template = 'testcmd.' + str(os.getpid()) + '.' 27481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgelse: 27581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org tempfile.template = 'testcmd.' 27681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 27781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgre_space = re.compile('\s') 27881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 27981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org_Cleanup = [] 28081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 28181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org_chain_to_exitfunc = None 28281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 28381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgdef _clean(): 28481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org global _Cleanup 28581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org cleanlist = filter(None, _Cleanup) 28681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org del _Cleanup[:] 28781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org cleanlist.reverse() 28881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org for test in cleanlist: 28981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.cleanup() 29081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if _chain_to_exitfunc: 29181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org _chain_to_exitfunc() 29281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 29381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgtry: 29481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org import atexit 29581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgexcept ImportError: 29681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org # TODO(1.5): atexit requires python 2.0, so chain sys.exitfunc 29781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org try: 29881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org _chain_to_exitfunc = sys.exitfunc 29981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org except AttributeError: 30081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org pass 30181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org sys.exitfunc = _clean 30281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgelse: 30381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org atexit.register(_clean) 30481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 30581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgtry: 30681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org zip 30781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgexcept NameError: 30881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def zip(*lists): 30981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org result = [] 31081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org for i in xrange(min(map(len, lists))): 31181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org result.append(tuple(map(lambda l, i=i: l[i], lists))) 31281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return result 31381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 31481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgclass Collector: 31581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def __init__(self, top): 31681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self.entries = [top] 31781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def __call__(self, arg, dirname, names): 31881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org pathjoin = lambda n, d=dirname: os.path.join(d, n) 31981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self.entries.extend(map(pathjoin, names)) 32081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 32181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgdef _caller(tblist, skip): 32281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org string = "" 32381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org arr = [] 32481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org for file, line, name, text in tblist: 32581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if file[-10:] == "TestCmd.py": 32681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org break 32781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org arr = [(file, line, name, text)] + arr 32881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org atfrom = "at" 32981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org for file, line, name, text in arr[skip:]: 33081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if name in ("?", "<module>"): 33181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org name = "" 33281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org else: 33381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org name = " (" + name + ")" 33481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org string = string + ("%s line %d of %s%s\n" % (atfrom, line, file, name)) 33581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org atfrom = "\tfrom" 33681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return string 33781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 33881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgdef fail_test(self = None, condition = 1, function = None, skip = 0): 33981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """Cause the test to fail. 34081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 34181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org By default, the fail_test() method reports that the test FAILED 34281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org and exits with a status of 1. If a condition argument is supplied, 34381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org the test fails only if the condition is true. 34481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """ 34581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if not condition: 34681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return 34781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if not function is None: 34881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org function() 34981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org of = "" 35081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org desc = "" 35181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org sep = " " 35281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if not self is None: 35381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if self.program: 35481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org of = " of " + self.program 35581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org sep = "\n\t" 35681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if self.description: 35781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org desc = " [" + self.description + "]" 35881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org sep = "\n\t" 35981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 36081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org at = _caller(traceback.extract_stack(), skip) 36181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org sys.stderr.write("FAILED test" + of + desc + sep + at) 36281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 36381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org sys.exit(1) 36481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 36581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgdef no_result(self = None, condition = 1, function = None, skip = 0): 36681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """Causes a test to exit with no valid result. 36781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 36881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org By default, the no_result() method reports NO RESULT for the test 36981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org and exits with a status of 2. If a condition argument is supplied, 37081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org the test fails only if the condition is true. 37181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """ 37281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if not condition: 37381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return 37481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if not function is None: 37581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org function() 37681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org of = "" 37781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org desc = "" 37881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org sep = " " 37981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if not self is None: 38081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if self.program: 38181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org of = " of " + self.program 38281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org sep = "\n\t" 38381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if self.description: 38481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org desc = " [" + self.description + "]" 38581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org sep = "\n\t" 38681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 3873afe3277af466c60b6d35a56f578c09a4c5f4c98sbc@chromium.org if os.environ.get('TESTCMD_DEBUG_SKIPS'): 3883afe3277af466c60b6d35a56f578c09a4c5f4c98sbc@chromium.org at = _caller(traceback.extract_stack(), skip) 3893afe3277af466c60b6d35a56f578c09a4c5f4c98sbc@chromium.org sys.stderr.write("NO RESULT for test" + of + desc + sep + at) 3903afe3277af466c60b6d35a56f578c09a4c5f4c98sbc@chromium.org else: 3913afe3277af466c60b6d35a56f578c09a4c5f4c98sbc@chromium.org sys.stderr.write("NO RESULT\n") 39281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 39381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org sys.exit(2) 39481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 39581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgdef pass_test(self = None, condition = 1, function = None): 39681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """Causes a test to pass. 39781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 39881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org By default, the pass_test() method reports PASSED for the test 39981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org and exits with a status of 0. If a condition argument is supplied, 40081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org the test passes only if the condition is true. 40181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """ 40281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if not condition: 40381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return 40481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if not function is None: 40581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org function() 40681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org sys.stderr.write("PASSED\n") 40781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org sys.exit(0) 40881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 40981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgdef match_exact(lines = None, matches = None): 41081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """ 41181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """ 41281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if not is_List(lines): 41381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org lines = string.split(lines, "\n") 41481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if not is_List(matches): 41581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org matches = string.split(matches, "\n") 41681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if len(lines) != len(matches): 41781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return 41881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org for i in range(len(lines)): 41981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if lines[i] != matches[i]: 42081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return 42181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return 1 42281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 42381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgdef match_re(lines = None, res = None): 42481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """ 42581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """ 42681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if not is_List(lines): 42781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org lines = string.split(lines, "\n") 42881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if not is_List(res): 42981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org res = string.split(res, "\n") 43081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if len(lines) != len(res): 43181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return 43281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org for i in range(len(lines)): 43381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org s = "^" + res[i] + "$" 43481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org try: 43581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org expr = re.compile(s) 43681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org except re.error, e: 43781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org msg = "Regular expression error in %s: %s" 43881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org raise re.error, msg % (repr(s), e[0]) 43981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if not expr.search(lines[i]): 44081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return 44181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return 1 44281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 44381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgdef match_re_dotall(lines = None, res = None): 44481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """ 44581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """ 44681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if not type(lines) is type(""): 44781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org lines = string.join(lines, "\n") 44881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if not type(res) is type(""): 44981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org res = string.join(res, "\n") 45081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org s = "^" + res + "$" 45181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org try: 45281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org expr = re.compile(s, re.DOTALL) 45381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org except re.error, e: 45481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org msg = "Regular expression error in %s: %s" 45581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org raise re.error, msg % (repr(s), e[0]) 45681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if expr.match(lines): 45781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return 1 45881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 45981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgtry: 46081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org import difflib 46181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgexcept ImportError: 46281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org pass 46381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgelse: 46481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def simple_diff(a, b, fromfile='', tofile='', 46581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org fromfiledate='', tofiledate='', n=3, lineterm='\n'): 46681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """ 46781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org A function with the same calling signature as difflib.context_diff 46881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org (diff -c) and difflib.unified_diff (diff -u) but which prints 46981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org output like the simple, unadorned 'diff" command. 47081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """ 47181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org sm = difflib.SequenceMatcher(None, a, b) 47281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def comma(x1, x2): 47381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return x1+1 == x2 and str(x2) or '%s,%s' % (x1+1, x2) 47481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org result = [] 47581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org for op, a1, a2, b1, b2 in sm.get_opcodes(): 47681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if op == 'delete': 47781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org result.append("%sd%d" % (comma(a1, a2), b1)) 47881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org result.extend(map(lambda l: '< ' + l, a[a1:a2])) 47981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org elif op == 'insert': 48081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org result.append("%da%s" % (a1, comma(b1, b2))) 48181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org result.extend(map(lambda l: '> ' + l, b[b1:b2])) 48281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org elif op == 'replace': 48381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org result.append("%sc%s" % (comma(a1, a2), comma(b1, b2))) 48481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org result.extend(map(lambda l: '< ' + l, a[a1:a2])) 48581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org result.append('---') 48681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org result.extend(map(lambda l: '> ' + l, b[b1:b2])) 48781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return result 48881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 48981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgdef diff_re(a, b, fromfile='', tofile='', 49081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org fromfiledate='', tofiledate='', n=3, lineterm='\n'): 49181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """ 49281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org A simple "diff" of two sets of lines when the expected lines 49381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org are regular expressions. This is a really dumb thing that 49481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org just compares each line in turn, so it doesn't look for 49581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org chunks of matching lines and the like--but at least it lets 49681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org you know exactly which line first didn't compare correctl... 49781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """ 49881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org result = [] 49981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org diff = len(a) - len(b) 50081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if diff < 0: 50181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org a = a + ['']*(-diff) 50281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org elif diff > 0: 50381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org b = b + ['']*diff 50481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org i = 0 50581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org for aline, bline in zip(a, b): 50681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org s = "^" + aline + "$" 50781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org try: 50881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org expr = re.compile(s) 50981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org except re.error, e: 51081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org msg = "Regular expression error in %s: %s" 51181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org raise re.error, msg % (repr(s), e[0]) 51281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if not expr.search(bline): 51381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org result.append("%sc%s" % (i+1, i+1)) 51481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org result.append('< ' + repr(a[i])) 51581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org result.append('---') 51681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org result.append('> ' + repr(b[i])) 51781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org i = i+1 51881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return result 51981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 52081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgif os.name == 'java': 52181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 52281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org python_executable = os.path.join(sys.prefix, 'jython') 52381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 52481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgelse: 52581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 52681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org python_executable = sys.executable 52781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 52881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgif sys.platform == 'win32': 52981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 53081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org default_sleep_seconds = 2 53181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 53281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def where_is(file, path=None, pathext=None): 53381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if path is None: 53481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org path = os.environ['PATH'] 53581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if is_String(path): 53681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org path = string.split(path, os.pathsep) 53781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if pathext is None: 53881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org pathext = os.environ['PATHEXT'] 53981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if is_String(pathext): 54081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org pathext = string.split(pathext, os.pathsep) 54181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org for ext in pathext: 54281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if string.lower(ext) == string.lower(file[-len(ext):]): 54381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org pathext = [''] 54481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org break 54581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org for dir in path: 54681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org f = os.path.join(dir, file) 54781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org for ext in pathext: 54881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org fext = f + ext 54981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if os.path.isfile(fext): 55081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return fext 55181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return None 55281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 55381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgelse: 55481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 55581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def where_is(file, path=None, pathext=None): 55681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if path is None: 55781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org path = os.environ['PATH'] 55881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if is_String(path): 55981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org path = string.split(path, os.pathsep) 56081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org for dir in path: 56181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org f = os.path.join(dir, file) 56281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if os.path.isfile(f): 56381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org try: 56481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org st = os.stat(f) 56581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org except OSError: 56681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org continue 56781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if stat.S_IMODE(st[stat.ST_MODE]) & 0111: 56881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return f 56981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return None 57081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 57181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org default_sleep_seconds = 1 57281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 57381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 57481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 57581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgtry: 57681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org import subprocess 57781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgexcept ImportError: 57881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org # The subprocess module doesn't exist in this version of Python, 57981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org # so we're going to cobble up something that looks just enough 58081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org # like its API for our purposes below. 58181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org import new 58281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 58381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org subprocess = new.module('subprocess') 58481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 58581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org subprocess.PIPE = 'PIPE' 58681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org subprocess.STDOUT = 'STDOUT' 58781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org subprocess.mswindows = (sys.platform == 'win32') 58881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 58981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org try: 59081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org import popen2 59181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org popen2.Popen3 59281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org except AttributeError: 59381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org class Popen3: 59481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org universal_newlines = 1 59581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def __init__(self, command, **kw): 59681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if sys.platform == 'win32' and command[0] == '"': 59781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org command = '"' + command + '"' 59881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org (stdin, stdout, stderr) = os.popen3(' ' + command) 59981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self.stdin = stdin 60081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self.stdout = stdout 60181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self.stderr = stderr 60281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def close_output(self): 60381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self.stdout.close() 60481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self.resultcode = self.stderr.close() 60581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def wait(self): 60681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org resultcode = self.resultcode 60781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if os.WIFEXITED(resultcode): 60881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return os.WEXITSTATUS(resultcode) 60981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org elif os.WIFSIGNALED(resultcode): 61081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return os.WTERMSIG(resultcode) 61181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org else: 61281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return None 61381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 61481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org else: 61581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org try: 61681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org popen2.Popen4 61781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org except AttributeError: 61881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org # A cribbed Popen4 class, with some retrofitted code from 61981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org # the Python 1.5 Popen3 class methods to do certain things 62081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org # by hand. 62181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org class Popen4(popen2.Popen3): 62281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org childerr = None 62381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 62481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def __init__(self, cmd, bufsize=-1): 62581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org p2cread, p2cwrite = os.pipe() 62681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org c2pread, c2pwrite = os.pipe() 62781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self.pid = os.fork() 62881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if self.pid == 0: 62981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org # Child 63081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org os.dup2(p2cread, 0) 63181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org os.dup2(c2pwrite, 1) 63281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org os.dup2(c2pwrite, 2) 63381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org for i in range(3, popen2.MAXFD): 63481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org try: 63581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org os.close(i) 63681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org except: pass 63781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org try: 63881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org os.execvp(cmd[0], cmd) 63981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org finally: 64081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org os._exit(1) 64181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org # Shouldn't come here, I guess 64281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org os._exit(1) 64381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org os.close(p2cread) 64481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self.tochild = os.fdopen(p2cwrite, 'w', bufsize) 64581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org os.close(c2pwrite) 64681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self.fromchild = os.fdopen(c2pread, 'r', bufsize) 64781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org popen2._active.append(self) 64881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 64981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org popen2.Popen4 = Popen4 65081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 65181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org class Popen3(popen2.Popen3, popen2.Popen4): 65281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org universal_newlines = 1 65381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def __init__(self, command, **kw): 65481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if kw.get('stderr') == 'STDOUT': 65581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org apply(popen2.Popen4.__init__, (self, command, 1)) 65681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org else: 65781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org apply(popen2.Popen3.__init__, (self, command, 1)) 65881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self.stdin = self.tochild 65981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self.stdout = self.fromchild 66081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self.stderr = self.childerr 66181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def wait(self, *args, **kw): 66281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org resultcode = apply(popen2.Popen3.wait, (self,)+args, kw) 66381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if os.WIFEXITED(resultcode): 66481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return os.WEXITSTATUS(resultcode) 66581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org elif os.WIFSIGNALED(resultcode): 66681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return os.WTERMSIG(resultcode) 66781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org else: 66881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return None 66981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 67081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org subprocess.Popen = Popen3 67181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 67281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 67381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 67481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org# From Josiah Carlson, 67581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org# ASPN : Python Cookbook : Module to allow Asynchronous subprocess use on Windows and Posix platforms 67681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org# http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/440554 67781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 67881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgPIPE = subprocess.PIPE 67981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 68081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgif subprocess.mswindows: 68181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org from win32file import ReadFile, WriteFile 68281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org from win32pipe import PeekNamedPipe 68381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org import msvcrt 68481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgelse: 68581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org import select 68681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org import fcntl 68781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 68881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org try: fcntl.F_GETFL 68981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org except AttributeError: fcntl.F_GETFL = 3 69081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 69181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org try: fcntl.F_SETFL 69281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org except AttributeError: fcntl.F_SETFL = 4 69381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 69481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgclass Popen(subprocess.Popen): 69581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def recv(self, maxsize=None): 69681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return self._recv('stdout', maxsize) 69781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 69881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def recv_err(self, maxsize=None): 69981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return self._recv('stderr', maxsize) 70081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 70181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def send_recv(self, input='', maxsize=None): 70281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return self.send(input), self.recv(maxsize), self.recv_err(maxsize) 70381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 70481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def get_conn_maxsize(self, which, maxsize): 70581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if maxsize is None: 70681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org maxsize = 1024 70781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org elif maxsize < 1: 70881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org maxsize = 1 70981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return getattr(self, which), maxsize 71081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 71181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def _close(self, which): 71281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org getattr(self, which).close() 71381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org setattr(self, which, None) 71481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 71581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if subprocess.mswindows: 71681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def send(self, input): 71781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if not self.stdin: 71881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return None 71981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 72081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org try: 72181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org x = msvcrt.get_osfhandle(self.stdin.fileno()) 72281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org (errCode, written) = WriteFile(x, input) 72381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org except ValueError: 72481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return self._close('stdin') 72581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org except (subprocess.pywintypes.error, Exception), why: 72681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if why[0] in (109, errno.ESHUTDOWN): 72781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return self._close('stdin') 72881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org raise 72981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 73081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return written 73181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 73281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def _recv(self, which, maxsize): 73381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org conn, maxsize = self.get_conn_maxsize(which, maxsize) 73481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if conn is None: 73581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return None 73681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 73781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org try: 73881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org x = msvcrt.get_osfhandle(conn.fileno()) 73981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org (read, nAvail, nMessage) = PeekNamedPipe(x, 0) 74081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if maxsize < nAvail: 74181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org nAvail = maxsize 74281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if nAvail > 0: 74381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org (errCode, read) = ReadFile(x, nAvail, None) 74481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org except ValueError: 74581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return self._close(which) 74681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org except (subprocess.pywintypes.error, Exception), why: 74781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if why[0] in (109, errno.ESHUTDOWN): 74881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return self._close(which) 74981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org raise 75081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 75181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org #if self.universal_newlines: 75281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org # read = self._translate_newlines(read) 75381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return read 75481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 75581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org else: 75681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def send(self, input): 75781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if not self.stdin: 75881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return None 75981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 76081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if not select.select([], [self.stdin], [], 0)[1]: 76181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return 0 76281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 76381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org try: 76481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org written = os.write(self.stdin.fileno(), input) 76581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org except OSError, why: 76681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if why[0] == errno.EPIPE: #broken pipe 76781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return self._close('stdin') 76881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org raise 76981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 77081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return written 77181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 77281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def _recv(self, which, maxsize): 77381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org conn, maxsize = self.get_conn_maxsize(which, maxsize) 77481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if conn is None: 77581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return None 77681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 77781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org try: 77881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org flags = fcntl.fcntl(conn, fcntl.F_GETFL) 77981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org except TypeError: 78081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org flags = None 78181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org else: 78281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if not conn.closed: 78381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org fcntl.fcntl(conn, fcntl.F_SETFL, flags| os.O_NONBLOCK) 78481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 78581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org try: 78681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if not select.select([conn], [], [], 0)[0]: 78781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return '' 78881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 78981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org r = conn.read(maxsize) 79081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if not r: 79181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return self._close(which) 79281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 79381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org #if self.universal_newlines: 79481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org # r = self._translate_newlines(r) 79581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return r 79681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org finally: 79781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if not conn.closed and not flags is None: 79881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org fcntl.fcntl(conn, fcntl.F_SETFL, flags) 79981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 80081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgdisconnect_message = "Other end disconnected!" 80181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 80281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgdef recv_some(p, t=.1, e=1, tr=5, stderr=0): 80381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if tr < 1: 80481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org tr = 1 80581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org x = time.time()+t 80681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org y = [] 80781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org r = '' 80881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org pr = p.recv 80981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if stderr: 81081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org pr = p.recv_err 81181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org while time.time() < x or r: 81281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org r = pr() 81381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if r is None: 81481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if e: 81581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org raise Exception(disconnect_message) 81681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org else: 81781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org break 81881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org elif r: 81981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org y.append(r) 82081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org else: 82181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org time.sleep(max((x-time.time())/tr, 0)) 82281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return ''.join(y) 82381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 82481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org# TODO(3.0: rewrite to use memoryview() 82581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgdef send_all(p, data): 82681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org while len(data): 82781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org sent = p.send(data) 82881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if sent is None: 82981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org raise Exception(disconnect_message) 83081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org data = buffer(data, sent) 83181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 83281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 83381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 834c3836fd58fdfa6f8bb2c70e40e6aaf11dfaa76d5sgk@chromium.orgtry: 835c3836fd58fdfa6f8bb2c70e40e6aaf11dfaa76d5sgk@chromium.org object 836c3836fd58fdfa6f8bb2c70e40e6aaf11dfaa76d5sgk@chromium.orgexcept NameError: 837c3836fd58fdfa6f8bb2c70e40e6aaf11dfaa76d5sgk@chromium.org class object: 838c3836fd58fdfa6f8bb2c70e40e6aaf11dfaa76d5sgk@chromium.org pass 839c3836fd58fdfa6f8bb2c70e40e6aaf11dfaa76d5sgk@chromium.org 840c3836fd58fdfa6f8bb2c70e40e6aaf11dfaa76d5sgk@chromium.org 841c3836fd58fdfa6f8bb2c70e40e6aaf11dfaa76d5sgk@chromium.org 84281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.orgclass TestCmd(object): 84381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """Class TestCmd 84481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """ 84581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 84681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def __init__(self, description = None, 84781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org program = None, 84881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org interpreter = None, 84981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org workdir = None, 85081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org subdir = None, 85181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org verbose = None, 85281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org match = None, 85381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org diff = None, 85481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org combine = 0, 85581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org universal_newlines = 1): 85681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self._cwd = os.getcwd() 85781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self.description_set(description) 85881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self.program_set(program) 85981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self.interpreter_set(interpreter) 86081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if verbose is None: 86181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org try: 86281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org verbose = max( 0, int(os.environ.get('TESTCMD_VERBOSE', 0)) ) 86381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org except ValueError: 86481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org verbose = 0 86581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self.verbose_set(verbose) 86681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self.combine = combine 86781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self.universal_newlines = universal_newlines 8682013ec6b77b9f4ce80b7c0d7fafd187e7b3e3f9fthakis@chromium.org if match is not None: 86981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self.match_function = match 87081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org else: 87181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self.match_function = match_re 8722013ec6b77b9f4ce80b7c0d7fafd187e7b3e3f9fthakis@chromium.org if diff is not None: 87381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self.diff_function = diff 87481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org else: 87581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org try: 87681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org difflib 87781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org except NameError: 87881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org pass 87981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org else: 88081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self.diff_function = simple_diff 88181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org #self.diff_function = difflib.context_diff 88281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org #self.diff_function = difflib.unified_diff 88381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self._dirlist = [] 88481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self._preserve = {'pass_test': 0, 'fail_test': 0, 'no_result': 0} 88581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if os.environ.has_key('PRESERVE') and not os.environ['PRESERVE'] is '': 88681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self._preserve['pass_test'] = os.environ['PRESERVE'] 88781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self._preserve['fail_test'] = os.environ['PRESERVE'] 88881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self._preserve['no_result'] = os.environ['PRESERVE'] 88981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org else: 89081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org try: 89181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self._preserve['pass_test'] = os.environ['PRESERVE_PASS'] 89281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org except KeyError: 89381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org pass 89481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org try: 89581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self._preserve['fail_test'] = os.environ['PRESERVE_FAIL'] 89681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org except KeyError: 89781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org pass 89881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org try: 89981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self._preserve['no_result'] = os.environ['PRESERVE_NO_RESULT'] 90081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org except KeyError: 90181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org pass 90281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self._stdout = [] 90381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self._stderr = [] 90481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self.status = None 90581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self.condition = 'no_result' 90681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self.workdir_set(workdir) 90781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self.subdir(subdir) 90881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 90981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def __del__(self): 91081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self.cleanup() 91181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 91281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def __repr__(self): 91381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return "%x" % id(self) 91481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 91581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org banner_char = '=' 91681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org banner_width = 80 91781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 91881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def banner(self, s, width=None): 91981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if width is None: 92081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org width = self.banner_width 92181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return s + self.banner_char * (width - len(s)) 92281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 92381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if os.name == 'posix': 92481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 92581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def escape(self, arg): 92681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org "escape shell special characters" 92781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org slash = '\\' 92881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org special = '"$' 92981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 93081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org arg = string.replace(arg, slash, slash+slash) 93181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org for c in special: 93281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org arg = string.replace(arg, c, slash+c) 93381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 93481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if re_space.search(arg): 93581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org arg = '"' + arg + '"' 93681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return arg 93781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 93881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org else: 93981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 94081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org # Windows does not allow special characters in file names 94181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org # anyway, so no need for an escape function, we will just quote 94281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org # the arg. 94381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def escape(self, arg): 94481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if re_space.search(arg): 94581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org arg = '"' + arg + '"' 94681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return arg 94781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 94881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def canonicalize(self, path): 94981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if is_List(path): 95081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org path = apply(os.path.join, tuple(path)) 95181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if not os.path.isabs(path): 95281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org path = os.path.join(self.workdir, path) 95381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return path 95481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 95581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def chmod(self, path, mode): 95681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """Changes permissions on the specified file or directory 95781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org path name.""" 95881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org path = self.canonicalize(path) 95981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org os.chmod(path, mode) 96081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 96181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def cleanup(self, condition = None): 96281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """Removes any temporary working directories for the specified 96381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org TestCmd environment. If the environment variable PRESERVE was 96481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org set when the TestCmd environment was created, temporary working 96581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org directories are not removed. If any of the environment variables 96681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org PRESERVE_PASS, PRESERVE_FAIL, or PRESERVE_NO_RESULT were set 96781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org when the TestCmd environment was created, then temporary working 96881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org directories are not removed if the test passed, failed, or had 96981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org no result, respectively. Temporary working directories are also 97081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org preserved for conditions specified via the preserve method. 97181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 97281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org Typically, this method is not called directly, but is used when 97381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org the script exits to clean up temporary working directories as 97481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org appropriate for the exit status. 97581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """ 97681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if not self._dirlist: 97781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return 97881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org os.chdir(self._cwd) 97981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self.workdir = None 98081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if condition is None: 98181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org condition = self.condition 98281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if self._preserve[condition]: 98381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org for dir in self._dirlist: 98481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org print "Preserved directory", dir 98581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org else: 98681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org list = self._dirlist[:] 98781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org list.reverse() 98881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org for dir in list: 98981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self.writable(dir, 1) 99081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org shutil.rmtree(dir, ignore_errors = 1) 99181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self._dirlist = [] 99281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 99381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org try: 99481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org global _Cleanup 99581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org _Cleanup.remove(self) 99681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org except (AttributeError, ValueError): 99781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org pass 99881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 99981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def command_args(self, program = None, 100081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org interpreter = None, 100181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org arguments = None): 100281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if program: 100381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if type(program) == type('') and not os.path.isabs(program): 100481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org program = os.path.join(self._cwd, program) 100581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org else: 100681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org program = self.program 100781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if not interpreter: 100881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org interpreter = self.interpreter 100981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if not type(program) in [type([]), type(())]: 101081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org program = [program] 101181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org cmd = list(program) 101281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if interpreter: 101381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if not type(interpreter) in [type([]), type(())]: 101481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org interpreter = [interpreter] 101581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org cmd = list(interpreter) + cmd 101681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if arguments: 101781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if type(arguments) == type(''): 101881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org arguments = string.split(arguments) 101981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org cmd.extend(arguments) 102081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return cmd 102181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 102281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def description_set(self, description): 102381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """Set the description of the functionality being tested. 102481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """ 102581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self.description = description 102681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 102781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org try: 102881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org difflib 102981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org except NameError: 103081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def diff(self, a, b, name, *args, **kw): 103181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org print self.banner('Expected %s' % name) 103281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org print a 103381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org print self.banner('Actual %s' % name) 103481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org print b 103581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org else: 103681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def diff(self, a, b, name, *args, **kw): 103781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org print self.banner(name) 103881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org args = (a.splitlines(), b.splitlines()) + args 103981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org lines = apply(self.diff_function, args, kw) 104081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org for l in lines: 104181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org print l 104281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 104381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def fail_test(self, condition = 1, function = None, skip = 0): 104481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """Cause the test to fail. 104581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """ 104681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if not condition: 104781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return 104881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self.condition = 'fail_test' 104981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org fail_test(self = self, 105081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org condition = condition, 105181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org function = function, 105281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org skip = skip) 105381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 105481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def interpreter_set(self, interpreter): 105581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """Set the program to be used to interpret the program 105681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org under test as a script. 105781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """ 105881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self.interpreter = interpreter 105981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 106081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def match(self, lines, matches): 106181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """Compare actual and expected file contents. 106281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """ 106381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return self.match_function(lines, matches) 106481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 106581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def match_exact(self, lines, matches): 106681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """Compare actual and expected file contents. 106781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """ 106881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return match_exact(lines, matches) 106981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 107081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def match_re(self, lines, res): 107181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """Compare actual and expected file contents. 107281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """ 107381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return match_re(lines, res) 107481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 107581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def match_re_dotall(self, lines, res): 107681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """Compare actual and expected file contents. 107781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """ 107881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return match_re_dotall(lines, res) 107981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 108081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def no_result(self, condition = 1, function = None, skip = 0): 108181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """Report that the test could not be run. 108281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """ 108381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if not condition: 108481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return 108581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self.condition = 'no_result' 108681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org no_result(self = self, 108781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org condition = condition, 108881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org function = function, 108981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org skip = skip) 109081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 109181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def pass_test(self, condition = 1, function = None): 109281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """Cause the test to pass. 109381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """ 109481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if not condition: 109581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return 109681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self.condition = 'pass_test' 109781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org pass_test(self = self, condition = condition, function = function) 109881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 109981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def preserve(self, *conditions): 110081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """Arrange for the temporary working directories for the 110181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org specified TestCmd environment to be preserved for one or more 110281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org conditions. If no conditions are specified, arranges for 110381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org the temporary working directories to be preserved for all 110481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org conditions. 110581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """ 110681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if conditions is (): 110781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org conditions = ('pass_test', 'fail_test', 'no_result') 110881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org for cond in conditions: 110981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self._preserve[cond] = 1 111081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 111181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def program_set(self, program): 111281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """Set the executable program or script to be tested. 111381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """ 111481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if program and not os.path.isabs(program): 111581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org program = os.path.join(self._cwd, program) 111681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self.program = program 111781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 111881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def read(self, file, mode = 'rb'): 111981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """Reads and returns the contents of the specified file name. 112081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org The file name may be a list, in which case the elements are 112181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org concatenated with the os.path.join() method. The file is 112281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org assumed to be under the temporary working directory unless it 112381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org is an absolute path name. The I/O mode for the file may 112481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org be specified; it must begin with an 'r'. The default is 112581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 'rb' (binary read). 112681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """ 112781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org file = self.canonicalize(file) 112881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if mode[0] != 'r': 112981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org raise ValueError, "mode must begin with 'r'" 1130fbcd968877bac98d0d6f5f61847c0232939562f4thakis@chromium.org with open(file, mode) as f: 1131fbcd968877bac98d0d6f5f61847c0232939562f4thakis@chromium.org result = f.read() 1132fbcd968877bac98d0d6f5f61847c0232939562f4thakis@chromium.org return result 113381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 113481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def rmdir(self, dir): 113581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """Removes the specified dir name. 113681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org The dir name may be a list, in which case the elements are 113781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org concatenated with the os.path.join() method. The dir is 113881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org assumed to be under the temporary working directory unless it 113981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org is an absolute path name. 114081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org The dir must be empty. 114181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """ 114281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org dir = self.canonicalize(dir) 114381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org os.rmdir(dir) 114481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 114581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def start(self, program = None, 114681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org interpreter = None, 114781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org arguments = None, 114881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org universal_newlines = None, 114981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org **kw): 115081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """ 115181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org Starts a program or script for the test environment. 115281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 115381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org The specified program will have the original directory 115481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org prepended unless it is enclosed in a [list]. 115581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """ 115681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org cmd = self.command_args(program, interpreter, arguments) 115781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org cmd_string = string.join(map(self.escape, cmd), ' ') 115881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if self.verbose: 115981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org sys.stderr.write(cmd_string + "\n") 116081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if universal_newlines is None: 116181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org universal_newlines = self.universal_newlines 116281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 1163c3836fd58fdfa6f8bb2c70e40e6aaf11dfaa76d5sgk@chromium.org # On Windows, if we make stdin a pipe when we plan to send 1164c3836fd58fdfa6f8bb2c70e40e6aaf11dfaa76d5sgk@chromium.org # no input, and the test program exits before 1165c3836fd58fdfa6f8bb2c70e40e6aaf11dfaa76d5sgk@chromium.org # Popen calls msvcrt.open_osfhandle, that call will fail. 1166c3836fd58fdfa6f8bb2c70e40e6aaf11dfaa76d5sgk@chromium.org # So don't use a pipe for stdin if we don't need one. 1167c3836fd58fdfa6f8bb2c70e40e6aaf11dfaa76d5sgk@chromium.org stdin = kw.get('stdin', None) 1168c3836fd58fdfa6f8bb2c70e40e6aaf11dfaa76d5sgk@chromium.org if stdin is not None: 1169c3836fd58fdfa6f8bb2c70e40e6aaf11dfaa76d5sgk@chromium.org stdin = subprocess.PIPE 1170c3836fd58fdfa6f8bb2c70e40e6aaf11dfaa76d5sgk@chromium.org 117181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org combine = kw.get('combine', self.combine) 117281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if combine: 117381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org stderr_value = subprocess.STDOUT 117481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org else: 117581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org stderr_value = subprocess.PIPE 117681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 117781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return Popen(cmd, 1178c3836fd58fdfa6f8bb2c70e40e6aaf11dfaa76d5sgk@chromium.org stdin=stdin, 117981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org stdout=subprocess.PIPE, 118081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org stderr=stderr_value, 118181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org universal_newlines=universal_newlines) 118281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 118381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def finish(self, popen, **kw): 118481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """ 118581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org Finishes and waits for the process being run under control of 118681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org the specified popen argument, recording the exit status, 118781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org standard output and error output. 118881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """ 118981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org popen.stdin.close() 119081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self.status = popen.wait() 119181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if not self.status: 119281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self.status = 0 119381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self._stdout.append(popen.stdout.read()) 119481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if popen.stderr: 119581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org stderr = popen.stderr.read() 119681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org else: 119781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org stderr = '' 119881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self._stderr.append(stderr) 119981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 120081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def run(self, program = None, 120181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org interpreter = None, 120281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org arguments = None, 120381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org chdir = None, 120481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org stdin = None, 120581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org universal_newlines = None): 120681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """Runs a test of the program or script for the test 120781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org environment. Standard output and error output are saved for 120881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org future retrieval via the stdout() and stderr() methods. 120981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 121081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org The specified program will have the original directory 121181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org prepended unless it is enclosed in a [list]. 121281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """ 121381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if chdir: 121481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org oldcwd = os.getcwd() 121581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if not os.path.isabs(chdir): 121681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org chdir = os.path.join(self.workpath(chdir)) 121781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if self.verbose: 121881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org sys.stderr.write("chdir(" + chdir + ")\n") 121981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org os.chdir(chdir) 1220c3836fd58fdfa6f8bb2c70e40e6aaf11dfaa76d5sgk@chromium.org p = self.start(program, 1221c3836fd58fdfa6f8bb2c70e40e6aaf11dfaa76d5sgk@chromium.org interpreter, 1222c3836fd58fdfa6f8bb2c70e40e6aaf11dfaa76d5sgk@chromium.org arguments, 1223c3836fd58fdfa6f8bb2c70e40e6aaf11dfaa76d5sgk@chromium.org universal_newlines, 1224c3836fd58fdfa6f8bb2c70e40e6aaf11dfaa76d5sgk@chromium.org stdin=stdin) 122581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if stdin: 122681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if is_List(stdin): 122781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org for line in stdin: 122881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org p.stdin.write(line) 122981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org else: 123081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org p.stdin.write(stdin) 1231c3836fd58fdfa6f8bb2c70e40e6aaf11dfaa76d5sgk@chromium.org p.stdin.close() 123281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 123381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org out = p.stdout.read() 123481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if p.stderr is None: 123581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org err = '' 123681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org else: 123781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org err = p.stderr.read() 123881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org try: 123981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org close_output = p.close_output 124081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org except AttributeError: 124181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org p.stdout.close() 124281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if not p.stderr is None: 124381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org p.stderr.close() 124481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org else: 124581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org close_output() 124681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 124781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self._stdout.append(out) 124881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self._stderr.append(err) 124981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 125081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self.status = p.wait() 125181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if not self.status: 125281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self.status = 0 125381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 125481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if chdir: 125581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org os.chdir(oldcwd) 125681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if self.verbose >= 2: 125781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org write = sys.stdout.write 125881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org write('============ STATUS: %d\n' % self.status) 125981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org out = self.stdout() 126081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if out or self.verbose >= 3: 126181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org write('============ BEGIN STDOUT (len=%d):\n' % len(out)) 126281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org write(out) 126381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org write('============ END STDOUT\n') 126481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org err = self.stderr() 126581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if err or self.verbose >= 3: 126681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org write('============ BEGIN STDERR (len=%d)\n' % len(err)) 126781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org write(err) 126881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org write('============ END STDERR\n') 126981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 127081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def sleep(self, seconds = default_sleep_seconds): 127181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """Sleeps at least the specified number of seconds. If no 127281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org number is specified, sleeps at least the minimum number of 127381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org seconds necessary to advance file time stamps on the current 127481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org system. Sleeping more seconds is all right. 127581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """ 127681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org time.sleep(seconds) 127781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 127881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def stderr(self, run = None): 127981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """Returns the error output from the specified run number. 128081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org If there is no specified run number, then returns the error 128181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org output of the last run. If the run number is less than zero, 128281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org then returns the error output from that many runs back from the 128381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org current run. 128481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """ 128581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if not run: 128681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org run = len(self._stderr) 128781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org elif run < 0: 128881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org run = len(self._stderr) + run 128981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org run = run - 1 129081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return self._stderr[run] 129181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 129281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def stdout(self, run = None): 129381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """Returns the standard output from the specified run number. 129481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org If there is no specified run number, then returns the standard 129581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org output of the last run. If the run number is less than zero, 129681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org then returns the standard output from that many runs back from 129781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org the current run. 129881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """ 129981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if not run: 130081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org run = len(self._stdout) 130181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org elif run < 0: 130281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org run = len(self._stdout) + run 130381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org run = run - 1 130481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return self._stdout[run] 130581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 130681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def subdir(self, *subdirs): 130781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """Create new subdirectories under the temporary working 130881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org directory, one for each argument. An argument may be a list, 130981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org in which case the list elements are concatenated using the 131081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org os.path.join() method. Subdirectories multiple levels deep 131181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org must be created using a separate argument for each level: 131281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 131381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org test.subdir('sub', ['sub', 'dir'], ['sub', 'dir', 'ectory']) 131481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 131581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org Returns the number of subdirectories actually created. 131681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """ 131781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org count = 0 131881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org for sub in subdirs: 131981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if sub is None: 132081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org continue 132181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if is_List(sub): 132281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org sub = apply(os.path.join, tuple(sub)) 132381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org new = os.path.join(self.workdir, sub) 132481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org try: 132581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org os.mkdir(new) 132681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org except OSError: 132781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org pass 132881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org else: 132981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org count = count + 1 133081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return count 133181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 133281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def symlink(self, target, link): 133381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """Creates a symlink to the specified target. 133481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org The link name may be a list, in which case the elements are 133581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org concatenated with the os.path.join() method. The link is 133681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org assumed to be under the temporary working directory unless it 133781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org is an absolute path name. The target is *not* assumed to be 133881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org under the temporary working directory. 133981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """ 134081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org link = self.canonicalize(link) 134181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org os.symlink(target, link) 134281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 134381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def tempdir(self, path=None): 134481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """Creates a temporary directory. 134581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org A unique directory name is generated if no path name is specified. 134681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org The directory is created, and will be removed when the TestCmd 134781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org object is destroyed. 134881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """ 134981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if path is None: 135081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org try: 135181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org path = tempfile.mktemp(prefix=tempfile.template) 135281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org except TypeError: 135381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org path = tempfile.mktemp() 135481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org os.mkdir(path) 135581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 135681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org # Symlinks in the path will report things 135781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org # differently from os.getcwd(), so chdir there 135881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org # and back to fetch the canonical path. 135981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org cwd = os.getcwd() 136081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org try: 136181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org os.chdir(path) 136281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org path = os.getcwd() 136381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org finally: 136481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org os.chdir(cwd) 136581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 136681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org # Uppercase the drive letter since the case of drive 136781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org # letters is pretty much random on win32: 136881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org drive,rest = os.path.splitdrive(path) 136981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if drive: 137081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org path = string.upper(drive) + rest 137181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 137281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org # 137381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self._dirlist.append(path) 137481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org global _Cleanup 137581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org try: 137681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org _Cleanup.index(self) 137781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org except ValueError: 137881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org _Cleanup.append(self) 137981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 138081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return path 138181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 138281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def touch(self, path, mtime=None): 138381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """Updates the modification time on the specified file or 138481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org directory path name. The default is to update to the 138581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org current time if no explicit modification time is specified. 138681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """ 138781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org path = self.canonicalize(path) 138881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org atime = os.path.getatime(path) 138981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if mtime is None: 139081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org mtime = time.time() 139181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org os.utime(path, (atime, mtime)) 139281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 139381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def unlink(self, file): 139481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """Unlinks the specified file name. 139581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org The file name may be a list, in which case the elements are 139681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org concatenated with the os.path.join() method. The file is 139781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org assumed to be under the temporary working directory unless it 139881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org is an absolute path name. 139981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """ 140081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org file = self.canonicalize(file) 140181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org os.unlink(file) 140281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 140381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def verbose_set(self, verbose): 140481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """Set the verbose level. 140581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """ 140681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self.verbose = verbose 140781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 140881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def where_is(self, file, path=None, pathext=None): 140981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """Find an executable file. 141081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """ 141181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if is_List(file): 141281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org file = apply(os.path.join, tuple(file)) 141381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if not os.path.isabs(file): 141481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org file = where_is(file, path, pathext) 141581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return file 141681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 141781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def workdir_set(self, path): 141881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """Creates a temporary working directory with the specified 141981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org path name. If the path is a null string (''), a unique 142081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org directory name is created. 142181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """ 142281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if (path != None): 142381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if path == '': 142481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org path = None 142581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org path = self.tempdir(path) 142681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org self.workdir = path 142781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 142881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def workpath(self, *args): 142981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """Returns the absolute path name to a subdirectory or file 143081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org within the current temporary working directory. Concatenates 143181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org the temporary working directory name with the specified 143281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org arguments using the os.path.join() method. 143381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """ 143481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return apply(os.path.join, (self.workdir,) + tuple(args)) 143581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 143681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def readable(self, top, read=1): 143781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """Make the specified directory tree readable (read == 1) 143881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org or not (read == None). 143981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 144081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org This method has no effect on Windows systems, which use a 144181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org completely different mechanism to control file readability. 144281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """ 144381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 144481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if sys.platform == 'win32': 144581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return 144681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 144781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if read: 144881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def do_chmod(fname): 144981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org try: st = os.stat(fname) 145081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org except OSError: pass 145181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org else: os.chmod(fname, stat.S_IMODE(st[stat.ST_MODE]|stat.S_IREAD)) 145281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org else: 145381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def do_chmod(fname): 145481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org try: st = os.stat(fname) 145581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org except OSError: pass 145681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org else: os.chmod(fname, stat.S_IMODE(st[stat.ST_MODE]&~stat.S_IREAD)) 145781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 145881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if os.path.isfile(top): 145981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org # If it's a file, that's easy, just chmod it. 146081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org do_chmod(top) 146181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org elif read: 146281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org # It's a directory and we're trying to turn on read 146381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org # permission, so it's also pretty easy, just chmod the 146481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org # directory and then chmod every entry on our walk down the 146581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org # tree. Because os.path.walk() is top-down, we'll enable 146681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org # read permission on any directories that have it disabled 146781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org # before os.path.walk() tries to list their contents. 146881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org do_chmod(top) 146981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 147081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def chmod_entries(arg, dirname, names, do_chmod=do_chmod): 147181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org for n in names: 147281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org do_chmod(os.path.join(dirname, n)) 147381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 147481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org os.path.walk(top, chmod_entries, None) 147581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org else: 147681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org # It's a directory and we're trying to turn off read 147781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org # permission, which means we have to chmod the directoreis 147881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org # in the tree bottom-up, lest disabling read permission from 147981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org # the top down get in the way of being able to get at lower 148081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org # parts of the tree. But os.path.walk() visits things top 148181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org # down, so we just use an object to collect a list of all 148281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org # of the entries in the tree, reverse the list, and then 148381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org # chmod the reversed (bottom-up) list. 148481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org col = Collector(top) 148581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org os.path.walk(top, col, None) 148681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org col.entries.reverse() 148781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org for d in col.entries: do_chmod(d) 148881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 148981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def writable(self, top, write=1): 149081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """Make the specified directory tree writable (write == 1) 149181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org or not (write == None). 149281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """ 149381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 149481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if sys.platform == 'win32': 149581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 149681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if write: 149781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def do_chmod(fname): 149881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org try: os.chmod(fname, stat.S_IWRITE) 149981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org except OSError: pass 150081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org else: 150181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def do_chmod(fname): 150281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org try: os.chmod(fname, stat.S_IREAD) 150381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org except OSError: pass 150481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 150581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org else: 150681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 150781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if write: 150881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def do_chmod(fname): 150981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org try: st = os.stat(fname) 151081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org except OSError: pass 151181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org else: os.chmod(fname, stat.S_IMODE(st[stat.ST_MODE]|0200)) 151281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org else: 151381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def do_chmod(fname): 151481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org try: st = os.stat(fname) 151581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org except OSError: pass 151681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org else: os.chmod(fname, stat.S_IMODE(st[stat.ST_MODE]&~0200)) 151781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 151881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if os.path.isfile(top): 151981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org do_chmod(top) 152081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org else: 152181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org col = Collector(top) 152281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org os.path.walk(top, col, None) 152381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org for d in col.entries: do_chmod(d) 152481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 152581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def executable(self, top, execute=1): 152681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """Make the specified directory tree executable (execute == 1) 152781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org or not (execute == None). 152881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 152981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org This method has no effect on Windows systems, which use a 153081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org completely different mechanism to control file executability. 153181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """ 153281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 153381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if sys.platform == 'win32': 153481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org return 153581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 153681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if execute: 153781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def do_chmod(fname): 153881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org try: st = os.stat(fname) 153981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org except OSError: pass 154081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org else: os.chmod(fname, stat.S_IMODE(st[stat.ST_MODE]|stat.S_IEXEC)) 154181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org else: 154281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def do_chmod(fname): 154381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org try: st = os.stat(fname) 154481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org except OSError: pass 154581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org else: os.chmod(fname, stat.S_IMODE(st[stat.ST_MODE]&~stat.S_IEXEC)) 154681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 154781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if os.path.isfile(top): 154881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org # If it's a file, that's easy, just chmod it. 154981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org do_chmod(top) 155081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org elif execute: 155181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org # It's a directory and we're trying to turn on execute 155281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org # permission, so it's also pretty easy, just chmod the 155381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org # directory and then chmod every entry on our walk down the 155481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org # tree. Because os.path.walk() is top-down, we'll enable 155581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org # execute permission on any directories that have it disabled 155681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org # before os.path.walk() tries to list their contents. 155781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org do_chmod(top) 155881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 155981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def chmod_entries(arg, dirname, names, do_chmod=do_chmod): 156081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org for n in names: 156181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org do_chmod(os.path.join(dirname, n)) 156281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 156381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org os.path.walk(top, chmod_entries, None) 156481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org else: 156581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org # It's a directory and we're trying to turn off execute 156681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org # permission, which means we have to chmod the directories 156781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org # in the tree bottom-up, lest disabling execute permission from 156881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org # the top down get in the way of being able to get at lower 156981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org # parts of the tree. But os.path.walk() visits things top 157081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org # down, so we just use an object to collect a list of all 157181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org # of the entries in the tree, reverse the list, and then 157281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org # chmod the reversed (bottom-up) list. 157381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org col = Collector(top) 157481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org os.path.walk(top, col, None) 157581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org col.entries.reverse() 157681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org for d in col.entries: do_chmod(d) 157781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 157881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org def write(self, file, content, mode = 'wb'): 157981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """Writes the specified content text (second argument) to the 158081ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org specified file name (first argument). The file name may be 158181ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org a list, in which case the elements are concatenated with the 158281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org os.path.join() method. The file is created under the temporary 158381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org working directory. Any subdirectories in the path must already 158481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org exist. The I/O mode for the file may be specified; it must 158581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org begin with a 'w'. The default is 'wb' (binary write). 158681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org """ 158781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org file = self.canonicalize(file) 158881ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org if mode[0] != 'w': 158981ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org raise ValueError, "mode must begin with 'w'" 1590fbcd968877bac98d0d6f5f61847c0232939562f4thakis@chromium.org with open(file, mode) as f: 1591fbcd968877bac98d0d6f5f61847c0232939562f4thakis@chromium.org f.write(content) 159281ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org 159381ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org# Local Variables: 159481ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org# tab-width:4 159581ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org# indent-tabs-mode:nil 159681ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org# End: 159781ac0047a01ca7d34b493fba09e7fd6a5acf09c5sgk@chromium.org# vim: set expandtab tabstop=4 shiftwidth=4: 1598