PageRenderTime 42ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/pypy/translator/sandbox/test/test_sandbox.py

https://bitbucket.org/pypy/pypy/
Python | 302 lines | 296 code | 6 blank | 0 comment | 2 complexity | 88d2b9f5bb6474d7991f3904b884cf47 MD5 | raw file
Possible License(s): AGPL-3.0, BSD-3-Clause, Apache-2.0
  1. import py
  2. import sys, os, time
  3. import struct
  4. import subprocess
  5. from pypy.rpython.lltypesystem import rffi
  6. from pypy.translator.interactive import Translation
  7. from pypy.translator.sandbox.sandlib import read_message, write_message
  8. from pypy.translator.sandbox.sandlib import write_exception
  9. def expect(f, g, fnname, args, result, resulttype=None):
  10. msg = read_message(f, timeout=10.0)
  11. assert msg == fnname
  12. msg = read_message(f, timeout=10.0)
  13. assert msg == args
  14. if isinstance(result, Exception):
  15. write_exception(g, result)
  16. else:
  17. write_message(g, 0)
  18. write_message(g, result, resulttype)
  19. g.flush()
  20. def compile(f, gc='ref'):
  21. t = Translation(f, backend='c', standalone=True, sandbox=True, gc=gc)
  22. return str(t.compile())
  23. def test_open_dup():
  24. def entry_point(argv):
  25. fd = os.open("/tmp/foobar", os.O_RDONLY, 0777)
  26. assert fd == 77
  27. fd2 = os.dup(fd)
  28. assert fd2 == 78
  29. return 0
  30. exe = compile(entry_point)
  31. g, f = os.popen2(exe, "t", 0)
  32. expect(f, g, "ll_os.ll_os_open", ("/tmp/foobar", os.O_RDONLY, 0777), 77)
  33. expect(f, g, "ll_os.ll_os_dup", (77,), 78)
  34. g.close()
  35. tail = f.read()
  36. f.close()
  37. assert tail == ""
  38. def test_read_write():
  39. def entry_point(argv):
  40. fd = os.open("/tmp/foobar", os.O_RDONLY, 0777)
  41. assert fd == 77
  42. res = os.read(fd, 123)
  43. assert res == "he\x00llo"
  44. count = os.write(fd, "world\x00!\x00")
  45. assert count == 42
  46. os.close(fd)
  47. return 0
  48. exe = compile(entry_point)
  49. g, f = os.popen2(exe, "t", 0)
  50. expect(f, g, "ll_os.ll_os_open", ("/tmp/foobar", os.O_RDONLY, 0777), 77)
  51. expect(f, g, "ll_os.ll_os_read", (77, 123), "he\x00llo")
  52. expect(f, g, "ll_os.ll_os_write", (77, "world\x00!\x00"), 42)
  53. expect(f, g, "ll_os.ll_os_close", (77,), None)
  54. g.close()
  55. tail = f.read()
  56. f.close()
  57. assert tail == ""
  58. def test_dup2_access():
  59. def entry_point(argv):
  60. os.dup2(34, 56)
  61. y = os.access("spam", 77)
  62. return 1 - y
  63. exe = compile(entry_point)
  64. g, f = os.popen2(exe, "t", 0)
  65. expect(f, g, "ll_os.ll_os_dup2", (34, 56), None)
  66. expect(f, g, "ll_os.ll_os_access", ("spam", 77), True)
  67. g.close()
  68. tail = f.read()
  69. f.close()
  70. assert tail == ""
  71. def test_stat_ftruncate():
  72. from pypy.translator.sandbox.sandlib import RESULTTYPE_STATRESULT
  73. from pypy.rlib.rarithmetic import r_longlong
  74. r0x12380000007 = r_longlong(0x12380000007)
  75. def entry_point(argv):
  76. st = os.stat("somewhere")
  77. os.ftruncate(st.st_mode, st.st_size) # nonsense, just to see outside
  78. return 0
  79. exe = compile(entry_point)
  80. g, f = os.popen2(exe, "t", 0)
  81. st = os.stat_result((55, 0, 0, 0, 0, 0, 0x12380000007, 0, 0, 0))
  82. expect(f, g, "ll_os.ll_os_stat", ("somewhere",), st,
  83. resulttype = RESULTTYPE_STATRESULT)
  84. expect(f, g, "ll_os.ll_os_ftruncate", (55, 0x12380000007), None)
  85. g.close()
  86. tail = f.read()
  87. f.close()
  88. assert tail == ""
  89. def test_time():
  90. def entry_point(argv):
  91. t = time.time()
  92. os.dup(int(t*1000))
  93. return 0
  94. exe = compile(entry_point)
  95. g, f = os.popen2(exe, "t", 0)
  96. expect(f, g, "ll_time.ll_time_time", (), 3.141592)
  97. expect(f, g, "ll_os.ll_os_dup", (3141,), 3)
  98. g.close()
  99. tail = f.read()
  100. f.close()
  101. assert tail == ""
  102. def test_oserror():
  103. def entry_point(argv):
  104. try:
  105. os.stat("somewhere")
  106. except OSError, e:
  107. os.close(e.errno) # nonsense, just to see outside
  108. return 0
  109. exe = compile(entry_point)
  110. g, f = os.popen2(exe, "t", 0)
  111. expect(f, g, "ll_os.ll_os_stat", ("somewhere",), OSError(6321, "egg"))
  112. expect(f, g, "ll_os.ll_os_close", (6321,), None)
  113. g.close()
  114. tail = f.read()
  115. f.close()
  116. assert tail == ""
  117. def test_hybrid_gc():
  118. def entry_point(argv):
  119. l = []
  120. for i in range(int(argv[1])):
  121. l.append("x" * int(argv[2]))
  122. return int(len(l) > 1000)
  123. exe = compile(entry_point, gc='hybrid')
  124. pipe = subprocess.Popen([exe, '10', '10000'], stdout=subprocess.PIPE,
  125. stdin=subprocess.PIPE)
  126. g = pipe.stdin
  127. f = pipe.stdout
  128. expect(f, g, "ll_os.ll_os_getenv", ("PYPY_GENERATIONGC_NURSERY",), None)
  129. if sys.platform.startswith('linux'): # on Mac, uses another (sandboxsafe) approach
  130. expect(f, g, "ll_os.ll_os_open", ("/proc/cpuinfo", 0, 420),
  131. OSError(5232, "xyz"))
  132. expect(f, g, "ll_os.ll_os_getenv", ("PYPY_GC_DEBUG",), None)
  133. g.close()
  134. tail = f.read()
  135. f.close()
  136. assert tail == ""
  137. rescode = pipe.wait()
  138. assert rescode == 0
  139. def test_segfault_1():
  140. class A:
  141. def __init__(self, m):
  142. self.m = m
  143. def g(m):
  144. if m < 10:
  145. return None
  146. return A(m)
  147. def entry_point(argv):
  148. x = g(len(argv))
  149. return int(x.m)
  150. exe = compile(entry_point)
  151. g, f, e = os.popen3(exe, "t", 0)
  152. g.close()
  153. tail = f.read()
  154. f.close()
  155. assert tail == ""
  156. errors = e.read()
  157. e.close()
  158. assert 'Invalid RPython operation' in errors
  159. def test_segfault_2():
  160. py.test.skip("hum, this is one example, but we need to be very careful")
  161. class Base:
  162. pass
  163. class A(Base):
  164. def __init__(self, m):
  165. self.m = m
  166. def getm(self):
  167. return self.m
  168. class B(Base):
  169. def __init__(self, a):
  170. self.a = a
  171. def g(m):
  172. a = A(m)
  173. if m < 10:
  174. a = B(a)
  175. return a
  176. def entry_point(argv):
  177. x = g(len(argv))
  178. os.write(2, str(x.getm()))
  179. return 0
  180. exe = compile(entry_point)
  181. g, f, e = os.popen3(exe, "t", 0)
  182. g.close()
  183. tail = f.read(23)
  184. f.close()
  185. assert tail == "" # and not ll_os.ll_os_write
  186. errors = e.read()
  187. e.close()
  188. assert '...think what kind of errors to get...' in errors
  189. def test_safe_alloc():
  190. from pypy.rlib.rmmap import alloc, free
  191. def entry_point(argv):
  192. one = alloc(1024)
  193. free(one, 1024)
  194. return 0
  195. exe = compile(entry_point)
  196. pipe = subprocess.Popen([exe], stdout=subprocess.PIPE,
  197. stdin=subprocess.PIPE)
  198. g = pipe.stdin
  199. f = pipe.stdout
  200. g.close()
  201. tail = f.read()
  202. f.close()
  203. assert tail == ""
  204. rescode = pipe.wait()
  205. assert rescode == 0
  206. def test_unsafe_mmap():
  207. py.test.skip("Since this stuff is unimplemented, it won't work anyway "
  208. "however, the day it starts working, it should pass test")
  209. from pypy.rlib.rmmap import mmap
  210. def entry_point(argv):
  211. try:
  212. res = mmap(0, 1024)
  213. except OSError:
  214. return 0
  215. return 1
  216. exe = compile(entry_point)
  217. pipe = subprocess.Popen([exe], stdout=subprocess.PIPE,
  218. stdin=subprocess.PIPE)
  219. g = pipe.stdin
  220. f = pipe.stdout
  221. expect(f, g, "mmap", ARGS, OSError(1, "xyz"))
  222. g.close()
  223. tail = f.read()
  224. f.close()
  225. assert tail == ""
  226. rescode = pipe.wait()
  227. assert rescode == 0
  228. class TestPrintedResults:
  229. def run(self, entry_point, args, expected):
  230. exe = compile(entry_point)
  231. from pypy.translator.sandbox.sandlib import SimpleIOSandboxedProc
  232. proc = SimpleIOSandboxedProc([exe] + args)
  233. output, error = proc.communicate()
  234. assert error == ''
  235. assert output == expected
  236. def test_safefuncs(self):
  237. import math
  238. def entry_point(argv):
  239. a = float(argv[1])
  240. print int(math.floor(a - 0.2)),
  241. print int(math.ceil(a)),
  242. print int(100.0 * math.sin(a)),
  243. mantissa, exponent = math.frexp(a)
  244. print int(100.0 * mantissa), exponent,
  245. fracpart, intpart = math.modf(a)
  246. print int(100.0 * fracpart), int(intpart),
  247. print
  248. return 0
  249. self.run(entry_point, ["3.011"], "2 4 13 75 2 1 3\n")
  250. def test_safefuncs_exception(self):
  251. import math
  252. def entry_point(argv):
  253. a = float(argv[1])
  254. x = math.log(a)
  255. print int(x * 100.0)
  256. try:
  257. math.log(-a)
  258. except ValueError:
  259. print 'as expected, got a ValueError'
  260. else:
  261. print 'did not get a ValueError!'
  262. return 0
  263. self.run(entry_point, ["3.011"], "110\nas expected, got a ValueError\n")
  264. def test_os_path_safe(self):
  265. def entry_point(argv):
  266. print os.path.join('tmp', argv[1])
  267. return 0
  268. self.run(entry_point, ["spam"], os.path.join("tmp", "spam")+'\n')