[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