| """develop tests |
| """ |
| import os |
| import types |
| |
| import pytest |
| |
| import pkg_resources |
| import setuptools.sandbox |
| |
| |
| class TestSandbox: |
| def test_devnull(self, tmpdir): |
| with setuptools.sandbox.DirectorySandbox(str(tmpdir)): |
| self._file_writer(os.devnull) |
| |
| @staticmethod |
| def _file_writer(path): |
| def do_write(): |
| with open(path, 'w') as f: |
| f.write('xxx') |
| |
| return do_write |
| |
| def test_setup_py_with_BOM(self): |
| """ |
| It should be possible to execute a setup.py with a Byte Order Mark |
| """ |
| target = pkg_resources.resource_filename(__name__, |
| 'script-with-bom.py') |
| namespace = types.ModuleType('namespace') |
| setuptools.sandbox._execfile(target, vars(namespace)) |
| assert namespace.result == 'passed' |
| |
| def test_setup_py_with_CRLF(self, tmpdir): |
| setup_py = tmpdir / 'setup.py' |
| with setup_py.open('wb') as stream: |
| stream.write(b'"degenerate script"\r\n') |
| setuptools.sandbox._execfile(str(setup_py), globals()) |
| |
| |
| class TestExceptionSaver: |
| def test_exception_trapped(self): |
| with setuptools.sandbox.ExceptionSaver(): |
| raise ValueError("details") |
| |
| def test_exception_resumed(self): |
| with setuptools.sandbox.ExceptionSaver() as saved_exc: |
| raise ValueError("details") |
| |
| with pytest.raises(ValueError) as caught: |
| saved_exc.resume() |
| |
| assert isinstance(caught.value, ValueError) |
| assert str(caught.value) == 'details' |
| |
| def test_exception_reconstructed(self): |
| orig_exc = ValueError("details") |
| |
| with setuptools.sandbox.ExceptionSaver() as saved_exc: |
| raise orig_exc |
| |
| with pytest.raises(ValueError) as caught: |
| saved_exc.resume() |
| |
| assert isinstance(caught.value, ValueError) |
| assert caught.value is not orig_exc |
| |
| def test_no_exception_passes_quietly(self): |
| with setuptools.sandbox.ExceptionSaver() as saved_exc: |
| pass |
| |
| saved_exc.resume() |
| |
| def test_unpickleable_exception(self): |
| class CantPickleThis(Exception): |
| "This Exception is unpickleable because it's not in globals" |
| def __repr__(self): |
| return 'CantPickleThis%r' % (self.args,) |
| |
| with setuptools.sandbox.ExceptionSaver() as saved_exc: |
| raise CantPickleThis('detail') |
| |
| with pytest.raises(setuptools.sandbox.UnpickleableException) as caught: |
| saved_exc.resume() |
| |
| assert str(caught.value) == "CantPickleThis('detail',)" |
| |
| def test_unpickleable_exception_when_hiding_setuptools(self): |
| """ |
| As revealed in #440, an infinite recursion can occur if an unpickleable |
| exception while setuptools is hidden. Ensure this doesn't happen. |
| """ |
| |
| class ExceptionUnderTest(Exception): |
| """ |
| An unpickleable exception (not in globals). |
| """ |
| |
| with pytest.raises(setuptools.sandbox.UnpickleableException) as caught: |
| with setuptools.sandbox.save_modules(): |
| setuptools.sandbox.hide_setuptools() |
| raise ExceptionUnderTest() |
| |
| msg, = caught.value.args |
| assert msg == 'ExceptionUnderTest()' |
| |
| def test_sandbox_violation_raised_hiding_setuptools(self, tmpdir): |
| """ |
| When in a sandbox with setuptools hidden, a SandboxViolation |
| should reflect a proper exception and not be wrapped in |
| an UnpickleableException. |
| """ |
| |
| def write_file(): |
| "Trigger a SandboxViolation by writing outside the sandbox" |
| with open('/etc/foo', 'w'): |
| pass |
| |
| with pytest.raises(setuptools.sandbox.SandboxViolation) as caught: |
| with setuptools.sandbox.save_modules(): |
| setuptools.sandbox.hide_setuptools() |
| with setuptools.sandbox.DirectorySandbox(str(tmpdir)): |
| write_file() |
| |
| cmd, args, kwargs = caught.value.args |
| assert cmd == 'open' |
| assert args == ('/etc/foo', 'w') |
| assert kwargs == {} |
| |
| msg = str(caught.value) |
| assert 'open' in msg |
| assert "('/etc/foo', 'w')" in msg |