1# Tests command line execution of scripts 2 3import unittest 4import os 5import os.path 6import test.test_support 7from test.script_helper import (run_python, 8 temp_dir, make_script, compile_script, 9 make_pkg, make_zip_script, make_zip_pkg) 10 11verbose = test.test_support.verbose 12 13 14test_source = """\ 15# Script may be run with optimisation enabled, so don't rely on assert 16# statements being executed 17def assertEqual(lhs, rhs): 18 if lhs != rhs: 19 raise AssertionError('%r != %r' % (lhs, rhs)) 20def assertIdentical(lhs, rhs): 21 if lhs is not rhs: 22 raise AssertionError('%r is not %r' % (lhs, rhs)) 23# Check basic code execution 24result = ['Top level assignment'] 25def f(): 26 result.append('Lower level reference') 27f() 28assertEqual(result, ['Top level assignment', 'Lower level reference']) 29# Check population of magic variables 30assertEqual(__name__, '__main__') 31print '__file__==%r' % __file__ 32print '__package__==%r' % __package__ 33# Check the sys module 34import sys 35assertIdentical(globals(), sys.modules[__name__].__dict__) 36print 'sys.argv[0]==%r' % sys.argv[0] 37""" 38 39def _make_test_script(script_dir, script_basename, source=test_source): 40 return make_script(script_dir, script_basename, source) 41 42def _make_test_zip_pkg(zip_dir, zip_basename, pkg_name, script_basename, 43 source=test_source, depth=1): 44 return make_zip_pkg(zip_dir, zip_basename, pkg_name, script_basename, 45 source, depth) 46 47# There's no easy way to pass the script directory in to get 48# -m to work (avoiding that is the whole point of making 49# directories and zipfiles executable!) 50# So we fake it for testing purposes with a custom launch script 51launch_source = """\ 52import sys, os.path, runpy 53sys.path.insert(0, %s) 54runpy._run_module_as_main(%r) 55""" 56 57def _make_launch_script(script_dir, script_basename, module_name, path=None): 58 if path is None: 59 path = "os.path.dirname(__file__)" 60 else: 61 path = repr(path) 62 source = launch_source % (path, module_name) 63 return make_script(script_dir, script_basename, source) 64 65class CmdLineTest(unittest.TestCase): 66 def _check_script(self, script_name, expected_file, 67 expected_argv0, expected_package, 68 *cmd_line_switches): 69 run_args = cmd_line_switches + (script_name,) 70 exit_code, data = run_python(*run_args) 71 if verbose: 72 print 'Output from test script %r:' % script_name 73 print data 74 self.assertEqual(exit_code, 0) 75 printed_file = '__file__==%r' % expected_file 76 printed_argv0 = 'sys.argv[0]==%r' % expected_argv0 77 printed_package = '__package__==%r' % expected_package 78 if verbose: 79 print 'Expected output:' 80 print printed_file 81 print printed_package 82 print printed_argv0 83 self.assertIn(printed_file, data) 84 self.assertIn(printed_package, data) 85 self.assertIn(printed_argv0, data) 86 87 def _check_import_error(self, script_name, expected_msg, 88 *cmd_line_switches): 89 run_args = cmd_line_switches + (script_name,) 90 exit_code, data = run_python(*run_args) 91 if verbose: 92 print 'Output from test script %r:' % script_name 93 print data 94 print 'Expected output: %r' % expected_msg 95 self.assertIn(expected_msg, data) 96 97 def test_basic_script(self): 98 with temp_dir() as script_dir: 99 script_name = _make_test_script(script_dir, 'script') 100 self._check_script(script_name, script_name, script_name, None) 101 102 def test_script_compiled(self): 103 with temp_dir() as script_dir: 104 script_name = _make_test_script(script_dir, 'script') 105 compiled_name = compile_script(script_name) 106 os.remove(script_name) 107 self._check_script(compiled_name, compiled_name, compiled_name, None) 108 109 def test_directory(self): 110 with temp_dir() as script_dir: 111 script_name = _make_test_script(script_dir, '__main__') 112 self._check_script(script_dir, script_name, script_dir, '') 113 114 def test_directory_compiled(self): 115 with temp_dir() as script_dir: 116 script_name = _make_test_script(script_dir, '__main__') 117 compiled_name = compile_script(script_name) 118 os.remove(script_name) 119 self._check_script(script_dir, compiled_name, script_dir, '') 120 121 def test_directory_error(self): 122 with temp_dir() as script_dir: 123 msg = "can't find '__main__' module in %r" % script_dir 124 self._check_import_error(script_dir, msg) 125 126 def test_zipfile(self): 127 with temp_dir() as script_dir: 128 script_name = _make_test_script(script_dir, '__main__') 129 zip_name, run_name = make_zip_script(script_dir, 'test_zip', script_name) 130 self._check_script(zip_name, run_name, zip_name, '') 131 132 def test_zipfile_compiled(self): 133 with temp_dir() as script_dir: 134 script_name = _make_test_script(script_dir, '__main__') 135 compiled_name = compile_script(script_name) 136 zip_name, run_name = make_zip_script(script_dir, 'test_zip', compiled_name) 137 self._check_script(zip_name, run_name, zip_name, '') 138 139 def test_zipfile_error(self): 140 with temp_dir() as script_dir: 141 script_name = _make_test_script(script_dir, 'not_main') 142 zip_name, run_name = make_zip_script(script_dir, 'test_zip', script_name) 143 msg = "can't find '__main__' module in %r" % zip_name 144 self._check_import_error(zip_name, msg) 145 146 def test_module_in_package(self): 147 with temp_dir() as script_dir: 148 pkg_dir = os.path.join(script_dir, 'test_pkg') 149 make_pkg(pkg_dir) 150 script_name = _make_test_script(pkg_dir, 'script') 151 launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg.script') 152 self._check_script(launch_name, script_name, script_name, 'test_pkg') 153 154 def test_module_in_package_in_zipfile(self): 155 with temp_dir() as script_dir: 156 zip_name, run_name = _make_test_zip_pkg(script_dir, 'test_zip', 'test_pkg', 'script') 157 launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg.script', zip_name) 158 self._check_script(launch_name, run_name, run_name, 'test_pkg') 159 160 def test_module_in_subpackage_in_zipfile(self): 161 with temp_dir() as script_dir: 162 zip_name, run_name = _make_test_zip_pkg(script_dir, 'test_zip', 'test_pkg', 'script', depth=2) 163 launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg.test_pkg.script', zip_name) 164 self._check_script(launch_name, run_name, run_name, 'test_pkg.test_pkg') 165 166 def test_package(self): 167 with temp_dir() as script_dir: 168 pkg_dir = os.path.join(script_dir, 'test_pkg') 169 make_pkg(pkg_dir) 170 script_name = _make_test_script(pkg_dir, '__main__') 171 launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg') 172 self._check_script(launch_name, script_name, 173 script_name, 'test_pkg') 174 175 def test_package_compiled(self): 176 with temp_dir() as script_dir: 177 pkg_dir = os.path.join(script_dir, 'test_pkg') 178 make_pkg(pkg_dir) 179 script_name = _make_test_script(pkg_dir, '__main__') 180 compiled_name = compile_script(script_name) 181 os.remove(script_name) 182 launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg') 183 self._check_script(launch_name, compiled_name, 184 compiled_name, 'test_pkg') 185 186 def test_package_error(self): 187 with temp_dir() as script_dir: 188 pkg_dir = os.path.join(script_dir, 'test_pkg') 189 make_pkg(pkg_dir) 190 msg = ("'test_pkg' is a package and cannot " 191 "be directly executed") 192 launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg') 193 self._check_import_error(launch_name, msg) 194 195 def test_package_recursion(self): 196 with temp_dir() as script_dir: 197 pkg_dir = os.path.join(script_dir, 'test_pkg') 198 make_pkg(pkg_dir) 199 main_dir = os.path.join(pkg_dir, '__main__') 200 make_pkg(main_dir) 201 msg = ("Cannot use package as __main__ module; " 202 "'test_pkg' is a package and cannot " 203 "be directly executed") 204 launch_name = _make_launch_script(script_dir, 'launch', 'test_pkg') 205 self._check_import_error(launch_name, msg) 206 207 208def test_main(): 209 test.test_support.run_unittest(CmdLineTest) 210 test.test_support.reap_children() 211 212if __name__ == '__main__': 213 test_main() 214