def test_eval_state_update(self): """ Tests that eval may update the state of the program. """ # We will try to corrupt this variable with a stateful operation. test_var = 'pure' # NOQA db = Qdb( uuid='eval_test', cmd_manager=self.cmd_manager, host=self.tracer_host, port=self.tracer_port, redirect_output=False, green=True, ) gyield() self.server.session_store.send_to_tracer( uuid=db.uuid, event=fmt_msg('eval', "test_var = 'mutated'") ) self.server.session_store.send_to_tracer( uuid=db.uuid, event=fmt_msg('continue') ) db.set_trace(stop=True) self.server.session_store.slaughter(db.uuid) self.assertEqual(test_var, 'mutated')
def test_locals(self): """ Tests accessing the locals. """ tracer = self.MockTracer() tracer.curframe_locals = {'a': 'a'} cmd_manager = self.cmd_manager cmd_manager.start(tracer, '') gyield() self.server.session_store.send_to_tracer( uuid=tracer.uuid, event=fmt_msg('locals') ) command_locals_called = NonLocal(False) def test_command_locals(cmd_manager, tracer, payload): command_locals_called.value = True type(self.cmd_manager).command_locals(cmd_manager, tracer, payload) cmd_locals = partial(test_command_locals, cmd_manager) with gevent.Timeout(0.1, False), \ patch.object(cmd_manager, 'command_locals', cmd_locals): cmd_manager.next_command(tracer) self.assertTrue(command_locals_called.value) tracer.start.assert_called() # Start always gets called. self.server.session_store.slaughter(tracer.uuid)
def test_eval_pprint(self, input_, exc, output): """ Tests that evaling code returns the proper results. """ prints = [] class cmd_manager(type(self.cmd_manager)): """ Captures print commands to make assertions on them. """ def send_print(self, input_, exc, output): prints.append({'input': input_, 'exc': exc, 'output': output}) db = Qdb( uuid='eval_test', cmd_manager=cmd_manager(), host=self.tracer_host, port=self.tracer_port, redirect_output=False, ) gyield() self.server.session_store.send_to_tracer(uuid=db.uuid, event=fmt_msg( 'pprint', input_)) self.server.session_store.send_to_tracer(uuid=db.uuid, event=fmt_msg('continue')) db.set_trace(stop=True) self.server.session_store.slaughter(db.uuid) self.assertTrue(prints) print_ = prints[0] self.assertEqual(print_['input'], input_) self.assertEqual(print_['exc'], exc) self.assertEqual(print_['output'], output)
def test_stack_transpose_no_skip(self, direction): """ Tests moving up the stack. """ events = [] def capture_event(self, event, payload): events.append(fmt_msg(event, payload)) class cmd_manager(type(self.cmd_manager)): """ Wrap send_stack by just capturing the output to make assertions on it. """ def send_stack(self, tracer): with patch.object(cmd_manager, 'send_event', capture_event): super(cmd_manager, self).send_stack(tracer) db = Qdb( uuid='test_' + direction, cmd_manager=cmd_manager(), host=self.tracer_host, port=self.tracer_port, redirect_output=False, green=True, ) gyield() if direction == 'down': # We are already located in the bottom frame, let's go up one # so that we may try going down. self.server.session_store.send_to_tracer( uuid=db.uuid, event=fmt_msg('up') ) self.server.session_store.send_to_tracer( uuid=db.uuid, event=fmt_msg(direction) ) self.server.session_store.send_to_tracer( uuid=db.uuid, event=fmt_msg('disable', 'soft') ) gyield() db.set_trace() start_ind = events[-2]['p']['index'] shift_ind = events[-1]['p']['index'] if direction == 'up': self.assertEqual(start_ind - shift_ind, 1) elif direction == 'down': self.assertEqual(shift_ind - start_ind, 1) else: self.fail("direction is not 'up' or 'down'") # wut did u do?
def test_eval_timeout(self): """ Tests that evaluating user repl commands will raise Timeouts. """ def g(): while True: pass prints = [] class cmd_manager(type(self.cmd_manager)): """ Captures print commands to make assertions on them. """ def send_print(self, input_, exc, output): prints.append({ 'input': input_, 'exc': exc, 'output': output }) to_eval = 'g()' db = Qdb( uuid='timeout_test', cmd_manager=cmd_manager(), host=self.tracer_host, port=self.tracer_port, redirect_output=False, execution_timeout=1, green=True, ) gyield() self.server.session_store.send_to_tracer( uuid=db.uuid, event=fmt_msg('eval', to_eval) ) self.server.session_store.send_to_tracer( uuid=db.uuid, event=fmt_msg('continue') ) db.set_trace(stop=True) self.server.session_store.slaughter(db.uuid) self.assertTrue(prints) print_ = prints[0] self.assertEqual(print_['input'], to_eval) self.assertTrue(print_['exc']) self.assertEqual( print_['output'], db.exception_serializer(QdbExecutionTimeout(to_eval, 1)) )
def test_send_stack_results(self, use_skip_fn): """ Tests that the results from sending the stack are accurate. WARNING: This test uses lines of it's own source as string literals, be sure to edit the source and the string if you make any changes. """ def skip_fn(filename): return not fix_filename(__file__) in filename events = [] def capture_event(self, event, payload): events.append(fmt_msg(event, payload)) class cmd_manager(type(self.cmd_manager)): """ Wrap send_stack by just capturing the output to make assertions on it. """ def send_stack(self, tracer): with patch.object(cmd_manager, 'send_event', capture_event): super(cmd_manager, self).send_stack(tracer) db = Qdb( uuid='send_stack_test', cmd_manager=cmd_manager(), host=self.tracer_host, port=self.tracer_port, redirect_output=False, skip_fn=skip_fn if use_skip_fn else None, green=True, ) gyield() self.server.session_store.send_to_tracer( uuid=db.uuid, event=fmt_msg('continue') ) db.set_trace(stop=True) self.assertTrue(events) # EDIT IN BOTH PLACES event = events[0] if use_skip_fn: # Assert that we actually suppressed some frames. self.assertTrue(len(event['p']['stack']) < len(db.stack)) self.assertEqual( # I love dictionaries so much! event['p']['stack'][event['p']['index']]['code'], ' self.assertTrue(events) # EDIT IN BOTH PLACES', ) self.server.session_store.slaughter(db.uuid)
def test_client_orphan_session(self): """ Tests that a client makes it into the session store without a tracer attaching if attach_timeout is set to ALLOW_ORPHANS or 0. """ with QdbServer(tracer_server=QdbNopServer(), client_host='localhost', client_port=0, attach_timeout=ALLOW_ORPHANS) as server: client = create_connection('ws://localhost:%d%s' % (server.client_server.server_port, DEFAULT_ROUTE_FMT.format(uuid='test'))) send_client_event(client, 'start', '') # yield to the session_store to let it get attached. gyield() self.assertIn('test', server.session_store)
def test_client_orphan_session(self): """ Tests that a client makes it into the session store without a tracer attaching if attach_timeout is set to ALLOW_ORPHANS or 0. """ with QdbServer(tracer_server=QdbNopServer(), client_host='localhost', client_port=0, attach_timeout=ALLOW_ORPHANS) as server: client = create_connection( 'ws://localhost:%d%s' % (server.client_server.server_port, DEFAULT_ROUTE_FMT.format(uuid='test')) ) send_client_event(client, 'start', '') # yield to the session_store to let it get attached. gyield() self.assertIn('test', server.session_store)
def test_why_are_you_executing_all_these_commands(self): db = Qdb( uuid='send_stack_test', cmd_manager=self.cmd_manager, host=self.tracer_host, port=self.tracer_port, redirect_output=False, green=True, ) gyield() for n in range(sys.getrecursionlimit()): self.server.session_store.send_to_tracer(uuid=db.uuid, event=fmt_msg( 'eval', 'None')) self.server.session_store.send_to_tracer(uuid=db.uuid, event=fmt_msg('continue')) with gevent.Timeout(1): db.set_trace(stop=True)
def test_tracer_orphan_session(self): """ Tests that a tracer makes it into the session_store without a client attaching if attach_timeout is set to ALLOW_ORPHANS or 0. """ with QdbServer(client_server=QdbNopServer(), tracer_host='localhost', tracer_port=0, attach_timeout=ALLOW_ORPHANS) as server: tracer = gevent.socket.create_connection( ('localhost', server.tracer_server.server_port)) send_tracer_event(tracer, 'start', { 'uuid': 'test', 'auth': '', 'local': (0, 0), }) # yield to the session_store to let it get attached. gyield() self.assertIn('test', server.session_store)
def test_eval_results(self, input_, exc, output): """ Tests that evaling code returns the proper results. """ prints = [] class cmd_manager(type(self.cmd_manager)): """ Captures print commands to make assertions on them. """ def send_print(self, input_, exc, output): prints.append({ 'input': input_, 'exc': exc, 'output': output }) db = Qdb( uuid='eval_test', cmd_manager=cmd_manager(), host=self.tracer_host, port=self.tracer_port, redirect_output=False, green=True, ) gyield() self.server.session_store.send_to_tracer( uuid=db.uuid, event=fmt_msg('eval', input_) ) self.server.session_store.send_to_tracer( uuid=db.uuid, event=fmt_msg('continue') ) db.set_trace(stop=True) self.server.session_store.slaughter(db.uuid) self.assertTrue(prints) print_ = prints[0] self.assertEqual(print_['input'], input_) self.assertEqual(print_['exc'], exc) self.assertEqual(print_['output'], output)
def test_tracer_orphan_session(self): """ Tests that a tracer makes it into the session_store without a client attaching if attach_timeout is set to ALLOW_ORPHANS or 0. """ with QdbServer(client_server=QdbNopServer(), tracer_host='localhost', tracer_port=0, attach_timeout=ALLOW_ORPHANS) as server: tracer = gevent.socket.create_connection( ('localhost', server.tracer_server.server_port) ) send_tracer_event(tracer, 'start', { 'uuid': 'test', 'auth': '', 'local': (0, 0), }) # yield to the session_store to let it get attached. gyield() self.assertIn('test', server.session_store)
def test_why_are_you_executing_all_these_commands(self): db = Qdb( uuid='send_stack_test', cmd_manager=self.cmd_manager, host=self.tracer_host, port=self.tracer_port, redirect_output=False, green=True, ) gyield() for n in range(sys.getrecursionlimit()): self.server.session_store.send_to_tracer( uuid=db.uuid, event=fmt_msg('eval', 'None') ) self.server.session_store.send_to_tracer( uuid=db.uuid, event=fmt_msg('continue') ) with gevent.Timeout(1): db.set_trace(stop=True)
def test_send_disabled(self): """ Tests that disabling sends a 'disabled' message back to the server. """ class cmd_manager(type(self.cmd_manager)): disabled = False def send_disabled(self): self.disabled = True db = Qdb( uuid='send_disabled_test', cmd_manager=cmd_manager(), host=self.tracer_host, port=self.tracer_port, redirect_output=False, green=True, ) gyield() db.set_trace(stop=False) db.disable() self.assertTrue(db.cmd_manager.disabled) self.server.session_store.slaughter(db.uuid)