1"""Tests for distutils.spawn.""" 2import os 3import stat 4import sys 5import unittest 6from unittest import mock 7from test.support import run_unittest, unix_shell 8from test import support as test_support 9 10from distutils.spawn import find_executable 11from distutils.spawn import _nt_quote_args 12from distutils.spawn import spawn 13from distutils.errors import DistutilsExecError 14from distutils.tests import support 15 16class SpawnTestCase(support.TempdirManager, 17 support.LoggingSilencer, 18 unittest.TestCase): 19 20 def test_nt_quote_args(self): 21 22 for (args, wanted) in ((['with space', 'nospace'], 23 ['"with space"', 'nospace']), 24 (['nochange', 'nospace'], 25 ['nochange', 'nospace'])): 26 res = _nt_quote_args(args) 27 self.assertEqual(res, wanted) 28 29 30 @unittest.skipUnless(os.name in ('nt', 'posix'), 31 'Runs only under posix or nt') 32 def test_spawn(self): 33 tmpdir = self.mkdtemp() 34 35 # creating something executable 36 # through the shell that returns 1 37 if sys.platform != 'win32': 38 exe = os.path.join(tmpdir, 'foo.sh') 39 self.write_file(exe, '#!%s\nexit 1' % unix_shell) 40 else: 41 exe = os.path.join(tmpdir, 'foo.bat') 42 self.write_file(exe, 'exit 1') 43 44 os.chmod(exe, 0o777) 45 self.assertRaises(DistutilsExecError, spawn, [exe]) 46 47 # now something that works 48 if sys.platform != 'win32': 49 exe = os.path.join(tmpdir, 'foo.sh') 50 self.write_file(exe, '#!%s\nexit 0' % unix_shell) 51 else: 52 exe = os.path.join(tmpdir, 'foo.bat') 53 self.write_file(exe, 'exit 0') 54 55 os.chmod(exe, 0o777) 56 spawn([exe]) # should work without any error 57 58 def test_find_executable(self): 59 with test_support.temp_dir() as tmp_dir: 60 # use TESTFN to get a pseudo-unique filename 61 program_noeext = test_support.TESTFN 62 # Give the temporary program an ".exe" suffix for all. 63 # It's needed on Windows and not harmful on other platforms. 64 program = program_noeext + ".exe" 65 66 filename = os.path.join(tmp_dir, program) 67 with open(filename, "wb"): 68 pass 69 os.chmod(filename, stat.S_IXUSR) 70 71 # test path parameter 72 rv = find_executable(program, path=tmp_dir) 73 self.assertEqual(rv, filename) 74 75 if sys.platform == 'win32': 76 # test without ".exe" extension 77 rv = find_executable(program_noeext, path=tmp_dir) 78 self.assertEqual(rv, filename) 79 80 # test find in the current directory 81 with test_support.change_cwd(tmp_dir): 82 rv = find_executable(program) 83 self.assertEqual(rv, program) 84 85 # test non-existent program 86 dont_exist_program = "dontexist_" + program 87 rv = find_executable(dont_exist_program , path=tmp_dir) 88 self.assertIsNone(rv) 89 90 # PATH='': no match, except in the current directory 91 with test_support.EnvironmentVarGuard() as env: 92 env['PATH'] = '' 93 with unittest.mock.patch('distutils.spawn.os.confstr', 94 return_value=tmp_dir, create=True), \ 95 unittest.mock.patch('distutils.spawn.os.defpath', 96 tmp_dir): 97 rv = find_executable(program) 98 self.assertIsNone(rv) 99 100 # look in current directory 101 with test_support.change_cwd(tmp_dir): 102 rv = find_executable(program) 103 self.assertEqual(rv, program) 104 105 # PATH=':': explicitly looks in the current directory 106 with test_support.EnvironmentVarGuard() as env: 107 env['PATH'] = os.pathsep 108 with unittest.mock.patch('distutils.spawn.os.confstr', 109 return_value='', create=True), \ 110 unittest.mock.patch('distutils.spawn.os.defpath', ''): 111 rv = find_executable(program) 112 self.assertIsNone(rv) 113 114 # look in current directory 115 with test_support.change_cwd(tmp_dir): 116 rv = find_executable(program) 117 self.assertEqual(rv, program) 118 119 # missing PATH: test os.confstr("CS_PATH") and os.defpath 120 with test_support.EnvironmentVarGuard() as env: 121 env.pop('PATH', None) 122 123 # without confstr 124 with unittest.mock.patch('distutils.spawn.os.confstr', 125 side_effect=ValueError, 126 create=True), \ 127 unittest.mock.patch('distutils.spawn.os.defpath', 128 tmp_dir): 129 rv = find_executable(program) 130 self.assertEqual(rv, filename) 131 132 # with confstr 133 with unittest.mock.patch('distutils.spawn.os.confstr', 134 return_value=tmp_dir, create=True), \ 135 unittest.mock.patch('distutils.spawn.os.defpath', ''): 136 rv = find_executable(program) 137 self.assertEqual(rv, filename) 138 139 140def test_suite(): 141 return unittest.makeSuite(SpawnTestCase) 142 143if __name__ == "__main__": 144 run_unittest(test_suite()) 145