[pypy-commit] pypy reverse-debugger: Move the tests to the external repo
arigo
pypy.commits at gmail.com
Fri Sep 9 04:54:49 EDT 2016
Author: Armin Rigo <arigo at tunes.org>
Branch: reverse-debugger
Changeset: r86969:6acec5a7e9ed
Date: 2016-09-09 10:54 +0200
http://bitbucket.org/pypy/pypy/changeset/6acec5a7e9ed/
Log: Move the tests to the external repo
diff --git a/rpython/rlib/src/boehm-rawrefcount.h b/rpython/rlib/src/boehm-rawrefcount.h
--- a/rpython/rlib/src/boehm-rawrefcount.h
+++ b/rpython/rlib/src/boehm-rawrefcount.h
@@ -3,6 +3,7 @@
OP_GC_RAWREFCOUNT_INIT(callback, r): the callback is not supported here
OP_GC_RAWREFCOUNT_CREATE_LINK_PYOBJ(): not implemented, maybe not needed
*/
+#define RPY_USES_RAWREFCOUNT
#ifdef RPY_REVERSE_DEBUGGER
/* these macros are defined in src-revdb/revdb_include.h */
diff --git a/rpython/translator/revdb/src-revdb/revdb.c b/rpython/translator/revdb/src-revdb/revdb.c
--- a/rpython/translator/revdb/src-revdb/revdb.c
+++ b/rpython/translator/revdb/src-revdb/revdb.c
@@ -1783,6 +1783,8 @@
}
+#ifdef RPY_USES_RAWREFCOUNT
+
static void *rawrefcount_tree; /* {pyobj: gcobj} */
struct rawrefcount_link2_s {
@@ -1940,6 +1942,8 @@
}
}
+#endif /* RPY_USES_RAWREFCOUNT */
+
/* ------------------------------------------------------------ */
diff --git a/rpython/translator/revdb/test/README b/rpython/translator/revdb/test/README
new file mode 100644
--- /dev/null
+++ b/rpython/translator/revdb/test/README
@@ -0,0 +1,3 @@
+The tests are located in the external repository:
+
+ https://bitbucket.org/pypy/revdb/
diff --git a/rpython/translator/revdb/test/__init__.py b/rpython/translator/revdb/test/__init__.py
deleted file mode 100644
diff --git a/rpython/translator/revdb/test/ctrl_c.py b/rpython/translator/revdb/test/ctrl_c.py
deleted file mode 100644
--- a/rpython/translator/revdb/test/ctrl_c.py
+++ /dev/null
@@ -1,43 +0,0 @@
-import sys, os, thread, time, signal
-
-os.setpgid(0, 0)
-assert os.getpgrp() == os.getpid()
-
-
-sys.path[:] = sys.argv[1].split('\x7f')
-from rpython.translator.revdb.process import ReplayProcessGroup
-
-exename, rdbname = sys.argv[2:]
-group = ReplayProcessGroup(exename, rdbname)
-
-
-class MyInterrupt(Exception):
- pass
-def my_signal(*args):
- raise MyInterrupt
-prev_signal = signal.signal(signal.SIGINT, my_signal)
-
-def enable_timer():
- def my_kill():
- time.sleep(0.8)
- print >> sys.stderr, "--<<< Sending CTRL-C >>>--"
- os.killpg(os.getpid(), signal.SIGINT)
- thread.start_new_thread(my_kill, ())
-
-all_ok = False
-try:
- # this runs for ~9 seconds if uninterrupted
- enable_timer()
- group.print_cmd('very-long-loop')
-except MyInterrupt:
- print >> sys.stderr, "very-long-loop interrupted, trying again"
- group.recreate_subprocess(1)
- try:
- enable_timer()
- group.print_cmd('very-long-loop')
- except MyInterrupt:
- print >> sys.stderr, "second interruption ok"
- all_ok = True
-
-assert all_ok, "expected very-long-loop to be killed by SIGINT"
-print "all ok"
diff --git a/rpython/translator/revdb/test/test_basic.py b/rpython/translator/revdb/test/test_basic.py
deleted file mode 100644
--- a/rpython/translator/revdb/test/test_basic.py
+++ /dev/null
@@ -1,462 +0,0 @@
-import py
-import os, sys, subprocess, socket
-import re, array, struct
-from rpython.tool.udir import udir
-from rpython.translator.interactive import Translation
-from rpython.rlib.rarithmetic import LONG_BIT, intmask
-from rpython.rlib import objectmodel, revdb
-from rpython.rlib.debug import debug_print
-from rpython.rtyper.annlowlevel import cast_gcref_to_instance
-from rpython.rtyper.lltypesystem import lltype, llmemory
-
-from rpython.translator.revdb.message import *
-from rpython.translator.revdb.process import ReplayProcess
-
-
-ASYNC_THREAD_SWITCH = 0xff54 - 2**16
-
-
-class RDB(object):
- def __init__(self, filename, expected_argv):
- with open(filename, 'rb') as f:
- self.buffer = f.read()
- self.cur = self.buffer.index('\x00') + 1
- header = self.buffer[:self.cur]
- assert header == 'RevDB:\t' + '\t'.join(expected_argv) + '\n\x00'
- #
- x = self.read1('P'); assert x == 0x00FF0003
- x = self.read1('P'); self.main_thread_id = x
- x = self.read1('P'); assert x == 0
- x = self.read1('P'); #assert x == &rpy_reverse_db_stop_point
- x = self.read1('P'); #assert x == &rpy_revdb
- x = self.read1('i'); assert x == 0
- self.argc = self.read1('i')
- self.argv = self.read1('P')
- self.current_packet_end = self.cur
- self.read_check_argv(expected_argv)
-
- def read1(self, mode):
- p = self.cur
- self.cur = p + struct.calcsize(mode)
- return struct.unpack_from(mode, self.buffer, p)[0]
-
- def next(self, mode='P'):
- if self.current_packet_end == self.cur:
- packet_size = self.read1('h')
- assert packet_size > 0
- self.current_packet_end = self.cur + packet_size
- result = self.read1(mode)
- assert self.cur <= self.current_packet_end
- return result
-
- def is_special_packet(self):
- if self.current_packet_end != self.cur:
- assert self.current_packet_end > self.cur
- return False
- next_header = struct.unpack_from('h', self.buffer, self.cur)[0]
- return (next_header & 0xFF00) == 0xFF00
-
- def special_packet(self, expected, fmt):
- assert self.current_packet_end == self.cur
- next_id = self.read1('h')
- assert next_id == expected
- p = self.cur
- self.cur = self.current_packet_end = p + struct.calcsize(fmt)
- return struct.unpack_from(fmt, self.buffer, p)
-
- def read_check_argv(self, expected):
- assert self.argc == len(expected)
- for i in range(self.argc):
- self.next() # this is from "p = argv[i]"
- s = []
- # first we determine the length of the "char *p"
- while True:
- c = self.next('c')
- if c == '\x00':
- break
- s.append(c)
- # then we really read the "char *" and copy it into a rpy string
- # (that's why this time we don't read the final \0)
- for c1 in s:
- c2 = self.next('c')
- assert c2 == c1
- assert ''.join(s) == expected[i]
-
- def number_of_stop_points(self):
- return struct.unpack_from("q", self.buffer, len(self.buffer) - 8)[0]
-
- def done(self):
- return self.cur == len(self.buffer)
-
- def write_call(self, expected_string):
- x = self.next() # raw_malloc: the pointer we got
- self.gil_release()
- self.same_stack() # write
- x = self.next(); assert x == len(expected_string)
- self.same_stack() # errno
- x = self.next('i'); assert x == 0 # errno
- self.gil_acquire()
-
- def same_stack(self):
- x = self.next('c'); assert x == '\xFC'
-
- def gil_acquire(self):
- x = self.next('c'); assert x == '\xFD'
-
- def gil_release(self):
- x = self.next('c'); assert x == '\xFE'
-
- def switch_thread(self, expected=None):
- th, = self.special_packet(ASYNC_THREAD_SWITCH, 'q')
- if expected is not None:
- assert th == expected
- return th
-
-
-def compile(self, entry_point, backendopt=True,
- withsmallfuncsets=None, shared=False, thread=False):
- t = Translation(entry_point, None, gc="boehm")
- self.t = t
- t.set_backend_extra_options(c_debug_defines=True)
- t.config.translation.reverse_debugger = True
- t.config.translation.lldebug0 = True
- t.config.translation.shared = shared
- t.config.translation.thread = thread
- if withsmallfuncsets is not None:
- t.config.translation.withsmallfuncsets = withsmallfuncsets
- if not backendopt:
- t.disable(["backendopt_lltype"])
- t.annotate()
- t.rtype()
- if t.backendopt:
- t.backendopt()
- self.exename = t.compile_c()
- self.rdbname = os.path.join(os.path.dirname(str(self.exename)),
- 'log.rdb')
-
-def run(self, *argv):
- env = os.environ.copy()
- env['PYPYRDB'] = self.rdbname
- t = self.t
- stdout, stderr = t.driver.cbuilder.cmdexec(' '.join(argv), env=env,
- expect_crash=9)
- print >> sys.stderr, stderr
- return stdout
-
-def fetch_rdb(self, expected_argv):
- return RDB(self.rdbname, map(str, expected_argv))
-
-
-class BaseRecordingTests(object):
- compile = compile
- run = run
- fetch_rdb = fetch_rdb
-
-
-class TestRecording(BaseRecordingTests):
-
- def test_simple(self):
- def main(argv):
- print argv[1:]
- return 9
- self.compile(main, backendopt=False)
- assert self.run('abc d') == '[abc, d]\n'
- rdb = self.fetch_rdb([self.exename, 'abc', 'd'])
- rdb.write_call('[abc, d]\n')
- x = rdb.next('q'); assert x == 0 # number of stop points
- # that's all we should get from this simple example
- assert rdb.done()
-
- def test_identityhash(self):
- def main(argv):
- print [objectmodel.compute_identity_hash(argv),
- objectmodel.compute_identity_hash(argv),
- objectmodel.compute_identity_hash(argv)]
- return 9
- self.compile(main, backendopt=False)
- out = self.run('Xx')
- match = re.match(r'\[(-?\d+), \1, \1]\n', out)
- assert match
- hash_value = int(match.group(1))
- rdb = self.fetch_rdb([self.exename, 'Xx'])
- # compute_identity_hash() doesn't record anything
- rdb.write_call(out)
- # done
- x = rdb.next('q'); assert x == 0 # number of stop points
- assert rdb.done()
-
- def test_dont_record_vtable_reads(self):
- class A(object):
- x = 42
- class B(A):
- x = 43
- lst = [A(), B()]
- def main(argv):
- print lst[len(argv) & 1].x
- return 9
- self.compile(main, backendopt=False)
- out = self.run('Xx')
- assert out == '42\n'
- rdb = self.fetch_rdb([self.exename, 'Xx'])
- # write() call (it used to be the case that vtable reads where
- # recorded too; the single byte fetched from the vtable from
- # the '.x' in main() would appear here)
- rdb.write_call(out)
- # done
- x = rdb.next('q'); assert x == 0 # number of stop points
- assert rdb.done()
-
- def test_dont_record_pbc_reads(self):
- class MyPBC:
- def _freeze_(self):
- return True
- pbc1 = MyPBC(); pbc1.x = 41
- pbc2 = MyPBC(); pbc2.x = 42
- lst = [pbc1, pbc2]
- def main(argv):
- print lst[len(argv) & 1].x
- return 9
- self.compile(main, backendopt=False)
- out = self.run('Xx')
- assert out == '41\n'
- rdb = self.fetch_rdb([self.exename, 'Xx'])
- # write() call
- rdb.write_call(out)
- # done
- x = rdb.next('q'); assert x == 0 # number of stop points
- assert rdb.done()
-
- @py.test.mark.parametrize('limit', [3, 5])
- def test_dont_record_small_funcset_conversions(self, limit):
- def f1():
- return 111
- def f2():
- return 222
- def f3():
- return 333
- def g(n):
- if n & 1:
- return f1
- else:
- return f2
- def main(argv):
- x = g(len(argv)) # can be f1 or f2
- if len(argv) > 5:
- x = f3 # now can be f1 or f2 or f3
- print x()
- return 9
- self.compile(main, backendopt=False, withsmallfuncsets=limit)
- for input, expected_output in [
- ('2 3', '111\n'),
- ('2 3 4', '222\n'),
- ('2 3 4 5 6 7', '333\n'),
- ]:
- out = self.run(input)
- assert out == expected_output
- rdb = self.fetch_rdb([self.exename] + input.split())
- # write() call
- rdb.write_call(out)
- x = rdb.next('q'); assert x == 0 # number of stop points
- assert rdb.done()
-
-
-class InteractiveTests(object):
-
- def replay(self, **kwds):
- s1, s2 = socket.socketpair()
- subproc = subprocess.Popen(
- [str(self.exename), '--revdb-replay', str(self.rdbname),
- str(s2.fileno())], preexec_fn=s1.close, **kwds)
- s2.close()
- self.subproc = subproc
- child = ReplayProcess(subproc.pid, s1)
- child.expect(ANSWER_INIT, INIT_VERSION_NUMBER,
- self.expected_stop_points)
- child.expect(ANSWER_READY, 1, Ellipsis)
- return child
-
-
-class TestSimpleInterpreter(InteractiveTests):
- expected_stop_points = 3
-
- def setup_class(cls):
- def main(argv):
- lst = [argv[0], 'prebuilt']
- for op in argv[1:]:
- revdb.stop_point()
- print op
- lst.append(op + '??') # create a new string here
- for x in lst:
- print revdb.get_unique_id(x)
- return 9
- compile(cls, main, backendopt=False)
- assert run(cls, 'abc d ef') == ('abc\nd\nef\n'
- '3\n0\n12\n15\n17\n')
- rdb = fetch_rdb(cls, [cls.exename, 'abc', 'd', 'ef'])
- assert rdb.number_of_stop_points() == 3
-
- def test_go(self):
- child = self.replay()
- child.send(Message(CMD_FORWARD, 2))
- child.expect(ANSWER_READY, 3, Ellipsis)
- child.send(Message(CMD_FORWARD, 2))
- child.expect(ANSWER_AT_END)
-
- def test_quit(self):
- child = self.replay()
- child.send(Message(CMD_QUIT))
- assert self.subproc.wait() == 0
-
- def test_fork(self):
- child = self.replay()
- child2 = child.clone()
- child.send(Message(CMD_FORWARD, 2))
- child.expect(ANSWER_READY, 3, Ellipsis)
- child2.send(Message(CMD_FORWARD, 1))
- child2.expect(ANSWER_READY, 2, Ellipsis)
- #
- child.close()
- child2.close()
-
-
-class TestDebugCommands(InteractiveTests):
- expected_stop_points = 3
-
- def setup_class(cls):
- #
- class Stuff:
- pass
- #
- def g(cmdline):
- if len(cmdline) > 5:
- raise ValueError
- g._dont_inline_ = True
- #
- def went_fw():
- revdb.send_answer(120, revdb.current_time())
- if revdb.current_time() != revdb.total_time():
- revdb.go_forward(1, went_fw)
- #
- def _nothing(arg):
- pass
- #
- def callback_track_obj(gcref):
- revdb.send_output("callback_track_obj\n")
- dbstate.gcref = gcref
- #
- def blip(cmd, extra):
- debug_print('<<<', cmd.c_cmd, cmd.c_arg1,
- cmd.c_arg2, cmd.c_arg3, extra, '>>>')
- if extra == 'oops':
- print 42 # I/O not permitted
- if extra == 'raise-and-catch':
- try:
- g(extra)
- except ValueError:
- pass
- if extra == 'crash':
- raise ValueError
- if extra == 'get-value':
- revdb.send_answer(100, revdb.current_time(),
- revdb.total_time())
- if extra == 'current-place':
- revdb.send_answer(200, revdb.current_place())
- ## if extra == 'go-fw':
- ## revdb.go_forward(1, went_fw)
- ## if cmdline == 'set-break-after-0':
- ## dbstate.break_after = 0
- ## if cmdline == 'print-id':
- ## revdb.send_output('obj.x=%d %d %d\n' % (
- ## dbstate.stuff.x,
- ## revdb.get_unique_id(dbstate.stuff),
- ## revdb.currently_created_objects()))
- ## if cmdline.startswith('track-object '):
- ## uid = int(cmdline[len('track-object '):])
- ## dbstate.gcref = lltype.nullptr(llmemory.GCREF.TO)
- ## revdb.track_object(uid, callback_track_obj)
- ## if cmdline == 'get-tracked-object':
- ## if dbstate.gcref:
- ## revdb.send_output('got obj.x=%d\n' % (
- ## cast_gcref_to_instance(Stuff, dbstate.gcref).x,))
- ## else:
- ## revdb.send_output('none\n')
- ## if cmdline == 'first-created-uid':
- ## revdb.send_output('first-created-uid=%d\n' % (
- ## revdb.first_created_object_uid(),))
- revdb.send_answer(42, cmd.c_cmd, -43, -44, extra)
- lambda_blip = lambda: blip
- #
- class DBState:
- pass
- dbstate = DBState()
- #
- def main(argv):
- revdb.register_debug_command(1, lambda_blip)
- for i, op in enumerate(argv[1:]):
- dbstate.stuff = Stuff()
- dbstate.stuff.x = i + 1000
- revdb.stop_point(i * 10)
- print op
- if i == 1:
- if os.fork() == 0: # child
- os.write(2, "this line is from the fork child.\n")
- return 0
- return 9
- compile(cls, main, backendopt=False)
- assert run(cls, 'abc d ef') == 'abc\nd\nef\n'
-
- def test_run_blip(self):
- child = self.replay()
- child.send(Message(1, extra='foo'))
- child.expect(42, 1, -43, -44, 'foo')
-
- def test_io_not_permitted(self):
- child = self.replay(stderr=subprocess.PIPE)
- child.send(Message(1, extra='oops'))
- child.expect(ANSWER_ATTEMPT_IO)
- child.close()
- err = self.subproc.stderr.read()
- assert err.endswith(': Attempted to do I/O or access raw memory\n')
-
- def test_interaction_with_forward(self):
- child = self.replay()
- child.send(Message(CMD_FORWARD, 50))
- child.expect(ANSWER_AT_END)
-
- def test_raise_and_catch(self):
- child = self.replay()
- child.send(Message(1, extra='raise-and-catch'))
- child.expect(42, 1, -43, -44, 'raise-and-catch')
-
- def test_crash(self):
- child = self.replay(stderr=subprocess.PIPE)
- child.send(Message(1, extra='crash'))
- child.close()
- err = self.subproc.stderr.read()
- assert err.endswith('Command crashed with ValueError\n')
-
- def test_get_value(self):
- child = self.replay()
- child.send(Message(1, extra='get-value'))
- child.expect(100, 1, 3)
-
- def test_current_place(self):
- child = self.replay()
- child.send(Message(1, extra='current-place'))
- child.expect(200, 0)
- child.expect(42, 1, -43, -44, 'current-place')
- child.expect(ANSWER_READY, 1, Ellipsis)
- child.send(Message(CMD_FORWARD, 2))
- child.expect(ANSWER_READY, 3, Ellipsis)
- child.send(Message(1, extra='current-place'))
- child.expect(200, 20)
- child.expect(42, 1, -43, -44, 'current-place')
-
- ## def test_go_fw(self):
- ## child = self.replay()
- ## child.send(Message(1, extra='go-fw'))
- ## child.expect(42, 1, -43, -44, 'go-fw')
- ## child.expect(120, 2)
- ## child.expect(120, 3)
- ## child.send(Message(CMD_FORWARD, 0))
- ## child.expect(ANSWER_READY, 3, Ellipsis)
diff --git a/rpython/translator/revdb/test/test_callback.py b/rpython/translator/revdb/test/test_callback.py
deleted file mode 100644
--- a/rpython/translator/revdb/test/test_callback.py
+++ /dev/null
@@ -1,123 +0,0 @@
-from rpython.translator.tool.cbuild import ExternalCompilationInfo
-from rpython.rtyper.lltypesystem import lltype, rffi
-from rpython.rlib.rarithmetic import intmask
-from rpython.rlib import revdb
-from rpython.translator.revdb.test.test_basic import BaseRecordingTests
-from rpython.translator.revdb.test.test_basic import InteractiveTests
-
-from rpython.translator.revdb.message import *
-
-
-def get_callback_demo():
- eci = ExternalCompilationInfo(separate_module_sources=['''
- int callme(int(*cb)(int)) {
- return cb(40) * cb(3);
- }
- '''], post_include_bits=['''
- int callme(int(*)(int));
- '''])
- FUNCPTR = lltype.Ptr(lltype.FuncType([rffi.INT], rffi.INT))
- callme = rffi.llexternal('callme', [FUNCPTR], rffi.INT,
- compilation_info=eci)
-
- def callback(n):
- print intmask(n)
- return n
-
- def main(argv):
- revdb.stop_point()
- print intmask(callme(callback))
- revdb.stop_point()
- return 9
-
- return main
-
-
-class TestRecording(BaseRecordingTests):
-
- def test_callback_simple(self):
- eci = ExternalCompilationInfo(separate_module_sources=['''
- int callme(int(*cb)(int)) {
- return cb(40) * cb(3);
- }
- int callmesimple(void) {
- return 55555;
- }
- '''], post_include_bits=['''
- int callme(int(*)(int));
- int callmesimple(void);
- '''])
- FUNCPTR = lltype.Ptr(lltype.FuncType([rffi.INT], rffi.INT))
- callme = rffi.llexternal('callme', [FUNCPTR], rffi.INT,
- compilation_info=eci)
- callmesimple = rffi.llexternal('callmesimple', [], rffi.INT,
- compilation_info=eci)
-
- def callback(n):
- return intmask(n) * 100
-
- def main(argv):
- print intmask(callmesimple())
- print intmask(callme(callback))
- return 9
- self.compile(main, backendopt=False)
- out = self.run('Xx')
- rdb = self.fetch_rdb([self.exename, 'Xx'])
- rdb.gil_release()
- rdb.same_stack() # callmesimple()
- x = rdb.next('i'); assert x == 55555
- rdb.gil_acquire()
- rdb.write_call('55555\n')
- rdb.gil_release()
- b = rdb.next('!h'); assert 300 <= b < 310 # -> callback
- x = rdb.next('i'); assert x == 40 # arg n
- rdb.gil_acquire()
- rdb.gil_release()
- x = rdb.next('!h'); assert x == b # -> callback
- x = rdb.next('i'); assert x == 3 # arg n
- rdb.gil_acquire()
- rdb.gil_release()
- rdb.same_stack() # <- return in main thread
- x = rdb.next('i'); assert x == 4000 * 300 # return from callme()
- rdb.gil_acquire()
- rdb.write_call('%s\n' % (4000 * 300,))
- x = rdb.next('q'); assert x == 0 # number of stop points
- assert rdb.done()
-
- def test_callback_with_effects(self):
- main = get_callback_demo()
- self.compile(main, backendopt=False)
- out = self.run('Xx')
- rdb = self.fetch_rdb([self.exename, 'Xx'])
- rdb.gil_release()
- b = rdb.next('!h'); assert 300 <= b < 310 # -> callback
- x = rdb.next('i'); assert x == 40 # arg n
- rdb.gil_acquire()
- rdb.write_call('40\n')
- rdb.gil_release()
- x = rdb.next('!h'); assert x == b # -> callback again
- x = rdb.next('i'); assert x == 3 # arg n
- rdb.gil_acquire()
- rdb.write_call('3\n')
- rdb.gil_release()
- rdb.same_stack() # -> return in main thread
- x = rdb.next('i'); assert x == 120 # <- return from callme()
- rdb.gil_acquire()
- rdb.write_call('120\n')
- x = rdb.next('q'); assert x == 2 # number of stop points
- assert rdb.done()
-
-
-class TestReplayingCallback(InteractiveTests):
- expected_stop_points = 2
-
- def setup_class(cls):
- from rpython.translator.revdb.test.test_basic import compile, run
- main = get_callback_demo()
- compile(cls, main, backendopt=False)
- run(cls, '')
-
- def test_replaying_callback(self):
- child = self.replay()
- child.send(Message(CMD_FORWARD, 3))
- child.expect(ANSWER_AT_END)
diff --git a/rpython/translator/revdb/test/test_process.py b/rpython/translator/revdb/test/test_process.py
deleted file mode 100644
--- a/rpython/translator/revdb/test/test_process.py
+++ /dev/null
@@ -1,237 +0,0 @@
-import py, sys, math, os, subprocess, time
-from cStringIO import StringIO
-from rpython.rlib import revdb, rdtoa
-from rpython.rlib.debug import debug_print, ll_assert
-from rpython.rtyper.annlowlevel import cast_gcref_to_instance
-from rpython.translator.revdb.message import *
-from rpython.translator.revdb.process import ReplayProcessGroup, Breakpoint
-
-from hypothesis import given, strategies
-
-
-class stdout_capture(object):
- def __enter__(self):
- self.old_stdout = sys.stdout
- sys.stdout = self.buffer = StringIO()
- return self.buffer
- def __exit__(self, *args):
- sys.stdout = self.old_stdout
-
-
-class TestReplayProcessGroup:
-
- def setup_class(cls):
- from rpython.translator.revdb.test.test_basic import compile, run
-
- class Stuff:
- pass
-
- class DBState:
- break_loop = -2
- stuff = None
- metavar = None
- printed_stuff = None
- watch_future = -1
- dbstate = DBState()
-
- def blip(cmd, extra):
- debug_print('<<<', cmd.c_cmd, cmd.c_arg1,
- cmd.c_arg2, cmd.c_arg3, extra, '>>>')
- if extra == 'set-breakpoint':
- dbstate.break_loop = cmd.c_arg1
- revdb.send_answer(42, cmd.c_cmd, -43, -44, extra)
- lambda_blip = lambda: blip
-
- def command_print(cmd, extra):
- if extra == 'print-me':
- stuff = dbstate.stuff
- elif extra == '$0':
- stuff = dbstate.metavar
- elif extra == '2.35':
- val = rdtoa.strtod('2.35')
- valx, valy = math.modf(val)
- revdb.send_output(rdtoa.dtoa(valx) + '\n')
- revdb.send_output(rdtoa.dtoa(valy) + '\n')
- xx, yy = math.frexp(val)
- revdb.send_output(rdtoa.dtoa(xx) + '\n')
- revdb.send_output('%d\n' % yy)
- return
- elif extra == 'very-long-loop':
- i = 0
- total = 0
- while i < 2000000000:
- total += revdb.flag_io_disabled()
- i += 1
- revdb.send_output(str(total))
- return
- else:
- assert False
- uid = revdb.get_unique_id(stuff)
- ll_assert(uid > 0, "uid == 0")
- revdb.send_nextnid(uid) # outputs '$NUM = '
- revdb.send_output('stuff\n')
- dbstate.printed_stuff = stuff
- lambda_print = lambda: command_print
-
- def command_attachid(cmd, extra):
- index_metavar = cmd.c_arg1
- uid = cmd.c_arg2
- ll_assert(index_metavar == 0, "index_metavar != 0") # in this test
- dbstate.metavar = dbstate.printed_stuff
- if dbstate.metavar is None:
- # uid not found, probably a future object
- dbstate.watch_future = uid
- lambda_attachid = lambda: command_attachid
-
- def command_allocating(uid, gcref):
- stuff = cast_gcref_to_instance(Stuff, gcref)
- # 'stuff' is just allocated; 'stuff.x' is not yet initialized
- dbstate.printed_stuff = stuff
- if dbstate.watch_future != -1:
- ll_assert(dbstate.watch_future == uid,
- "watch_future out of sync")
- dbstate.watch_future = -1
- dbstate.metavar = stuff
- lambda_allocating = lambda: command_allocating
-
- def command_compilewatch(cmd, expression):
- revdb.send_watch("marshalled_code", ok_flag=1)
- lambda_compilewatch = lambda: command_compilewatch
-
- def command_checkwatch(cmd, marshalled_code):
- assert marshalled_code == "marshalled_code"
- # check that $0 exists
- if dbstate.metavar is not None:
- revdb.send_watch("ok, stuff exists\n", ok_flag=1)
- else:
- revdb.send_watch("stuff does not exist!\n", ok_flag=0)
- lambda_checkwatch = lambda: command_checkwatch
-
- def main(argv):
- revdb.register_debug_command(100, lambda_blip)
- revdb.register_debug_command(CMD_PRINT, lambda_print)
- revdb.register_debug_command(CMD_ATTACHID, lambda_attachid)
- revdb.register_debug_command("ALLOCATING", lambda_allocating)
- revdb.register_debug_command(revdb.CMD_COMPILEWATCH,
- lambda_compilewatch)
- revdb.register_debug_command(revdb.CMD_CHECKWATCH,
- lambda_checkwatch)
- for i, op in enumerate(argv[1:]):
- dbstate.stuff = Stuff()
- dbstate.stuff.x = i + 1000
- if i == dbstate.break_loop or i == dbstate.break_loop + 1:
- revdb.breakpoint(99)
- revdb.stop_point()
- print op
- return 9
- compile(cls, main, backendopt=False)
- assert run(cls, 'abc d ef g h i j k l m') == (
- 'abc\nd\nef\ng\nh\ni\nj\nk\nl\nm\n')
-
-
- def test_init(self):
- group = ReplayProcessGroup(str(self.exename), self.rdbname)
- assert group.get_max_time() == 10
- assert group.get_next_clone_time() == 4
-
- def test_forward(self):
- group = ReplayProcessGroup(str(self.exename), self.rdbname)
- group.go_forward(100)
- assert group.get_current_time() == 10
- assert sorted(group.paused) == [1, 4, 6, 8, 9, 10]
- assert group._check_current_time(10)
-
- @given(strategies.lists(strategies.integers(min_value=1, max_value=10)))
- def test_jump_in_time(self, target_times):
- group = ReplayProcessGroup(str(self.exename), self.rdbname)
- for target_time in target_times:
- group.jump_in_time(target_time)
- group._check_current_time(target_time)
-
- def test_breakpoint_b(self):
- group = ReplayProcessGroup(str(self.exename), self.rdbname)
- group.active.send(Message(100, 6, extra='set-breakpoint'))
- group.active.expect(42, 100, -43, -44, 'set-breakpoint')
- group.active.expect(ANSWER_READY, 1, Ellipsis)
- e = py.test.raises(Breakpoint, group.go_forward, 10, 'b')
- assert e.value.time == 7
- assert e.value.nums == [99]
- group._check_current_time(7)
-
- def test_breakpoint_r(self):
- group = ReplayProcessGroup(str(self.exename), self.rdbname)
- group.active.send(Message(100, 6, extra='set-breakpoint'))
- group.active.expect(42, 100, -43, -44, 'set-breakpoint')
- group.active.expect(ANSWER_READY, 1, Ellipsis)
- e = py.test.raises(Breakpoint, group.go_forward, 10, 'r')
- assert e.value.time == 7
- assert e.value.nums == [99]
- group._check_current_time(10)
-
- def test_breakpoint_i(self):
- group = ReplayProcessGroup(str(self.exename), self.rdbname)
- group.active.send(Message(100, 6, extra='set-breakpoint'))
- group.active.expect(42, 100, -43, -44, 'set-breakpoint')
- group.active.expect(ANSWER_READY, 1, Ellipsis)
- group.go_forward(10, 'i') # does not raise Breakpoint
-
- def test_print_cmd(self):
- group = ReplayProcessGroup(str(self.exename), self.rdbname)
- group.go_forward(1)
- assert group.get_current_time() == 2
- with stdout_capture() as buf:
- group.print_cmd('print-me')
- assert buf.getvalue() == "$0 = stuff\n"
- return group
-
- def _print_metavar(self, group):
- with stdout_capture() as buf:
- group.print_cmd('$0', nids=[0])
- assert buf.getvalue() == "$0 = stuff\n"
-
- def test_print_metavar(self):
- group = self.test_print_cmd()
- self._print_metavar(group)
-
- def test_jump_and_print_metavar(self):
- group = self.test_print_cmd()
- assert group.is_tainted()
- group.jump_in_time(2)
- self._print_metavar(group)
-
- def _check_watchpoint_expr(self, group, must_exist):
- ok_flag, compiled_code = group.compile_watchpoint_expr("$0")
- assert ok_flag == 1
- assert compiled_code == "marshalled_code"
- nids = [0]
- ok_flag, text = group.check_watchpoint_expr(compiled_code, nids)
- print text
- assert ok_flag == must_exist
-
- def test_check_watchpoint_expr(self):
- group = self.test_print_cmd()
- self._check_watchpoint_expr(group, must_exist=1)
-
- def test_jump_and_check_watchpoint_expr(self):
- group = self.test_print_cmd()
- group.jump_in_time(2)
- self._check_watchpoint_expr(group, must_exist=1)
-
- def test_rdtoa(self):
- group = ReplayProcessGroup(str(self.exename), self.rdbname)
- with stdout_capture() as buf:
- group.print_cmd('2.35')
- assert buf.getvalue() == "0.35\n2.0\n0.5875\n2\n"
-
- def test_ctrl_c(self):
- localdir = os.path.dirname(__file__)
- args = [sys.executable, os.path.join(localdir, 'ctrl_c.py'),
- '\x7f'.join(sys.path),
- str(self.exename), self.rdbname]
- t1 = time.time()
- result = subprocess.check_output(args)
- t2 = time.time()
- print 'subprocess returned with captured stdout:\n%r' % (result,)
- assert result == 'all ok\n'
- # should take two times ~0.8 seconds if correctly interrupted
- assert t2 - t1 < 3.0
diff --git a/rpython/translator/revdb/test/test_raw.py b/rpython/translator/revdb/test/test_raw.py
deleted file mode 100644
--- a/rpython/translator/revdb/test/test_raw.py
+++ /dev/null
@@ -1,88 +0,0 @@
-import os, subprocess
-from rpython.rlib import revdb
-from rpython.rtyper.lltypesystem import lltype
-from rpython.translator.revdb.test.test_basic import InteractiveTests
-
-from rpython.translator.revdb.message import *
-
-
-class TestReplayingRaw(InteractiveTests):
- expected_stop_points = 1
-
- def setup_class(cls):
- from rpython.translator.revdb.test.test_basic import compile, run
- from rpython.translator.revdb.test.test_basic import fetch_rdb
-
- FOO = lltype.Struct('FOO')
- foo = lltype.malloc(FOO, flavor='raw', immortal=True)
-
- BAR = lltype.Struct('BAR', ('p', lltype.Ptr(FOO)))
- bar = lltype.malloc(BAR, flavor='raw', immortal=True)
- bar.p = foo
-
- BAZ = lltype.Struct('BAZ', ('p', lltype.Ptr(FOO)), ('q', lltype.Signed),
- hints={'union': True})
- baz = lltype.malloc(BAZ, flavor='raw', immortal=True)
- baz.p = foo
-
- VBAR = lltype.Array(lltype.Ptr(FOO))
- vbar = lltype.malloc(VBAR, 3, flavor='raw', immortal=True)
- vbar[0] = vbar[1] = vbar[2] = foo
-
- RECBAR = lltype.Struct('RECBAR', ('super', BAR), ('q', lltype.Ptr(FOO)))
- recbar = lltype.malloc(RECBAR, flavor='raw', immortal=True)
- recbar.q = foo
- recbar.super.p = foo
-
- IBAR = lltype.Struct('IBAR', ('p', lltype.Ptr(FOO)),
- hints={'static_immutable': True})
- ibar = lltype.malloc(IBAR, flavor='raw', immortal=True)
- ibar.p = foo
-
- BARI = lltype.Struct('BARI', ('b', lltype.Ptr(IBAR)))
- bari = lltype.malloc(BARI, flavor='raw', immortal=True)
- bari.b = ibar
-
- class X:
- pass
- x = X()
- x.foo = foo
- x.ibar = ibar
- x.bari = bari
-
- def main(argv):
- assert bar.p == foo
- assert baz.p == foo
- for i in range(3):
- assert vbar[i] == foo
- assert recbar.q == foo
- assert recbar.super.p == foo
- assert ibar.p == foo
- assert bari.b == ibar
- assert x.foo == foo
- assert x.ibar == ibar
- assert x.bari == bari
- revdb.stop_point()
- return 9
-
- compile(cls, main, backendopt=False, shared=True)
- run(cls, '')
- rdb = fetch_rdb(cls, [cls.exename])
- #assert len(rdb.rdb_struct) >= 4
-
- def test_replaying_raw(self):
- # This tiny test seems to always have foo at the same address
- # in multiple runs. Here we recompile with different options
- # just to change that address.
- #
- # NOTE: not supported right now! The executable must be
- # exactly the same one with the same raw addresses. This
- # might be fixed in the future.
- #subprocess.check_call(["make", "clean"],
- # cwd=os.path.dirname(str(self.exename)))
- #subprocess.check_call(["make", "lldebug"],
- # cwd=os.path.dirname(str(self.exename)))
- #
- child = self.replay()
- child.send(Message(CMD_FORWARD, 2))
- child.expect(ANSWER_AT_END)
diff --git a/rpython/translator/revdb/test/test_rawrefcount.py b/rpython/translator/revdb/test/test_rawrefcount.py
deleted file mode 100644
--- a/rpython/translator/revdb/test/test_rawrefcount.py
+++ /dev/null
@@ -1,61 +0,0 @@
-from rpython.rlib import objectmodel, rgc, revdb
-from rpython.rtyper.lltypesystem import lltype
-from rpython.translator.revdb.test.test_basic import InteractiveTests
-from rpython.translator.revdb.test.test_basic import compile, fetch_rdb, run
-from rpython.translator.revdb.message import *
-
-from rpython.rlib import rawrefcount
-
-
-class TestRawRefcount(InteractiveTests):
- expected_stop_points = 27
-
- def setup_class(cls):
- class W_Root(object):
- def __init__(self, n):
- self.n = n
- PyObjectS = lltype.Struct('PyObjectS',
- ('c_ob_refcnt', lltype.Signed),
- ('c_ob_pypy_link', lltype.Signed))
- PyObject = lltype.Ptr(PyObjectS)
- w1 = W_Root(-42)
- ob1 = lltype.malloc(PyObjectS, flavor='raw', zero=True,
- immortal=True)
- ob1.c_ob_refcnt = rawrefcount.REFCNT_FROM_PYPY
-
- def main(argv):
- rawrefcount.create_link_pypy(w1, ob1)
- w = None
- ob = lltype.nullptr(PyObjectS)
- oblist = []
- for op in argv[1:]:
- revdb.stop_point()
- w = W_Root(42)
- ob = lltype.malloc(PyObjectS, flavor='raw', zero=True)
- ob.c_ob_refcnt = rawrefcount.REFCNT_FROM_PYPY
- rawrefcount.create_link_pypy(w, ob)
- oblist.append(ob)
- del oblist[-1]
- #
- rgc.collect()
- assert rawrefcount.from_obj(PyObject, w) == ob
- assert rawrefcount.to_obj(W_Root, ob) == w
- while True:
- ob = rawrefcount.next_dead(PyObject)
- if not ob:
- break
- assert ob in oblist
- oblist.remove(ob)
- objectmodel.keepalive_until_here(w)
- revdb.stop_point()
- return 9
- compile(cls, main, backendopt=False)
- ARGS26 = 'a b c d e f g h i j k l m n o p q r s t u v w x y z'
- run(cls, ARGS26)
- rdb = fetch_rdb(cls, [cls.exename] + ARGS26.split())
- assert rdb.number_of_stop_points() == cls.expected_stop_points
-
- def test_go(self):
- child = self.replay()
- child.send(Message(CMD_FORWARD, 50))
- child.expect(ANSWER_AT_END)
diff --git a/rpython/translator/revdb/test/test_thread.py b/rpython/translator/revdb/test/test_thread.py
deleted file mode 100644
--- a/rpython/translator/revdb/test/test_thread.py
+++ /dev/null
@@ -1,213 +0,0 @@
-from rpython.translator.revdb.test.test_basic import BaseRecordingTests
-from rpython.translator.revdb.test.test_basic import InteractiveTests
-from rpython.rtyper.lltypesystem import rffi
-from rpython.rlib import rthread
-from rpython.rlib import revdb
-
-from rpython.translator.revdb.message import *
-
-
-_sleep = rffi.llexternal('sleep', [rffi.UINT], rffi.UINT)
-
-
-class TestThreadRecording(BaseRecordingTests):
-
- def test_thread_simple(self):
- def bootstrap():
- rthread.gc_thread_start()
- _sleep(1)
- print "BB"
- _sleep(2)
- print "BBB"
- rthread.gc_thread_die()
-
- def main(argv):
- print "A"
- rthread.start_new_thread(bootstrap, ())
- for i in range(2):
- _sleep(2)
- print "AAAA"
- return 9
-
- self.compile(main, backendopt=False, thread=True)
- out = self.run('Xx')
- # should have printed A, BB, AAAA, BBB, AAAA
- rdb = self.fetch_rdb([self.exename, 'Xx'])
- th_A = rdb.main_thread_id
- rdb.write_call("A\n")
- rdb.same_stack() # RPyGilAllocate()
- rdb.gil_release()
-
- th_B = rdb.switch_thread()
- assert th_B != th_A
- b = rdb.next('!h'); assert 300 <= b < 310 # "callback": start thread
- rdb.gil_acquire()
- rdb.gil_release()
-
- rdb.switch_thread(th_A)
- rdb.same_stack() # start_new_thread returns
- x = rdb.next(); assert x == th_B # result is the 'th_B' id
- rdb.gil_acquire()
- rdb.gil_release()
-
- rdb.switch_thread(th_B)
- rdb.same_stack() # sleep() (finishes here)
- rdb.next('i') # sleep()
- rdb.gil_acquire()
- rdb.write_call("BB\n")
- rdb.gil_release()
-
- rdb.switch_thread(th_A)
- rdb.same_stack() # sleep()
- rdb.next('i') # sleep()
- rdb.gil_acquire()
- rdb.write_call("AAAA\n")
- rdb.gil_release()
-
- rdb.switch_thread(th_B)
- rdb.same_stack() # sleep()
- rdb.next('i') # sleep()
- rdb.gil_acquire()
- rdb.write_call("BBB\n")
- rdb.gil_release()
-
- rdb.switch_thread(th_A)
- rdb.same_stack() # sleep()
- rdb.next('i') # sleep()
- rdb.gil_acquire()
- rdb.write_call("AAAA\n")
- rdb.done()
-
- def test_threadlocal(self):
- class EC(object):
- def __init__(self, value):
- self.value = value
- raw_thread_local = rthread.ThreadLocalReference(EC)
-
- def bootstrap():
- rthread.gc_thread_start()
- _sleep(1)
- ec = EC(4567)
- raw_thread_local.set(ec)
- print raw_thread_local.get().value
- assert raw_thread_local.get() is ec
- rthread.gc_thread_die()
-
- def main(argv):
- ec = EC(12)
- raw_thread_local.set(ec)
- rthread.start_new_thread(bootstrap, ())
- _sleep(2)
- print raw_thread_local.get().value
- assert raw_thread_local.get() is ec
- return 9
-
- self.compile(main, backendopt=False, thread=True)
- out = self.run('Xx')
- # should have printed 4567 and 12
- rdb = self.fetch_rdb([self.exename, 'Xx'])
- th_A = rdb.main_thread_id
- rdb.same_stack() # RPyGilAllocate()
- rdb.gil_release()
-
- th_B = rdb.switch_thread()
- assert th_B != th_A
- b = rdb.next('!h'); assert 300 <= b < 310 # "callback": start thread
- rdb.gil_acquire()
- rdb.gil_release()
-
- rdb.switch_thread(th_A)
- rdb.same_stack() # start_new_thread returns
- x = rdb.next(); assert x == th_B # result is the 'th_B' id
- rdb.gil_acquire()
- rdb.gil_release()
-
- rdb.switch_thread(th_B)
- rdb.same_stack() # sleep() (finishes here)
- rdb.next('i') # sleep()
- rdb.gil_acquire()
- rdb.write_call("4567\n")
- rdb.gil_release()
-
- rdb.switch_thread(th_A)
- rdb.same_stack() # sleep()
- rdb.next('i') # sleep()
- rdb.gil_acquire()
- rdb.write_call("12\n")
- rdb.done()
-
-
-class TestThreadInteractive(InteractiveTests):
- expected_stop_points = 5
-
- def setup_class(cls):
- from rpython.translator.revdb.test.test_basic import compile, run
- def bootstrap():
- rthread.gc_thread_start()
- _sleep(1)
- revdb.stop_point()
- _sleep(2)
- revdb.stop_point()
- rthread.gc_thread_die()
-
- def main(argv):
- revdb.stop_point()
- rthread.start_new_thread(bootstrap, ())
- for i in range(2):
- _sleep(2)
- revdb.stop_point()
- print "ok"
- return 9
-
- compile(cls, main, backendopt=False, thread=True)
- assert run(cls, '') == 'ok\n'
-
- def test_go(self):
- child = self.replay()
- for i in range(2, 6):
- child.send(Message(CMD_FORWARD, 1))
- child.expect(ANSWER_READY, i, Ellipsis,
- (i & 1) ^ 1) # thread number: either 0 or 1 here
- child.send(Message(CMD_FORWARD, 1))
- child.expect(ANSWER_AT_END)
-
-
-class TestThreadLocal(InteractiveTests):
- expected_stop_points = 2
-
- def setup_class(cls):
- from rpython.translator.revdb.test.test_basic import compile, run
- class EC(object):
- def __init__(self, value):
- self.value = value
- raw_thread_local = rthread.ThreadLocalReference(EC)
-
- def bootstrap():
- rthread.gc_thread_start()
- _sleep(1)
- ec = EC(4567)
- raw_thread_local.set(ec)
- revdb.stop_point()
- print raw_thread_local.get().value
- assert raw_thread_local.get() is ec
- rthread.gc_thread_die()
-
- def main(argv):
- revdb.stop_point()
- ec = EC(12)
- raw_thread_local.set(ec)
- rthread.start_new_thread(bootstrap, ())
- _sleep(2)
- print raw_thread_local.get().value
- assert raw_thread_local.get() is ec
- return 9
-
- compile(cls, main, backendopt=False, thread=True)
- assert run(cls, '') == '4567\n12\n'
-
- def test_go_threadlocal(self):
- child = self.replay()
- child.send(Message(CMD_FORWARD, 1))
- child.expect(ANSWER_READY, 2, Ellipsis, 1)
- child.send(Message(CMD_FORWARD, 1))
- child.expect(ANSWER_AT_END)
diff --git a/rpython/translator/revdb/test/test_weak.py b/rpython/translator/revdb/test/test_weak.py
deleted file mode 100644
--- a/rpython/translator/revdb/test/test_weak.py
+++ /dev/null
@@ -1,357 +0,0 @@
-import py, weakref
-from rpython.rlib import revdb, rgc
-from rpython.rlib.debug import debug_print
-from rpython.rlib.objectmodel import keepalive_until_here
-from rpython.rlib.rarithmetic import intmask
-from rpython.translator.revdb.message import *
-from rpython.translator.revdb.test.test_basic import BaseRecordingTests
-from rpython.translator.revdb.test.test_basic import InteractiveTests
-
-
-# Weakrefs: implemented so that the log file contains one byte
-# "afterwards_alive" or "afterwards_dead" at the point where the
-# weakref is created, and similarly one such byte at every point where
-# the weakref is dereferenced. At every point, the weakref is _alive_
-# at the moment; but the byte tells whether it should stay alive until
-# the _next_ point or not. Done by always emitting "afterwards_dead"
-# in the log, and patching that to "afterwards_alive" if later we find
-# a deref() where the weakref is still alive. (If a deref() finds the
-# weakref dead, it doesn't do any recording or patching; it simply
-# leaves the previous already-written "afterwards_dead" byte.)
-
-
-WEAKREF_AFTERWARDS_DEAD = chr(0xf2)
-WEAKREF_AFTERWARDS_ALIVE = chr(0xeb)
-
-ASYNC_FINALIZER_TRIGGER = 0xff46 - 2**16
-
-
-def get_finalizer_queue_main():
- from rpython.rtyper.lltypesystem import lltype, rffi
- #
- from rpython.translator.tool.cbuild import ExternalCompilationInfo
- eci = ExternalCompilationInfo(
- pre_include_bits=["#define foobar(x) x\n"])
- foobar = rffi.llexternal('foobar', [lltype.Signed], lltype.Signed,
- compilation_info=eci)
- class Glob:
- pass
- glob = Glob()
- class X:
- pass
- class MyFinalizerQueue(rgc.FinalizerQueue):
- Class = X
- def finalizer_trigger(self):
- glob.ping = True
- fq = MyFinalizerQueue()
- #
- def main(argv):
- glob.ping = False
- lst1 = [X() for i in range(256)]
- lst = [X() for i in range(3000)]
- for i, x in enumerate(lst):
- x.baz = i
- fq.register_finalizer(x)
- for i in range(3000):
- lst[i] = None
- if i % 300 == 150:
- rgc.collect()
- revdb.stop_point()
- j = i + glob.ping * 1000000
- assert foobar(j) == j
- if glob.ping:
- glob.ping = False
- total = 0
- while True:
- x = fq.next_dead()
- if x is None:
- break
- total = intmask(total * 3 + x.baz)
- assert foobar(total) == total
- keepalive_until_here(lst1)
- return 9
- return main
-
-def get_old_style_finalizer_main():
- from rpython.rtyper.lltypesystem import lltype, rffi
- from rpython.translator.tool.cbuild import ExternalCompilationInfo
- #
- eci = ExternalCompilationInfo(
- pre_include_bits=["#define foobar(x) x\n"])
- foobar = rffi.llexternal('foobar', [lltype.Signed], lltype.Signed,
- compilation_info=eci, _nowrapper=True)
- class Glob:
- pass
- glob = Glob()
- class X:
- def __del__(self):
- assert foobar(-7) == -7
- glob.count += 1
- def main(argv):
- glob.count = 0
- lst = [X() for i in range(3000)]
- x = -1
- for i in range(3000):
- lst[i] = None
- if i % 300 == 150:
- rgc.collect()
- revdb.stop_point()
- x = glob.count
- assert foobar(x) == x
- print x
- return 9
- return main
-
-
-class TestRecording(BaseRecordingTests):
-
- def test_weakref_create(self):
- class X:
- pass
- class Glob:
- pass
- glob = Glob()
- def main(argv):
- glob.r1 = weakref.ref(X())
- glob.r2 = weakref.ref(X())
- glob.r3 = weakref.ref(X())
- return 9
- self.compile(main, backendopt=False)
- out = self.run('Xx')
- rdb = self.fetch_rdb([self.exename, 'Xx'])
- # find the extra WEAKREF_DEAD
- x = rdb.next('c'); assert x == WEAKREF_AFTERWARDS_DEAD
- x = rdb.next('c'); assert x == WEAKREF_AFTERWARDS_DEAD
- x = rdb.next('c'); assert x == WEAKREF_AFTERWARDS_DEAD
- x = rdb.next('q'); assert x == 0 # number of stop points
- assert rdb.done()
-
- def test_weakref_deref_nondead(self):
- class X:
- pass
- class Glob:
- pass
- glob = Glob()
- def main(argv):
- x1 = X(); x2 = X()
- r1 = weakref.ref(x1) # (*)
- r2 = weakref.ref(x2) # (*)
- for i in range(8500):
- assert r1() is x1 # (*)
- assert r2() is x2 # (*)
- return 9
- self.compile(main, backendopt=False)
- out = self.run('Xx')
- rdb = self.fetch_rdb([self.exename, 'Xx'])
- # find the 2 + 16998 first WEAKREF_xxx (all "(*)" but the last two)
- for i in range(2 + 16998):
- x = rdb.next('c'); assert x == WEAKREF_AFTERWARDS_ALIVE
- for i in range(2):
- x = rdb.next('c'); assert x == WEAKREF_AFTERWARDS_DEAD
- x = rdb.next('q'); assert x == 0 # number of stop points
- assert rdb.done()
-
- def test_prebuilt_weakref(self):
- class X:
- pass
- x1 = X()
- x1.foobar = 9
- wr = weakref.ref(x1)
- def main(argv):
- X().foobar = 43
- return wr().foobar
- self.compile(main, backendopt=False)
- out = self.run('Xx')
- rdb = self.fetch_rdb([self.exename, 'Xx'])
- # the weakref is prebuilt, so doesn't generate any WEAKREF_xxx
- x = rdb.next('q'); assert x == 0 # number of stop points
- assert rdb.done()
-
- def test_finalizer_light_ignored(self):
- py.test.skip("lightweight finalizers could be skipped, but that "
- "requires also skipping (instead of recording) any "
- "external call they do")
- class X:
- @rgc.must_be_light_finalizer
- def __del__(self):
- pass
- def main(argv):
- lst = [X() for i in range(3000)]
- for i in range(3000):
- lst[i] = None
- if i % 300 == 150:
- rgc.collect()
- revdb.stop_point()
- return 9
- self.compile(main, backendopt=False)
- out = self.run('Xx')
- rdb = self.fetch_rdb([self.exename, 'Xx'])
- x = rdb.next('q'); assert x == 3000 # number of stop points
- assert rdb.done()
-
- def test_finalizer_queue(self):
- main = get_finalizer_queue_main()
- self.compile(main, backendopt=False)
- out = self.run('Xx')
- rdb = self.fetch_rdb([self.exename, 'Xx'])
- uid_seen = set()
- totals = []
- for i in range(3000):
- triggered = False
- if rdb.is_special_packet():
- time, = rdb.special_packet(ASYNC_FINALIZER_TRIGGER, 'q')
- assert time == i + 1
- y = intmask(rdb.next('q')); assert y == -1
- triggered = True
- rdb.gil_release()
- rdb.same_stack() #
- j = rdb.next() # call to foobar()
- rdb.gil_acquire()
- assert j == i + 1000000 * triggered
- if triggered:
- lst = []
- while True:
- uid = intmask(rdb.next())
- if uid == -1:
- break
- assert uid > 0 and uid not in uid_seen
- uid_seen.add(uid)
- lst.append(uid)
- rdb.gil_release()
- rdb.same_stack() #
- totals.append((lst, intmask(rdb.next()))) # call to foobar()
- rdb.gil_acquire()
- x = rdb.next('q'); assert x == 3000 # number of stop points
- #
- assert 1500 <= len(uid_seen) <= 3000
- d = dict(zip(sorted(uid_seen), range(len(uid_seen))))
- for lst, expected in totals:
- total = 0
- for uid in lst:
- total = intmask(total * 3 + d[uid])
- assert total == expected
-
- def test_old_style_finalizer(self):
- main = get_old_style_finalizer_main()
- self.compile(main, backendopt=False)
- out = self.run('Xx')
- assert 1500 < int(out) <= 3000
- rdb = self.fetch_rdb([self.exename, 'Xx'])
- seen_uids = set()
- for i in range(3000):
- triggered = False
- if rdb.is_special_packet():
- time, = rdb.special_packet(ASYNC_FINALIZER_TRIGGER, 'q')
- assert time == i + 1
- triggered = True
- x = intmask(rdb.next())
- while True:
- assert x != -1
- assert x not in seen_uids
- seen_uids.add(x)
- rdb.same_stack()
- y = intmask(rdb.next())
- assert y == -7 # from the __del__
- x = intmask(rdb.next())
- if x == -1:
- break
- rdb.same_stack()
- x = rdb.next()
- assert x == len(seen_uids)
- assert len(seen_uids) == int(out)
- rdb.write_call(out)
- x = rdb.next('q'); assert x == 3000 # number of stop points
-
-
-class TestReplayingWeakref(InteractiveTests):
- expected_stop_points = 1
-
- def setup_class(cls):
- from rpython.translator.revdb.test.test_basic import compile, run
-
- class X:
- def __init__(self, s):
- self.s = s
- prebuilt = X('prebuilt')
-
- def make(s):
- lst = [prebuilt] + [X(c) for c in s]
- keepalive = lst[-1]
- return [weakref.ref(x) for x in lst], keepalive
-
- def main(argv):
- lst, keepalive = make(argv[0])
- expected = ['prebuilt'] + [c for c in argv[0]]
- dead = [False] * len(lst)
- for j in range(17000):
- outp = []
- for i in range(len(lst)):
- v = lst[i]()
- debug_print(v)
- if dead[i]:
- assert v is None
- elif v is None:
- outp.append('<DEAD>')
- dead[i] = True
- else:
- outp.append(v.s)
- assert v.s == expected[i]
- print ''.join(outp)
- if (j % 1000) == 999:
- debug_print('============= COLLECT ===========')
- rgc.collect()
- debug_print('------ done', j, '.')
- assert not dead[0]
- assert not dead[-1]
- keepalive_until_here(keepalive)
- revdb.stop_point()
- return 9
- compile(cls, main, backendopt=False)
- output = run(cls, '')
- lines = output.splitlines()
- assert lines[-1].startswith('prebuilt') and lines[-1].endswith(
- str(cls.exename)[-1])
- assert (len(lines[-1]) + output.count('<DEAD>') ==
- len('prebuilt') + len(str(cls.exename)))
-
- def test_replaying_weakref(self):
- child = self.replay()
- # the asserts are replayed; if we get here it means they passed again
- child.send(Message(CMD_FORWARD, 1))
- child.expect(ANSWER_AT_END)
-
-
-class TestReplayingFinalizerQueue(InteractiveTests):
- expected_stop_points = 3000
-
- def setup_class(cls):
- from rpython.translator.revdb.test.test_basic import compile, run
- main = get_finalizer_queue_main()
- compile(cls, main, backendopt=False)
- run(cls, '')
-
- def test_replaying_finalizer_queue(self):
- child = self.replay()
- child.send(Message(CMD_FORWARD, 3001))
- child.expect(ANSWER_AT_END)
-
-
-class TestReplayingOldStyleFinalizer(InteractiveTests):
- expected_stop_points = 3000
-
- def setup_class(cls):
- from rpython.translator.revdb.test.test_basic import compile, run
- main = get_old_style_finalizer_main()
- compile(cls, main, backendopt=False)
- run(cls, '')
-
- def test_replaying_old_style_finalizer(self):
- child = self.replay()
- child.send(Message(CMD_FORWARD, 3001))
- child.expect(ANSWER_AT_END)
-
- def test_bug1(self):
- child = self.replay()
- for i in range(50):
- child.send(Message(CMD_FORWARD, i))
- child.expect_ready()
More information about the pypy-commit
mailing list