1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
|
"""develop tests
"""
import os
import types
import pytest
import pkg_resources
import setuptools.sandbox
from setuptools.sandbox import DirectorySandbox
class TestSandbox:
def test_devnull(self, tmpdir):
sandbox = DirectorySandbox(str(tmpdir))
sandbox.run(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"
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
sandbox = DirectorySandbox(str(tmpdir))
with pytest.raises(setuptools.sandbox.SandboxViolation) as caught:
with setuptools.sandbox.save_modules():
setuptools.sandbox.hide_setuptools()
sandbox.run(write_file)
cmd, args, kwargs = caught.value.args
assert cmd == 'open'
assert args == ('/etc/foo', 'w')
assert kwargs == {}
|