Author: Armin Rigo <ar...@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() _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit