blob: e0b09ea8ee53e6fc1a64fc06432b43e5940128f5 [file] [log] [blame]
Christian Heimes9cd17752007-11-18 19:35:23 +00001# Tests command line execution of scripts
Christian Heimes9cd17752007-11-18 19:35:23 +00002
3import unittest
4import os
5import os.path
6import sys
Benjamin Petersonee8712c2008-05-20 21:35:26 +00007import test.support
Christian Heimes9cd17752007-11-18 19:35:23 +00008import tempfile
9import subprocess
10import py_compile
11import contextlib
12import shutil
13import zipfile
14
Benjamin Petersonee8712c2008-05-20 21:35:26 +000015verbose = test.support.verbose
Christian Heimes9cd17752007-11-18 19:35:23 +000016
Benjamin Petersonee8712c2008-05-20 21:35:26 +000017# XXX ncoghlan: Should we consider moving these to support?
Guido van Rossum87afcbf2007-11-19 15:56:44 +000018from test.test_cmd_line import _spawn_python, _kill_python
Christian Heimes9cd17752007-11-18 19:35:23 +000019
20def _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.decode()
27
28@contextlib.contextmanager
29def temp_dir():
30 dirname = tempfile.mkdtemp()
Guido van Rossum87c0f1d2007-11-19 18:03:44 +000031 dirname = os.path.realpath(dirname)
Christian Heimes9cd17752007-11-18 19:35:23 +000032 try:
33 yield dirname
34 finally:
35 shutil.rmtree(dirname)
36
Christian Heimescbf3b5c2007-12-03 21:02:03 +000037test_source = """\
Christian Heimes9cd17752007-11-18 19:35:23 +000038# Script may be run with optimisation enabled, so don't rely on assert
39# statements being executed
40def assertEqual(lhs, rhs):
41 if lhs != rhs:
Christian Heimescbf3b5c2007-12-03 21:02:03 +000042 raise AssertionError('%r != %r' % (lhs, rhs))
Christian Heimes9cd17752007-11-18 19:35:23 +000043def assertIdentical(lhs, rhs):
44 if lhs is not rhs:
Christian Heimescbf3b5c2007-12-03 21:02:03 +000045 raise AssertionError('%r is not %r' % (lhs, rhs))
Christian Heimes9cd17752007-11-18 19:35:23 +000046# Check basic code execution
47result = ['Top level assignment']
48def f():
49 result.append('Lower level reference')
50f()
51assertEqual(result, ['Top level assignment', 'Lower level reference'])
52# Check population of magic variables
53assertEqual(__name__, '__main__')
54print('__file__==%r' % __file__)
Christian Heimescbf3b5c2007-12-03 21:02:03 +000055print('__package__==%r' % __package__)
Christian Heimes9cd17752007-11-18 19:35:23 +000056# Check the sys module
57import sys
58assertIdentical(globals(), sys.modules[__name__].__dict__)
59print('sys.argv[0]==%r' % sys.argv[0])
Christian Heimescbf3b5c2007-12-03 21:02:03 +000060"""
Christian Heimes9cd17752007-11-18 19:35:23 +000061
Christian Heimescbf3b5c2007-12-03 21:02:03 +000062def _make_test_script(script_dir, script_basename, source=test_source):
63 script_filename = script_basename+os.path.extsep+'py'
Christian Heimes9cd17752007-11-18 19:35:23 +000064 script_name = os.path.join(script_dir, script_filename)
Christian Heimescbf3b5c2007-12-03 21:02:03 +000065 script_file = open(script_name, 'w')
66 script_file.write(source)
Christian Heimes9cd17752007-11-18 19:35:23 +000067 script_file.close()
68 return script_name
69
70def _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
78def _make_test_zip(zip_dir, zip_basename, script_name):
79 zip_filename = zip_basename+os.path.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')
Guido van Rossum87c0f1d2007-11-19 18:03:44 +000086 # print("Contents of %r:" % zip_name)
Christian Heimes9cd17752007-11-18 19:35:23 +000087 # zip_file.printdir()
88 # zip_file.close()
89 return zip_name
90
Christian Heimescbf3b5c2007-12-03 21:02:03 +000091def _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
99launch_source = """\
100import sys, os.path, runpy
101sys.path[0:0] = os.path.dirname(__file__)
102runpy._run_module_as_main(%r)
103"""
104
105def _make_launch_script(script_dir, script_basename, module_name):
106 return _make_test_script(script_dir, script_basename,
107 launch_source % module_name)
108
Christian Heimes9cd17752007-11-18 19:35:23 +0000109class CmdLineTest(unittest.TestCase):
Christian Heimescbf3b5c2007-12-03 21:02:03 +0000110 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)
Guido van Rossum87c0f1d2007-11-19 18:03:44 +0000115 if verbose:
116 print("Output from test script %r:" % script_name)
117 print(data)
Christian Heimescbf3b5c2007-12-03 21:02:03 +0000118 self.assertEqual(exit_code, 0)
Christian Heimes9cd17752007-11-18 19:35:23 +0000119 printed_file = '__file__==%r' % expected_file
120 printed_argv0 = 'sys.argv[0]==%r' % expected_argv0
Christian Heimescbf3b5c2007-12-03 21:02:03 +0000121 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)
Christian Heimes9cd17752007-11-18 19:35:23 +0000130
131 def test_basic_script(self):
132 with temp_dir() as script_dir:
Christian Heimescbf3b5c2007-12-03 21:02:03 +0000133 script_name = _make_test_script(script_dir, 'script')
134 self._check_script(script_name, script_name, script_name, None)
Christian Heimes9cd17752007-11-18 19:35:23 +0000135
136 def test_script_compiled(self):
137 with temp_dir() as script_dir:
Christian Heimescbf3b5c2007-12-03 21:02:03 +0000138 script_name = _make_test_script(script_dir, 'script')
Christian Heimes9cd17752007-11-18 19:35:23 +0000139 compiled_name = _compile_test_script(script_name)
140 os.remove(script_name)
Christian Heimescbf3b5c2007-12-03 21:02:03 +0000141 self._check_script(compiled_name, compiled_name, compiled_name, None)
Christian Heimes9cd17752007-11-18 19:35:23 +0000142
143 def test_directory(self):
144 with temp_dir() as script_dir:
Christian Heimescbf3b5c2007-12-03 21:02:03 +0000145 script_name = _make_test_script(script_dir, '__main__')
146 self._check_script(script_dir, script_name, script_dir, '')
Christian Heimes9cd17752007-11-18 19:35:23 +0000147
148 def test_directory_compiled(self):
149 with temp_dir() as script_dir:
Christian Heimescbf3b5c2007-12-03 21:02:03 +0000150 script_name = _make_test_script(script_dir, '__main__')
Christian Heimes9cd17752007-11-18 19:35:23 +0000151 compiled_name = _compile_test_script(script_name)
152 os.remove(script_name)
Christian Heimescbf3b5c2007-12-03 21:02:03 +0000153 self._check_script(script_dir, compiled_name, script_dir, '')
Christian Heimes9cd17752007-11-18 19:35:23 +0000154
155 def test_zipfile(self):
156 with temp_dir() as script_dir:
Christian Heimescbf3b5c2007-12-03 21:02:03 +0000157 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, '')
Christian Heimes9cd17752007-11-18 19:35:23 +0000160
161 def test_zipfile_compiled(self):
162 with temp_dir() as script_dir:
Christian Heimescbf3b5c2007-12-03 21:02:03 +0000163 script_name = _make_test_script(script_dir, '__main__')
Christian Heimes9cd17752007-11-18 19:35:23 +0000164 compiled_name = _compile_test_script(script_name)
Christian Heimescbf3b5c2007-12-03 21:02:03 +0000165 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')
Christian Heimes9cd17752007-11-18 19:35:23 +0000176
177
178def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000179 test.support.run_unittest(CmdLineTest)
180 test.support.reap_children()
Christian Heimes9cd17752007-11-18 19:35:23 +0000181
Christian Heimescbf3b5c2007-12-03 21:02:03 +0000182if __name__ == '__main__':
Christian Heimes9cd17752007-11-18 19:35:23 +0000183 test_main()