test_spawn.py 5.4 KB

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