|
1 # Tests command line execution of scripts |
|
2 |
|
3 import unittest |
|
4 import os |
|
5 import os.path |
|
6 import sys |
|
7 import test.test_support |
|
8 import tempfile |
|
9 import subprocess |
|
10 import py_compile |
|
11 import contextlib |
|
12 import shutil |
|
13 import zipfile |
|
14 |
|
15 verbose = test.test_support.verbose |
|
16 |
|
17 # XXX ncoghlan: Should we consider moving these to test_support? |
|
18 from test_cmd_line import _spawn_python, _kill_python |
|
19 |
|
20 def _run_python(*args): |
|
21 if __debug__: |
|
22 p = _spawn_python(*args) |
|
23 else: |
|
24 p = _spawn_python('-O', *args) |
|
25 stdout_data = _kill_python(p) |
|
26 return p.wait(), stdout_data |
|
27 |
|
28 @contextlib.contextmanager |
|
29 def temp_dir(): |
|
30 dirname = tempfile.mkdtemp() |
|
31 dirname = os.path.realpath(dirname) |
|
32 try: |
|
33 yield dirname |
|
34 finally: |
|
35 shutil.rmtree(dirname) |
|
36 |
|
37 test_source = """\ |
|
38 # Script may be run with optimisation enabled, so don't rely on assert |
|
39 # statements being executed |
|
40 def assertEqual(lhs, rhs): |
|
41 if lhs != rhs: |
|
42 raise AssertionError('%r != %r' % (lhs, rhs)) |
|
43 def assertIdentical(lhs, rhs): |
|
44 if lhs is not rhs: |
|
45 raise AssertionError('%r is not %r' % (lhs, rhs)) |
|
46 # Check basic code execution |
|
47 result = ['Top level assignment'] |
|
48 def f(): |
|
49 result.append('Lower level reference') |
|
50 f() |
|
51 assertEqual(result, ['Top level assignment', 'Lower level reference']) |
|
52 # Check population of magic variables |
|
53 assertEqual(__name__, '__main__') |
|
54 print '__file__==%r' % __file__ |
|
55 print '__package__==%r' % __package__ |
|
56 # Check the sys module |
|
57 import sys |
|
58 assertIdentical(globals(), sys.modules[__name__].__dict__) |
|
59 print 'sys.argv[0]==%r' % sys.argv[0] |
|
60 """ |
|
61 |
|
62 def _make_test_script(script_dir, script_basename, source=test_source): |
|
63 script_filename = script_basename+os.extsep+'py' |
|
64 script_name = os.path.join(script_dir, script_filename) |
|
65 script_file = open(script_name, 'w') |
|
66 script_file.write(source) |
|
67 script_file.close() |
|
68 return script_name |
|
69 |
|
70 def _compile_test_script(script_name): |
|
71 py_compile.compile(script_name, doraise=True) |
|
72 if __debug__: |
|
73 compiled_name = script_name + 'c' |
|
74 else: |
|
75 compiled_name = script_name + 'o' |
|
76 return compiled_name |
|
77 |
|
78 def _make_test_zip(zip_dir, zip_basename, script_name): |
|
79 zip_filename = zip_basename+os.extsep+'zip' |
|
80 zip_name = os.path.join(zip_dir, zip_filename) |
|
81 zip_file = zipfile.ZipFile(zip_name, 'w') |
|
82 zip_file.write(script_name, os.path.basename(script_name)) |
|
83 zip_file.close() |
|
84 # if verbose: |
|
85 # zip_file = zipfile.ZipFile(zip_name, 'r') |
|
86 # print 'Contents of %r:' % zip_name |
|
87 # zip_file.printdir() |
|
88 # zip_file.close() |
|
89 return zip_name |
|
90 |
|
91 def _make_test_pkg(pkg_dir): |
|
92 os.mkdir(pkg_dir) |
|
93 _make_test_script(pkg_dir, '__init__', '') |
|
94 |
|
95 # There's no easy way to pass the script directory in to get |
|
96 # -m to work (avoiding that is the whole point of making |
|
97 # directories and zipfiles executable!) |
|
98 # So we fake it for testing purposes with a custom launch script |
|
99 launch_source = """\ |
|
100 import sys, os.path, runpy |
|
101 sys.path[0:0] = os.path.dirname(__file__) |
|
102 runpy._run_module_as_main(%r) |
|
103 """ |
|
104 |
|
105 def _make_launch_script(script_dir, script_basename, module_name): |
|
106 return _make_test_script(script_dir, script_basename, |
|
107 launch_source % module_name) |
|
108 |
|
109 class CmdLineTest(unittest.TestCase): |
|
110 def _check_script(self, script_name, expected_file, |
|
111 expected_argv0, expected_package, |
|
112 *cmd_line_switches): |
|
113 run_args = cmd_line_switches + (script_name,) |
|
114 exit_code, data = _run_python(*run_args) |
|
115 if verbose: |
|
116 print 'Output from test script %r:' % script_name |
|
117 print data |
|
118 self.assertEqual(exit_code, 0) |
|
119 printed_file = '__file__==%r' % expected_file |
|
120 printed_argv0 = 'sys.argv[0]==%r' % expected_argv0 |
|
121 printed_package = '__package__==%r' % expected_package |
|
122 if verbose: |
|
123 print 'Expected output:' |
|
124 print printed_file |
|
125 print printed_package |
|
126 print printed_argv0 |
|
127 self.assert_(printed_file in data) |
|
128 self.assert_(printed_package in data) |
|
129 self.assert_(printed_argv0 in data) |
|
130 |
|
131 def test_basic_script(self): |
|
132 with temp_dir() as script_dir: |
|
133 script_name = _make_test_script(script_dir, 'script') |
|
134 self._check_script(script_name, script_name, script_name, None) |
|
135 |
|
136 def test_script_compiled(self): |
|
137 with temp_dir() as script_dir: |
|
138 script_name = _make_test_script(script_dir, 'script') |
|
139 compiled_name = _compile_test_script(script_name) |
|
140 os.remove(script_name) |
|
141 self._check_script(compiled_name, compiled_name, compiled_name, None) |
|
142 |
|
143 def test_directory(self): |
|
144 with temp_dir() as script_dir: |
|
145 script_name = _make_test_script(script_dir, '__main__') |
|
146 self._check_script(script_dir, script_name, script_dir, '') |
|
147 |
|
148 def test_directory_compiled(self): |
|
149 with temp_dir() as script_dir: |
|
150 script_name = _make_test_script(script_dir, '__main__') |
|
151 compiled_name = _compile_test_script(script_name) |
|
152 os.remove(script_name) |
|
153 self._check_script(script_dir, compiled_name, script_dir, '') |
|
154 |
|
155 def test_zipfile(self): |
|
156 with temp_dir() as script_dir: |
|
157 script_name = _make_test_script(script_dir, '__main__') |
|
158 zip_name = _make_test_zip(script_dir, 'test_zip', script_name) |
|
159 self._check_script(zip_name, None, zip_name, '') |
|
160 |
|
161 def test_zipfile_compiled(self): |
|
162 with temp_dir() as script_dir: |
|
163 script_name = _make_test_script(script_dir, '__main__') |
|
164 compiled_name = _compile_test_script(script_name) |
|
165 zip_name = _make_test_zip(script_dir, 'test_zip', compiled_name) |
|
166 self._check_script(zip_name, None, zip_name, '') |
|
167 |
|
168 def test_module_in_package(self): |
|
169 with temp_dir() as script_dir: |
|
170 pkg_dir = os.path.join(script_dir, 'test_pkg') |
|
171 _make_test_pkg(pkg_dir) |
|
172 script_name = _make_test_script(pkg_dir, 'script') |
|
173 launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg.script') |
|
174 self._check_script(launch_name, script_name, |
|
175 script_name, 'test_pkg') |
|
176 |
|
177 |
|
178 def test_main(): |
|
179 test.test_support.run_unittest(CmdLineTest) |
|
180 test.test_support.reap_children() |
|
181 |
|
182 if __name__ == '__main__': |
|
183 test_main() |