def test_set_step(self): """ Tests the functionality of set_step by asserting that it only executes the next line and no more. """ db = Qdb(cmd_manager=QueueCommandManager) # Queue up a step command. db.cmd_manager.enqueue(lambda t: t.set_step()) stepped = False with Timeout(0.1, False): db.set_trace() stepped = True self.assertTrue(stepped) db.disable() db = Qdb(cmd_manager=QueueCommandManager) db.cmd_manager.enqueue(lambda t: t.set_step()) db.cmd_manager.user_wait(0.2) stepped = over_stepped = False with Timeout(0.1, False): db.set_trace() stepped = True over_stepped = True self.assertTrue(stepped) self.assertFalse(over_stepped)
def test_set_trace_without_stop(self): """ Asserts that calling set_trace with stop=False will start tracing but not stop. WARNING: This test relies on the relative line numbers inside the test. """ db = Qdb(cmd_manager=QueueCommandManager) line_offset = 8 # The difference in the set_break call and line_3. db.set_break( self.filename, sys._getframe().f_lineno + line_offset, ) db.cmd_manager.user_wait(0.2) line_1 = line_2 = line_3 = False with Timeout(0.1, False): db.set_trace(stop=False) # Should not stop us here. line_1 = True line_2 = True line_3 = True # Since we are stepping, we should not hit this line. self.assertTrue(line_1) self.assertTrue(line_2) # We should have still stopped at this breakpoint if we are tracing. self.assertFalse(line_3) db.disable() db = Qdb(cmd_manager=NopCommandManager) line_1 = False with Timeout(0.1, False): db.set_trace(stop=False) line_1 = True self.assertTrue(line_1)
def test_set_trace_without_stop(self): """ Asserts that calling set_trace with stop=False will start tracing but not stop. WARNING: This test relies on the relative line numbers inside the test. """ db = Qdb(cmd_manager=QueueCommandManager) line_offset = 8 # The difference in the set_break call and line_3. db.set_break( self.filename, sys._getframe().f_lineno + line_offset, ) db.cmd_manager.user_wait(0.2) line_1 = line_2 = line_3 = False with Timeout(0.1, False): db.set_trace(stop=False) # Should not stop us here. line_1 = True line_2 = True line_3 = True # Since we are stepping, we should not hit this line. self.assertTrue(line_1) self.assertTrue(line_2) # We should have still stopped at this breakpoint if we are tracing. self.assertFalse(line_3) db.disable() db = Qdb(cmd_manager=NopCommandManager) line_1 = False with Timeout(0.1, False): db.set_trace(stop=False) line_1 = True self.assertTrue(line_1)
def test_set_step(self): """ Tests the functionality of set_step by asserting that it only executes the next line and no more. """ db = Qdb(cmd_manager=QueueCommandManager) # Queue up a step command. db.cmd_manager.enqueue(lambda t: t.set_step()) stepped = False with Timeout(0.1, False): db.set_trace() stepped = True self.assertTrue(stepped) db.disable() db = Qdb(cmd_manager=QueueCommandManager) db.cmd_manager.enqueue(lambda t: t.set_step()) db.cmd_manager.user_wait(0.2) stepped = over_stepped = False with Timeout(0.1, False): db.set_trace() stepped = True over_stepped = True self.assertTrue(stepped) self.assertFalse(over_stepped)
def test_function_call_next_step(self): """ Tests the functionality of next and step when calling functions. This checks to make sure the function is stepped into and can be stepped over. """ cmd_manager = QueueCommandManager() db = Qdb(cmd_manager=cmd_manager) # Queue up a next command to next over the function call. cmd_manager.enqueue(lambda t: t.set_next(t.curframe)) # Queue up a sleep so that we block after calling next. # This would cause us to NOT execute the f_called[0] = True line of f # had we only called set_step. This is asserted afterwards. cmd_manager.user_wait(0.2) # A mutable structure to check if f is called. f_called = NonLocal(False) def f(): f_called.value = True with Timeout(0.1, False): db.set_trace() f() # We hit that line in f, so it should now be True. self.assertTrue(f_called.value) # Assert that we are currently executing the line we think we should # be executing. Since we are just stepping, this should be setting # curframe each time. self.assertEqual( db.get_line(self.filename, db.curframe.f_lineno), ' db.get_line(self.filename, db.curframe.f_lineno),' ) db.disable() cmd_manager = QueueCommandManager() db = Qdb(cmd_manager=cmd_manager) f_called = NonLocal(False) # This time we will be only stepping, so we should not execute the # entire call to f. cmd_manager.enqueue(lambda t: t.set_step()) cmd_manager.user_wait(1.2) with Timeout(0.1, False): db.set_trace() f() # We should not have hit this line in f. self.assertFalse(f_called.value) # Since we only stepped once, this is the last time we set the frame. self.assertEqual( db.get_line(self.filename, db.curframe.f_lineno), ' f_called.value = True' )
def test_function_call_next_step(self): """ Tests the functionality of next and step when calling functions. This checks to make sure the function is stepped into and can be stepped over. """ cmd_manager = QueueCommandManager() db = Qdb(cmd_manager=cmd_manager) # Queue up a next command to next over the function call. cmd_manager.enqueue(lambda t: t.set_next(t.curframe)) # Queue up a sleep so that we block after calling next. # This would cause us to NOT execute the f_called[0] = True line of f # had we only called set_step. This is asserted afterwards. cmd_manager.user_wait(0.2) # A mutable structure to check if f is called. f_called = NonLocal(False) def f(): f_called.value = True with Timeout(0.1, False): db.set_trace() f() # We hit that line in f, so it should now be True. self.assertTrue(f_called.value) # Assert that we are currently executing the line we think we should # be executing. Since we are just stepping, this should be setting # curframe each time. self.assertEqual( db.get_line(self.filename, db.curframe.f_lineno), ' db.get_line(self.filename, db.curframe.f_lineno),' ) db.disable() cmd_manager = QueueCommandManager() db = Qdb(cmd_manager=cmd_manager) f_called = NonLocal(False) # This time we will be only stepping, so we should not execute the # entire call to f. cmd_manager.enqueue(lambda t: t.set_step()) cmd_manager.user_wait(1.2) with Timeout(0.1, False): db.set_trace() f() # We should not have hit this line in f. self.assertFalse(f_called.value) # Since we only stepped once, this is the last time we set the frame. self.assertEqual( db.get_line(self.filename, db.curframe.f_lineno), ' f_called.value = True' )
def test_conditional_breakpoint_timeout(self): """ Tests conditional breakpoints that cause timeouts. WARNING: This test relies on the relative line numbers inside the test. """ stopped = [False] def stop(): stopped[0] = True return True # Execute the assertion. line = None cond = 'g()' cmd_manager = QueueCommandManager() db = Qdb(cmd_manager=cmd_manager, execution_timeout=1) cmd_manager.enqueue(lambda t: stop() and self.assertEqual(line, 1)) line_offset = 10 # Set a condition that will time out. db.set_break( self.filename, sys._getframe().f_lineno + line_offset, cond='g()', ) db.set_trace(stop=False) def g(): while True: pass line = 1 line = 2 line = 3 db.disable() errors = [e['p'] for e in cmd_manager.sent if e['e'] == 'error'] self.assertEqual(len(errors), 1) error = errors[0] self.assertEqual(error['type'], 'condition') negative_line_offset = 14 exc = QdbExecutionTimeout(cond, db.execution_timeout) self.assertEqual( error['data'], { 'line': sys._getframe().f_lineno - negative_line_offset, 'cond': cond, 'exc': type(exc).__name__, 'output': db.exception_serializer(exc), } ) # Make sure we stopped when we raised the exception. self.assertTrue(stopped[0])
def test_conditional_breakpoint_timeout(self): """ Tests conditional breakpoints that cause timeouts. WARNING: This test relies on the relative line numbers inside the test. """ stopped = [False] def stop(): stopped[0] = True return True # Execute the assertion. line = None cond = 'g()' cmd_manager = QueueCommandManager() db = Qdb(cmd_manager=cmd_manager, execution_timeout=1) cmd_manager.enqueue(lambda t: stop() and self.assertEqual(line, 1)) line_offset = 10 # Set a condition that will time out. db.set_break( self.filename, sys._getframe().f_lineno + line_offset, cond='g()', ) db.set_trace(stop=False) def g(): while True: pass line = 1 line = 2 line = 3 db.disable() errors = [e['p'] for e in cmd_manager.sent if e['e'] == 'error'] self.assertEqual(len(errors), 1) error = errors[0] self.assertEqual(error['type'], 'condition') negative_line_offset = 14 exc = QdbExecutionTimeout(cond, db.execution_timeout) self.assertEqual( error['data'], { 'line': sys._getframe().f_lineno - negative_line_offset, 'cond': cond, 'exc': type(exc).__name__, 'output': db.exception_serializer(exc), } ) # Make sure we stopped when we raised the exception. self.assertTrue(stopped[0])
def test_conditional_breakpoint_raises(self): """ Tests conditional breakpoints that raise an exception. WARNING: This test relies on the relative line numbers inside the test. """ line = None exc = ValueError('lol wut r u doing?') cond = 'raiser()' stopped = [False] def stop(): stopped[0] = True return True # Execute the assertion. cmd_manager = QueueCommandManager() db = Qdb(cmd_manager=cmd_manager) cmd_manager.enqueue(lambda t: stop() and self.assertEqual(line, 1)) line_offset = 9 # Set a condition that will raise a ValueError. db.set_break( self.filename, sys._getframe().f_lineno + line_offset, cond=cond, ) db.set_trace(stop=False) def raiser(): raise exc line = 1 line = 2 # This line number is used in the data assertion. line = 3 db.disable() errors = [e['p'] for e in cmd_manager.sent if e['e'] == 'error'] self.assertEqual(len(errors), 1) error = errors[0] self.assertEqual(error['type'], 'condition') negative_line_offset = 13 self.assertEqual( error['data'], { 'line': sys._getframe().f_lineno - negative_line_offset, 'cond': cond, 'exc': type(exc).__name__, 'output': db.exception_serializer(exc), } ) # Make sure we stopped when we raised the exception. self.assertTrue(stopped[0])
def test_conditional_breakpoint_raises(self): """ Tests conditional breakpoints that raise an exception. WARNING: This test relies on the relative line numbers inside the test. """ line = None exc = ValueError('lol wut r u doing?') cond = 'raiser()' stopped = [False] def stop(): stopped[0] = True return True # Execute the assertion. cmd_manager = QueueCommandManager() db = Qdb(cmd_manager=cmd_manager) cmd_manager.enqueue(lambda t: stop() and self.assertEqual(line, 1)) line_offset = 9 # Set a condition that will raise a ValueError. db.set_break( self.filename, sys._getframe().f_lineno + line_offset, cond=cond, ) db.set_trace(stop=False) def raiser(): raise exc line = 1 line = 2 # This line number is used in the data assertion. line = 3 db.disable() errors = [e['p'] for e in cmd_manager.sent if e['e'] == 'error'] self.assertEqual(len(errors), 1) error = errors[0] self.assertEqual(error['type'], 'condition') negative_line_offset = 13 self.assertEqual( error['data'], { 'line': sys._getframe().f_lineno - negative_line_offset, 'cond': cond, 'exc': type(exc).__name__, 'output': db.exception_serializer(exc), } ) # Make sure we stopped when we raised the exception. self.assertTrue(stopped[0])
def test_redirect_stderr(self): """ Tests that stderr is stored on the tracer. """ sys.stderr = stderr = StringIO() db = Qdb(cmd_manager=NopCommandManager) data_to_write = 'stderr' db.set_trace(stop=False) print >> sys.stderr, data_to_write, # Write some data to stderr. db.disable() self.assertEqual(db.stderr.getvalue(), data_to_write) # Assert that the stream was restored. self.assertIs(sys.stderr, stderr)
def test_redirect_stderr(self): """ Tests that stderr is stored on the tracer. """ sys.stderr = stderr = StringIO() db = Qdb(cmd_manager=NopCommandManager) data_to_write = 'stderr' db.set_trace(stop=False) print >> sys.stderr, data_to_write, # Write some data to stderr. db.disable() self.assertEqual(db.stderr.getvalue(), data_to_write) # Assert that the stream was restored. self.assertIs(sys.stderr, stderr)
def test_redirect_stdout(self): """ Tests that stdout is stored on the tracer. """ sys.stdout = stdout = StringIO() db = Qdb(cmd_manager=OutputCatchingNopCommandManager) data_to_write = 'stdout' db.set_trace(stop=False) print data_to_write, # Write some data to stdout. db.disable() msg = db.cmd_manager.msgs[0] self.assertEqual(msg.input_, '<stdout>') self.assertFalse(msg.exc) self.assertEqual(msg.output, data_to_write) self.assertEqual(stdout.getvalue(), data_to_write) # Assert that the stream was restored. self.assertIs(sys.stdout, stdout)
def test_clear_output_buffers(self): """ Tests that we can clear the output buffers to free up some memory. """ db = Qdb(cmd_manager=NopCommandManager) stdout_data, stderr_data = 'stdout', 'stderr' db.set_trace(stop=False) print stdout_data, print >> sys.stderr, stderr_data, db.disable() # Assert that the data actually got written. self.assertEqual(db.stdout.getvalue(), stdout_data) self.assertEqual(db.stderr.getvalue(), stderr_data) db.clear_output_buffers() # Assert that the data actually got cleared. self.assertEqual(db.stdout.getvalue(), '') self.assertEqual(db.stderr.getvalue(), '')
def test_redirect_stdout(self): """ Tests that stdout is stored on the tracer. """ sys.stdout = stdout = StringIO() cmd_manager = OutputCatchingNopCommandManager() db = Qdb(cmd_manager=cmd_manager) data_to_write = 'stdout' db.set_trace(stop=False) # Write some data to stdout. print(data_to_write, end='') db.disable() msg = cmd_manager.msgs[0] self.assertEqual(msg.input_, '<stdout>') self.assertFalse(msg.exc) self.assertEqual(msg.output, data_to_write) self.assertEqual(stdout.getvalue(), data_to_write) # Assert that the stream was restored. self.assertIs(sys.stdout, stdout)
def test_send_disabled(self): """ Tests that disabling sends a 'disabled' message back to the server. """ class cmd_manager(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, ) sleep(0.01) db.set_trace(stop=False) db.disable() self.assertTrue(db.cmd_manager.disabled) self.server.session_store.slaughter(db.uuid)
def test_send_disabled(self): """ Tests that disabling sends a 'disabled' message back to the server. """ class cmd_manager(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, ) sleep(0.01) db.set_trace(stop=False) db.disable() self.assertTrue(db.cmd_manager.disabled) self.server.session_store.slaughter(db.uuid)
def test_clear_output_buffers(self): """ Tests that we can clear the output buffers to free up some memory. """ db = Qdb(cmd_manager=NopCommandManager) stdout_data, stderr_data = 'stdout', 'stderr' db.set_trace(stop=False) print stdout_data, print >> sys.stderr, stderr_data, db.disable() # Assert that the data actually got written. self.assertEqual(db.stdout.getvalue(), stdout_data) self.assertEqual(db.stderr.getvalue(), stderr_data) db.clear_output_buffers() # Assert that the data actually got cleared. self.assertEqual(db.stdout.getvalue(), '') self.assertEqual(db.stderr.getvalue(), '')
def test_redirect_stderr(self): """ Tests that stderr is stored on the tracer. """ sys.stderr = stderr = StringIO() cmd_manager = OutputCatchingNopCommandManager() db = Qdb(cmd_manager=cmd_manager) data_to_write = 'stderr' db.set_trace(stop=False) # Write some data to stderr. print(data_to_write, end='', file=sys.stderr) db.disable() msg = cmd_manager.msgs[0] self.assertEqual(msg.input_, '<stderr>') self.assertFalse(msg.exc) self.assertEqual(msg.output, data_to_write) self.assertEqual(stderr.getvalue(), data_to_write) # Assert that the stream was restored. self.assertIs(sys.stderr, stderr)
def test_set_continue_with_breaks(self): """ Tests the behavior of continue when there are breakpoints in the mix. WARNING: This test relies on the relative line numbers inside the test. """ db = Qdb(cmd_manager=QueueCommandManager) line_offset = 8 # The difference in the set_break call and line_2. db.set_break( self.filename, sys._getframe().f_lineno + line_offset, ) db.cmd_manager.enqueue(lambda t: t.set_continue()) db.cmd_manager.user_wait(0.2) line_1 = line_2 = line_3 = False with Timeout(0.1, False): db.set_trace() line_1 = True line_2 = True line_3 = True # Assert we only got to line_1 because of the breakpoint. # These are split up to give more helpful messages if the test fails. self.assertTrue(line_1) self.assertFalse(line_2) self.assertFalse(line_3) # We are still in stepping mode so we should be reporting the stack. self.assertEqual( db.get_line(self.filename, db.curframe.f_lineno), ' db.get_line(self.filename, db.curframe.f_lineno),' ) sys.settrace(None) db.disable() db = Qdb(cmd_manager=QueueCommandManager) line_2_offset = 13 # The difference in the set_break call and line_2. line_3_offset = 10 # THe difference in the set_break call and line_3. db.set_break( self.filename, sys._getframe().f_lineno + line_2_offset, ) db.set_break( self.filename, sys._getframe().f_lineno + line_3_offset, ) db.cmd_manager.enqueue(lambda t: t.set_continue()) db.cmd_manager.enqueue(lambda t: t.set_continue()) db.cmd_manager.user_wait(0.2) line_1 = line_2 = line_3 = False with Timeout(0.1, False): db.set_trace() line_1 = True line_2 = True line_3 = True self.assertTrue(line_1) self.assertTrue(line_2) self.assertFalse(line_3) self.assertEqual( db.get_line(self.filename, db.curframe.f_lineno), ' db.get_line(self.filename, db.curframe.f_lineno),' )
def test_set_continue_with_breaks(self): """ Tests the behavior of continue when there are breakpoints in the mix. WARNING: This test relies on the relative line numbers inside the test. """ cmd_manager = QueueCommandManager() db = Qdb(cmd_manager=cmd_manager) line_offset = 8 # The difference in the set_break call and line_2. db.set_break( self.filename, sys._getframe().f_lineno + line_offset, ) cmd_manager.enqueue(lambda t: t.set_continue()) cmd_manager.user_wait(0.2) line_1 = line_2 = line_3 = False with Timeout(0.1, False): db.set_trace() line_1 = True line_2 = True line_3 = True # Assert we only got to line_1 because of the breakpoint. # These are split up to give more helpful messages if the test fails. self.assertTrue(line_1) self.assertFalse(line_2) self.assertFalse(line_3) # We are still in stepping mode so we should be reporting the stack. self.assertEqual( db.get_line(self.filename, db.curframe.f_lineno), ' db.get_line(self.filename, db.curframe.f_lineno),' ) sys.settrace(None) db.disable() cmd_manager = QueueCommandManager() db = Qdb(cmd_manager=cmd_manager) line_2_offset = 13 # The difference in the set_break call and line_2. line_3_offset = 10 # THe difference in the set_break call and line_3. db.set_break( self.filename, sys._getframe().f_lineno + line_2_offset, ) db.set_break( self.filename, sys._getframe().f_lineno + line_3_offset, ) cmd_manager.enqueue(lambda t: t.set_continue()) cmd_manager.enqueue(lambda t: t.set_continue()) cmd_manager.user_wait(0.2) line_1 = line_2 = line_3 = False with Timeout(0.1, False): db.set_trace() line_1 = True line_2 = True line_3 = True self.assertTrue(line_1) self.assertTrue(line_2) self.assertFalse(line_3) self.assertEqual( db.get_line(self.filename, db.curframe.f_lineno), ' db.get_line(self.filename, db.curframe.f_lineno),' )