test_spawn.py 5.3 KB

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