def test_crossfile_breakpoint(pyfile, run_as, start_method): @pyfile def script1(): from dbgimporter import import_and_enable_debugger # noqa def do_something(): print('do something') @pyfile def script2(): from dbgimporter import import_and_enable_debugger import_and_enable_debugger() import script1 script1.do_something() print('Done') bp_script1_line = 3 bp_script2_line = 4 with DebugSession() as session: session.initialize( target=(run_as, script2), start_method=start_method, ignore_unobserved=[Event('continued')], ) session.set_breakpoints(script1, lines=[bp_script1_line]) session.set_breakpoints(script2, lines=[bp_script2_line]) session.start_debugging() hit = session.wait_for_thread_stopped() frames = hit.stacktrace.body['stackFrames'] assert bp_script2_line == frames[0]['line'] assert compare_path(frames[0]['source']['path'], script2, show=False) session.send_request('continue').wait_for_response(freeze=False) hit = session.wait_for_thread_stopped() frames = hit.stacktrace.body['stackFrames'] assert bp_script1_line == frames[0]['line'] assert compare_path(frames[0]['source']['path'], script1, show=False) session.send_request('continue').wait_for_response(freeze=False) session.wait_for_exit()
def test_path_with_ampersand(run_as, start_method): bp_line = 4 testfile = os.path.join(BP_TEST_ROOT, 'a&b', 'test.py') with DebugSession() as session: session.initialize( target=(run_as, testfile), start_method=start_method, ignore_unobserved=[Event('continued')], ) session.set_breakpoints(testfile, [bp_line]) session.start_debugging() hit = session.wait_for_thread_stopped('breakpoint') frames = hit.stacktrace.body['stackFrames'] assert compare_path(frames[0]['source']['path'], testfile, show=False) session.send_request('continue').wait_for_response(freeze=False) session.wait_for_exit()
def test_flask_breakpoint_no_multiproc(bp_target, start_method): bp_file, bp_line, bp_name = { 'code': (FLASK1_APP, 11, 'home'), 'template': (FLASK1_TEMPLATE, 8, 'template') }[bp_target] with DebugSession() as session: _initialize_flask_session_no_multiproc(session, start_method) bp_var_content = 'Flask-Jinja-Test' session.set_breakpoints(bp_file, [bp_line]) session.start_debugging() # wait for Flask web server to start wait_for_connection(FLASK_PORT) link = FLASK_LINK web_request = get_web_content(link, {}) thread_stopped = session.wait_for_next( Event('stopped'), ANY.dict_with({'reason': 'breakpoint'})) assert thread_stopped.body['threadId'] is not None tid = thread_stopped.body['threadId'] resp_stacktrace = session.send_request('stackTrace', arguments={ 'threadId': tid, }).wait_for_response() assert resp_stacktrace.body['totalFrames'] > 0 frames = resp_stacktrace.body['stackFrames'] assert frames[0] == { 'id': ANY.int, 'name': bp_name, 'source': { 'sourceReference': ANY.int, 'path': ANY.such_that(lambda s: compare_path(s, bp_file)), }, 'line': bp_line, 'column': 1, } fid = frames[0]['id'] resp_scopes = session.send_request('scopes', arguments={ 'frameId': fid }).wait_for_response() scopes = resp_scopes.body['scopes'] assert len(scopes) > 0 resp_variables = session.send_request( 'variables', arguments={ 'variablesReference': scopes[0]['variablesReference'] }).wait_for_response() variables = list(v for v in resp_variables.body['variables'] if v['name'] == 'content') assert variables == [{ 'name': 'content', 'type': 'str', 'value': repr(bp_var_content), 'presentationHint': { 'attributes': ['rawString'] }, 'evaluateName': 'content' }] session.send_request('continue').wait_for_response(freeze=False) web_content = web_request.wait_for_response() assert web_content.find(bp_var_content) != -1 # shutdown to web server link = FLASK_LINK + 'exit' get_web_content(link).wait_for_response() session.wait_for_exit()
def test_flask_breakpoint_multiproc(start_method): env = { 'FLASK_APP': 'app', 'FLASK_ENV': 'development', 'FLASK_DEBUG': '1', } if platform.system() != 'Windows': locale = 'en_US.utf8' if platform.system( ) == 'Linux' else 'en_US.UTF-8' env.update({ 'LC_ALL': locale, 'LANG': locale, }) with DebugSession() as parent_session: parent_session.initialize( start_method=start_method, target=('module', 'flask'), multiprocess=True, program_args=[ 'run', ], ignore_unobserved=[Event('stopped'), Event('continued')], debug_options=['Jinja'], cwd=FLASK1_ROOT, env=env, expected_returncode=ANY.int, # No clean way to kill Flask server ) bp_line = 11 bp_var_content = 'Flask-Jinja-Test' parent_session.set_breakpoints(FLASK1_APP, [bp_line]) parent_session.start_debugging() with parent_session.connect_to_next_child_session() as child_session: child_session.send_request('setBreakpoints', arguments={ 'source': { 'path': FLASK1_APP }, 'breakpoints': [ { 'line': bp_line }, ], }).wait_for_response() child_session.start_debugging() # wait for Flask server to start wait_for_connection(FLASK_PORT) web_request = get_web_content(FLASK_LINK, {}) thread_stopped = child_session.wait_for_next( Event('stopped', ANY.dict_with({'reason': 'breakpoint'}))) assert thread_stopped.body['threadId'] is not None tid = thread_stopped.body['threadId'] resp_stacktrace = child_session.send_request( 'stackTrace', arguments={ 'threadId': tid, }).wait_for_response() assert resp_stacktrace.body['totalFrames'] > 0 frames = resp_stacktrace.body['stackFrames'] assert frames[0] == { 'id': ANY.int, 'name': 'home', 'source': { 'sourceReference': ANY.int, 'path': ANY.such_that(lambda s: compare_path(s, FLASK1_APP)), }, 'line': bp_line, 'column': 1, } fid = frames[0]['id'] resp_scopes = child_session.send_request('scopes', arguments={ 'frameId': fid }).wait_for_response() scopes = resp_scopes.body['scopes'] assert len(scopes) > 0 resp_variables = child_session.send_request( 'variables', arguments={ 'variablesReference': scopes[0]['variablesReference'] }).wait_for_response() variables = [ v for v in resp_variables.body['variables'] if v['name'] == 'content' ] assert variables == [{ 'name': 'content', 'type': 'str', 'value': repr(bp_var_content), 'presentationHint': { 'attributes': ['rawString'] }, 'evaluateName': 'content' }] child_session.send_request('continue').wait_for_response( freeze=False) web_content = web_request.wait_for_response() assert web_content.find(bp_var_content) != -1 # shutdown to web server link = FLASK_LINK + 'exit' get_web_content(link).wait_for_response() child_session.wait_for_termination() parent_session.wait_for_exit()
def test_flask_exception_no_multiproc(ex_type, start_method): ex_line = { 'handled': 21, 'unhandled': 33, }[ex_type] with DebugSession() as session: _initialize_flask_session_no_multiproc(session, start_method) session.send_request('setExceptionBreakpoints', arguments={ 'filters': ['raised', 'uncaught'], }).wait_for_response() session.start_debugging() # wait for Flask web server to start wait_for_connection(FLASK_PORT) base_link = FLASK_LINK link = base_link + ex_type if base_link.endswith('/') else ('/' + ex_type) web_request = get_web_content(link, {}) thread_stopped = session.wait_for_next( Event('stopped', ANY.dict_with({'reason': 'exception'}))) assert thread_stopped == Event( 'stopped', ANY.dict_with({ 'reason': 'exception', 'text': ANY.such_that(lambda s: s.endswith('ArithmeticError')), 'description': 'Hello' })) tid = thread_stopped.body['threadId'] resp_exception_info = session.send_request('exceptionInfo', arguments={ 'threadId': tid, }).wait_for_response() exception = resp_exception_info.body assert exception == { 'exceptionId': ANY.such_that(lambda s: s.endswith('ArithmeticError')), 'breakMode': 'always', 'description': 'Hello', 'details': { 'message': 'Hello', 'typeName': ANY.such_that(lambda s: s.endswith('ArithmeticError')), 'source': ANY.such_that(lambda s: compare_path(s, FLASK1_APP)), 'stackTrace': ANY.such_that(lambda s: True) } } resp_stacktrace = session.send_request('stackTrace', arguments={ 'threadId': tid, }).wait_for_response() assert resp_stacktrace.body['totalFrames'] > 0 frames = resp_stacktrace.body['stackFrames'] assert frames[0] == { 'id': ANY.int, 'name': 'bad_route_' + ex_type, 'source': { 'sourceReference': ANY.int, 'path': ANY.such_that(lambda s: compare_path(s, FLASK1_APP)), }, 'line': ex_line, 'column': 1, } session.send_request('continue').wait_for_response(freeze=False) # ignore response for exception tests web_request.wait_for_response() # shutdown to web server link = base_link + 'exit' if base_link.endswith('/') else '/exit' get_web_content(link).wait_for_response() session.wait_for_exit()
def test_django_breakpoint_no_multiproc(debug_session, bp_file, bp_line, bp_name, start_method): debug_session.initialize( start_method=start_method, target=('file', DJANGO1_MANAGE), program_args=['runserver', '--noreload', '--nothreading'], debug_options=['Django'], cwd=DJANGO1_ROOT, expected_returncode=ANY.int, # No clean way to kill Flask server ) bp_var_content = 'Django-Django-Test' debug_session.set_breakpoints(bp_file, [bp_line]) debug_session.start_debugging() # wait for Django server to start wait_for_connection(DJANGO_PORT) web_request = get_web_content(DJANGO_LINK, {}) thread_stopped = debug_session.wait_for_next( Event('stopped', ANY.dict_with({'reason': 'breakpoint'}))) assert thread_stopped.body['threadId'] is not None tid = thread_stopped.body['threadId'] resp_stacktrace = debug_session.send_request('stackTrace', arguments={ 'threadId': tid, }).wait_for_response() assert resp_stacktrace.body['totalFrames'] > 1 frames = resp_stacktrace.body['stackFrames'] assert frames[0] == { 'id': 1, 'name': bp_name, 'source': { 'sourceReference': ANY, 'path': ANY.such_that(lambda s: compare_path(s, bp_file)), }, 'line': bp_line, 'column': 1, } fid = frames[0]['id'] resp_scopes = debug_session.send_request('scopes', arguments={ 'frameId': fid }).wait_for_response() scopes = resp_scopes.body['scopes'] assert len(scopes) > 0 resp_variables = debug_session.send_request( 'variables', arguments={ 'variablesReference': scopes[0]['variablesReference'] }).wait_for_response() variables = list(v for v in resp_variables.body['variables'] if v['name'] == 'content') assert variables == [{ 'name': 'content', 'type': 'str', 'value': repr(bp_var_content), 'presentationHint': { 'attributes': ['rawString'] }, 'evaluateName': 'content' }] debug_session.send_request('continue').wait_for_response() debug_session.wait_for_next(Event('continued')) web_content = web_request.wait_for_response() assert web_content.find(bp_var_content) != -1 # shutdown to web server link = DJANGO_LINK + 'exit' get_web_content(link).wait_for_response()
def test_django_breakpoint_multiproc(debug_session, start_method): debug_session.initialize( start_method=start_method, target=('file', DJANGO1_MANAGE), multiprocess=True, program_args=[ 'runserver', ], debug_options=['Django'], cwd=DJANGO1_ROOT, ignore_events=[Event('stopped'), Event('continued')], expected_returncode=ANY.int, # No clean way to kill Flask server ) bp_line = 40 bp_var_content = 'Django-Django-Test' debug_session.set_breakpoints(DJANGO1_MANAGE, [bp_line]) debug_session.start_debugging() child_session = _wait_for_child_process(debug_session) child_session.send_request('setBreakpoints', arguments={ 'source': { 'path': DJANGO1_MANAGE }, 'breakpoints': [ { 'line': bp_line }, ], }).wait_for_response() child_session.start_debugging() # wait for Django server to start while True: child_session.proceed() o = child_session.wait_for_next(Event('output')) if get_url_from_str(o.body['output']) is not None: break web_request = get_web_content(DJANGO_LINK, {}) thread_stopped = child_session.wait_for_next( Event('stopped', ANY.dict_with({'reason': 'breakpoint'}))) assert thread_stopped.body['threadId'] is not None tid = thread_stopped.body['threadId'] resp_stacktrace = child_session.send_request('stackTrace', arguments={ 'threadId': tid, }).wait_for_response() assert resp_stacktrace.body['totalFrames'] > 0 frames = resp_stacktrace.body['stackFrames'] assert frames[0] == { 'id': ANY.int, 'name': 'home', 'source': { 'sourceReference': ANY.int, 'path': ANY.such_that(lambda s: compare_path(s, DJANGO1_MANAGE)), }, 'line': bp_line, 'column': 1, } fid = frames[0]['id'] resp_scopes = child_session.send_request('scopes', arguments={ 'frameId': fid }).wait_for_response() scopes = resp_scopes.body['scopes'] assert len(scopes) > 0 resp_variables = child_session.send_request( 'variables', arguments={ 'variablesReference': scopes[0]['variablesReference'] }).wait_for_response() variables = list(v for v in resp_variables.body['variables'] if v['name'] == 'content') assert variables == [{ 'name': 'content', 'type': 'str', 'value': repr(bp_var_content), 'presentationHint': { 'attributes': ['rawString'] }, 'evaluateName': 'content' }] child_session.send_request('continue').wait_for_response() child_session.wait_for_next(Event('continued')) web_content = web_request.wait_for_response() assert web_content.find(bp_var_content) != -1 # shutdown to web server link = DJANGO_LINK + 'exit' get_web_content(link).wait_for_response()
def test_django_exception_no_multiproc(debug_session, ex_type, ex_line, start_method): debug_session.initialize( start_method=start_method, target=('file', DJANGO1_MANAGE), program_args=['runserver', '--noreload', '--nothreading'], debug_options=['Django'], cwd=DJANGO1_ROOT, expected_returncode=ANY.int, # No clean way to kill Flask server ) debug_session.send_request('setExceptionBreakpoints', arguments={ 'filters': ['raised', 'uncaught'], }).wait_for_response() debug_session.start_debugging() wait_for_connection(DJANGO_PORT) base_link = DJANGO_LINK link = base_link + ex_type if base_link.endswith('/') else ('/' + ex_type) web_request = get_web_content(link, {}) thread_stopped = debug_session.wait_for_next( Event('stopped', ANY.dict_with({'reason': 'exception'}))) assert thread_stopped == Event( 'stopped', ANY.dict_with({ 'reason': 'exception', 'text': ANY.such_that(lambda s: s.endswith('ArithmeticError')), 'description': 'Hello' })) tid = thread_stopped.body['threadId'] resp_exception_info = debug_session.send_request('exceptionInfo', arguments={ 'threadId': tid, }).wait_for_response() exception = resp_exception_info.body assert exception == { 'exceptionId': ANY.such_that(lambda s: s.endswith('ArithmeticError')), 'breakMode': 'always', 'description': 'Hello', 'details': { 'message': 'Hello', 'typeName': ANY.such_that(lambda s: s.endswith('ArithmeticError')), 'source': ANY.such_that(lambda s: compare_path(s, DJANGO1_MANAGE)), 'stackTrace': ANY.such_that(lambda s: True), } } resp_stacktrace = debug_session.send_request('stackTrace', arguments={ 'threadId': tid, }).wait_for_response() assert resp_stacktrace.body['totalFrames'] > 1 frames = resp_stacktrace.body['stackFrames'] assert frames[0] == { 'id': ANY, 'name': 'bad_route_' + ex_type, 'source': { 'sourceReference': ANY, 'path': ANY.such_that(lambda s: compare_path(s, DJANGO1_MANAGE)), }, 'line': ex_line, 'column': 1, } debug_session.send_request('continue').wait_for_response() debug_session.wait_for_next(Event('continued')) # ignore response for exception tests web_request.wait_for_response() # shutdown to web server link = base_link + 'exit' if base_link.endswith('/') else '/exit' get_web_content(link).wait_for_response()
def test_vsc_exception_options_raise_without_except(pyfile, run_as, start_method, raised, uncaught): @pyfile def code_to_debug(): from dbgimporter import import_and_enable_debugger import_and_enable_debugger() def raise_without_except(): raise ArithmeticError('bad code') raise_without_except() ex_line = 4 filters = [] filters += ['raised'] if raised == 'raisedOn' else [] filters += ['uncaught'] if uncaught == 'uncaughtOn' else [] with DebugSession() as session: session.initialize( target=(run_as, code_to_debug), start_method=start_method, ignore_unobserved=[Event('continued'), Event('stopped')], expected_returncode=ANY.int, ) session.send_request('setExceptionBreakpoints', { 'filters': filters }).wait_for_response() session.start_debugging() expected = ANY.dict_with({ 'exceptionId': ANY.such_that(lambda s: s.endswith('ArithmeticError')), 'description': 'bad code', 'breakMode': 'always' if raised == 'raisedOn' else 'unhandled', 'details': ANY.dict_with({ 'typeName': ANY.such_that(lambda s: s.endswith('ArithmeticError')), 'message': 'bad code', 'source': ANY.such_that(lambda s: compare_path(code_to_debug, s)), }), }) if raised == 'raisedOn': hit = session.wait_for_thread_stopped(reason='exception') frames = hit.stacktrace.body['stackFrames'] assert ex_line == frames[0]['line'] resp_exc_info = session.send_request('exceptionInfo', { 'threadId': hit.thread_id }).wait_for_response() assert resp_exc_info.body == expected session.send_request('continue').wait_for_response(freeze=False) # NOTE: debugger stops at each frame if raised and is uncaught # This behavior can be changed by updating 'notify_on_handled_exceptions' # setting we send to pydevd to notify only once. In our test code, we have # two frames, hence two stops. session.wait_for_thread_stopped(reason='exception') session.send_request('continue').wait_for_response(freeze=False) if uncaught == 'uncaughtOn': hit = session.wait_for_thread_stopped(reason='exception') frames = hit.stacktrace.body['stackFrames'] assert ex_line == frames[0]['line'] resp_exc_info = session.send_request('exceptionInfo', { 'threadId': hit.thread_id }).wait_for_response() assert resp_exc_info.body == expected session.send_request('continue').wait_for_response(freeze=False) session.wait_for_exit()
def test_vsc_exception_options_raise_with_except(pyfile, run_as, start_method, raised, uncaught): @pyfile def code_to_debug(): from dbgimporter import import_and_enable_debugger import_and_enable_debugger() def raise_with_except(): try: raise ArithmeticError('bad code') except Exception: pass raise_with_except() ex_line = 5 filters = [] filters += ['raised'] if raised == 'raisedOn' else [] filters += ['uncaught'] if uncaught == 'uncaughtOn' else [] with DebugSession() as session: session.initialize( target=(run_as, code_to_debug), start_method=start_method, ignore_unobserved=[Event('continued')], ) session.send_request('setExceptionBreakpoints', { 'filters': filters }).wait_for_response() session.start_debugging() expected = ANY.dict_with({ 'exceptionId': ANY.such_that(lambda s: s.endswith('ArithmeticError')), 'description': 'bad code', 'breakMode': 'always' if raised == 'raisedOn' else 'unhandled', 'details': ANY.dict_with({ 'typeName': ANY.such_that(lambda s: s.endswith('ArithmeticError')), 'message': 'bad code', 'source': ANY.such_that(lambda s: compare_path(code_to_debug, s)), }), }) if raised == 'raisedOn': hit = session.wait_for_thread_stopped(reason='exception') frames = hit.stacktrace.body['stackFrames'] assert ex_line == frames[0]['line'] resp_exc_info = session.send_request('exceptionInfo', { 'threadId': hit.thread_id }).wait_for_response() assert resp_exc_info.body == expected session.send_request('continue').wait_for_response(freeze=False) # uncaught should not 'stop' matter since the exception is caught session.wait_for_exit()
def __eq__(self, other): if not (isinstance(other, bytes) or isinstance(other, unicode)): return NotImplemented return compare_path(self.s, other, show=False)