test_spawn.py 5.5 KB

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