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