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( 30 __name__, 31 'script-with-bom.py') 32 namespace = types.ModuleType('namespace') 33 setuptools.sandbox._execfile(target, vars(namespace)) 34 assert namespace.result == 'passed' 35 36 def test_setup_py_with_CRLF(self, tmpdir): 37 setup_py = tmpdir / 'setup.py' 38 with setup_py.open('wb') as stream: 39 stream.write(b'"degenerate script"\r\n') 40 setuptools.sandbox._execfile(str(setup_py), globals()) 41 42 43class TestExceptionSaver: 44 def test_exception_trapped(self): 45 with setuptools.sandbox.ExceptionSaver(): 46 raise ValueError("details") 47 48 def test_exception_resumed(self): 49 with setuptools.sandbox.ExceptionSaver() as saved_exc: 50 raise ValueError("details") 51 52 with pytest.raises(ValueError) as caught: 53 saved_exc.resume() 54 55 assert isinstance(caught.value, ValueError) 56 assert str(caught.value) == 'details' 57 58 def test_exception_reconstructed(self): 59 orig_exc = ValueError("details") 60 61 with setuptools.sandbox.ExceptionSaver() as saved_exc: 62 raise orig_exc 63 64 with pytest.raises(ValueError) as caught: 65 saved_exc.resume() 66 67 assert isinstance(caught.value, ValueError) 68 assert caught.value is not orig_exc 69 70 def test_no_exception_passes_quietly(self): 71 with setuptools.sandbox.ExceptionSaver() as saved_exc: 72 pass 73 74 saved_exc.resume() 75 76 def test_unpickleable_exception(self): 77 class CantPickleThis(Exception): 78 "This Exception is unpickleable because it's not in globals" 79 def __repr__(self): 80 return 'CantPickleThis%r' % (self.args,) 81 82 with setuptools.sandbox.ExceptionSaver() as saved_exc: 83 raise CantPickleThis('detail') 84 85 with pytest.raises(setuptools.sandbox.UnpickleableException) as caught: 86 saved_exc.resume() 87 88 assert str(caught.value) == "CantPickleThis('detail',)" 89 90 def test_unpickleable_exception_when_hiding_setuptools(self): 91 """ 92 As revealed in #440, an infinite recursion can occur if an unpickleable 93 exception while setuptools is hidden. Ensure this doesn't happen. 94 """ 95 96 class ExceptionUnderTest(Exception): 97 """ 98 An unpickleable exception (not in globals). 99 """ 100 101 with pytest.raises(setuptools.sandbox.UnpickleableException) as caught: 102 with setuptools.sandbox.save_modules(): 103 setuptools.sandbox.hide_setuptools() 104 raise ExceptionUnderTest() 105 106 msg, = caught.value.args 107 assert msg == 'ExceptionUnderTest()' 108 109 def test_sandbox_violation_raised_hiding_setuptools(self, tmpdir): 110 """ 111 When in a sandbox with setuptools hidden, a SandboxViolation 112 should reflect a proper exception and not be wrapped in 113 an UnpickleableException. 114 """ 115 116 def write_file(): 117 "Trigger a SandboxViolation by writing outside the sandbox" 118 with open('/etc/foo', 'w'): 119 pass 120 121 with pytest.raises(setuptools.sandbox.SandboxViolation) as caught: 122 with setuptools.sandbox.save_modules(): 123 setuptools.sandbox.hide_setuptools() 124 with setuptools.sandbox.DirectorySandbox(str(tmpdir)): 125 write_file() 126 127 cmd, args, kwargs = caught.value.args 128 assert cmd == 'open' 129 assert args == ('/etc/foo', 'w') 130 assert kwargs == {} 131 132 msg = str(caught.value) 133 assert 'open' in msg 134 assert "('/etc/foo', 'w')" in msg 135