test_sandbox.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. """develop tests
  2. """
  3. import os
  4. import types
  5. import pytest
  6. import pkg_resources
  7. import setuptools.sandbox
  8. class TestSandbox:
  9. def test_devnull(self, tmpdir):
  10. with setuptools.sandbox.DirectorySandbox(str(tmpdir)):
  11. self._file_writer(os.devnull)
  12. @staticmethod
  13. def _file_writer(path):
  14. def do_write():
  15. with open(path, 'w') as f:
  16. f.write('xxx')
  17. return do_write
  18. def test_setup_py_with_BOM(self):
  19. """
  20. It should be possible to execute a setup.py with a Byte Order Mark
  21. """
  22. target = pkg_resources.resource_filename(
  23. __name__,
  24. 'script-with-bom.py')
  25. namespace = types.ModuleType('namespace')
  26. setuptools.sandbox._execfile(target, vars(namespace))
  27. assert namespace.result == 'passed'
  28. def test_setup_py_with_CRLF(self, tmpdir):
  29. setup_py = tmpdir / 'setup.py'
  30. with setup_py.open('wb') as stream:
  31. stream.write(b'"degenerate script"\r\n')
  32. setuptools.sandbox._execfile(str(setup_py), globals())
  33. class TestExceptionSaver:
  34. def test_exception_trapped(self):
  35. with setuptools.sandbox.ExceptionSaver():
  36. raise ValueError("details")
  37. def test_exception_resumed(self):
  38. with setuptools.sandbox.ExceptionSaver() as saved_exc:
  39. raise ValueError("details")
  40. with pytest.raises(ValueError) as caught:
  41. saved_exc.resume()
  42. assert isinstance(caught.value, ValueError)
  43. assert str(caught.value) == 'details'
  44. def test_exception_reconstructed(self):
  45. orig_exc = ValueError("details")
  46. with setuptools.sandbox.ExceptionSaver() as saved_exc:
  47. raise orig_exc
  48. with pytest.raises(ValueError) as caught:
  49. saved_exc.resume()
  50. assert isinstance(caught.value, ValueError)
  51. assert caught.value is not orig_exc
  52. def test_no_exception_passes_quietly(self):
  53. with setuptools.sandbox.ExceptionSaver() as saved_exc:
  54. pass
  55. saved_exc.resume()
  56. def test_unpickleable_exception(self):
  57. class CantPickleThis(Exception):
  58. "This Exception is unpickleable because it's not in globals"
  59. def __repr__(self):
  60. return 'CantPickleThis%r' % (self.args,)
  61. with setuptools.sandbox.ExceptionSaver() as saved_exc:
  62. raise CantPickleThis('detail')
  63. with pytest.raises(setuptools.sandbox.UnpickleableException) as caught:
  64. saved_exc.resume()
  65. assert str(caught.value) == "CantPickleThis('detail',)"
  66. def test_unpickleable_exception_when_hiding_setuptools(self):
  67. """
  68. As revealed in #440, an infinite recursion can occur if an unpickleable
  69. exception while setuptools is hidden. Ensure this doesn't happen.
  70. """
  71. class ExceptionUnderTest(Exception):
  72. """
  73. An unpickleable exception (not in globals).
  74. """
  75. with pytest.raises(setuptools.sandbox.UnpickleableException) as caught:
  76. with setuptools.sandbox.save_modules():
  77. setuptools.sandbox.hide_setuptools()
  78. raise ExceptionUnderTest()
  79. msg, = caught.value.args
  80. assert msg == 'ExceptionUnderTest()'
  81. def test_sandbox_violation_raised_hiding_setuptools(self, tmpdir):
  82. """
  83. When in a sandbox with setuptools hidden, a SandboxViolation
  84. should reflect a proper exception and not be wrapped in
  85. an UnpickleableException.
  86. """
  87. def write_file():
  88. "Trigger a SandboxViolation by writing outside the sandbox"
  89. with open('/etc/foo', 'w'):
  90. pass
  91. with pytest.raises(setuptools.sandbox.SandboxViolation) as caught:
  92. with setuptools.sandbox.save_modules():
  93. setuptools.sandbox.hide_setuptools()
  94. with setuptools.sandbox.DirectorySandbox(str(tmpdir)):
  95. write_file()
  96. cmd, args, kwargs = caught.value.args
  97. assert cmd == 'open'
  98. assert args == ('/etc/foo', 'w')
  99. assert kwargs == {}
  100. msg = str(caught.value)
  101. assert 'open' in msg
  102. assert "('/etc/foo', 'w')" in msg