Home | History | Annotate | Download | only in test
      1 # Tests command line execution of scripts

      2 
      3 import unittest
      4 import os
      5 import os.path
      6 import test.test_support
      7 from test.script_helper import (run_python,
      8                                 temp_dir, make_script, compile_script,
      9                                 make_pkg, make_zip_script, make_zip_pkg)
     10 
     11 verbose = test.test_support.verbose
     12 
     13 
     14 test_source = """\
     15 # Script may be run with optimisation enabled, so don't rely on assert
     16 # statements being executed
     17 def assertEqual(lhs, rhs):
     18     if lhs != rhs:
     19         raise AssertionError('%r != %r' % (lhs, rhs))
     20 def assertIdentical(lhs, rhs):
     21     if lhs is not rhs:
     22         raise AssertionError('%r is not %r' % (lhs, rhs))
     23 # Check basic code execution
     24 result = ['Top level assignment']
     25 def f():
     26     result.append('Lower level reference')
     27 f()
     28 assertEqual(result, ['Top level assignment', 'Lower level reference'])
     29 # Check population of magic variables
     30 assertEqual(__name__, '__main__')
     31 print '__file__==%r' % __file__
     32 print '__package__==%r' % __package__
     33 # Check the sys module
     34 import sys
     35 assertIdentical(globals(), sys.modules[__name__].__dict__)
     36 print 'sys.argv[0]==%r' % sys.argv[0]
     37 """
     38 
     39 def _make_test_script(script_dir, script_basename, source=test_source):
     40     return make_script(script_dir, script_basename, source)
     41 
     42 def _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

     51 launch_source = """\
     52 import sys, os.path, runpy
     53 sys.path.insert(0, %s)
     54 runpy._run_module_as_main(%r)
     55 """
     56 
     57 def _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 
     65 class 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 
    208 def test_main():
    209     test.test_support.run_unittest(CmdLineTest)
    210     test.test_support.reap_children()
    211 
    212 if __name__ == '__main__':
    213     test_main()
    214