Ejemplo n.º 1
0
def test_justmycode_frames(pyfile, run_as, start_method, jmc):
    @pyfile
    def code_to_debug():
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()
        print('break here')  #@bp

    line_numbers = get_marked_line_numbers(code_to_debug)
    with DebugSession() as session:
        session.initialize(
            target=(run_as, code_to_debug),
            start_method=start_method,
            ignore_unobserved=[Event('continued')],
            debug_options=[] if jmc == 'jmcOn' else ['DebugStdLib'])

        bp_line = line_numbers['bp']

        actual_bps = session.set_breakpoints(code_to_debug, [bp_line])
        actual_bps = [bp['line'] for bp in actual_bps]
        session.start_debugging()

        hit = session.wait_for_thread_stopped()
        frames = hit.stacktrace.body['stackFrames']
        assert frames[0] == ANY.dict_with({
            'line':
            bp_line,
            'source':
            ANY.dict_with({'path': Path(code_to_debug)})
        })

        if jmc == 'jmcOn':
            assert len(frames) == 1
            session.send_request('stepIn', {
                'threadId': hit.thread_id
            }).wait_for_response()
            # 'step' should terminate the debuggee
        else:
            assert len(frames) >= 1
            session.send_request('stepIn', {
                'threadId': hit.thread_id
            }).wait_for_response()

            # 'step' should enter stdlib
            hit2 = session.wait_for_thread_stopped()
            frames2 = hit2.stacktrace.body['stackFrames']
            assert frames2[0]['source']['path'] != Path(code_to_debug)

            # 'continue' should terminate the debuggee
            session.send_request('continue').wait_for_response(freeze=False)

        session.wait_for_exit()
Ejemplo n.º 2
0
def test_stop_on_entry(pyfile, run_as, start_method):

    @pyfile
    def code_to_debug():
        import backchannel
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()
        backchannel.write_json('done')

    with DebugSession() as session:
        session.initialize(
            target=(run_as, code_to_debug),
            start_method=start_method,
            debug_options=['StopOnEntry'],
            use_backchannel=True,
        )
        session.start_debugging()

        thread_stopped, resp_stacktrace, tid, _ = session.wait_for_thread_stopped(reason='entry')
        frames = resp_stacktrace.body['stackFrames']
        assert frames[0]['line'] == 1
        assert frames[0]['source']['path'] == Path(code_to_debug)

        session.send_request('continue').wait_for_response(freeze=False)
        session.wait_for_termination()

        assert session.read_json() == 'done'

        session.wait_for_exit()
Ejemplo n.º 3
0
def test_with_dot_remote_root(pyfile, tmpdir, run_as, start_method):

    @pyfile
    def code_to_debug():
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()
        import os
        import backchannel
        backchannel.write_json(os.path.abspath(__file__))
        print('done')

    bp_line = 6
    path_local = tmpdir.mkdir('local').join('code_to_debug.py').strpath
    path_remote = tmpdir.mkdir('remote').join('code_to_debug.py').strpath

    dir_local = os.path.dirname(path_local)
    dir_remote = os.path.dirname(path_remote)

    copyfile(code_to_debug, path_local)
    copyfile(code_to_debug, path_remote)

    with DebugSession() as session:
        session.initialize(
            target=(run_as, path_remote),
            start_method=start_method,
            ignore_unobserved=[Event('continued')],
            use_backchannel=True,
            path_mappings=[{
                'localRoot': dir_local,
                'remoteRoot': '.',
            }],
            cwd=dir_remote,
        )
        session.set_breakpoints(path_remote, [bp_line])
        session.start_debugging()
        hit = session.wait_for_thread_stopped('breakpoint')
        frames = hit.stacktrace.body['stackFrames']
        print('Local Path: ' + path_local)
        print('Frames: ' + str(frames))
        assert frames[0]['source']['path'] == Path(path_local)

        remote_code_path = session.read_json()
        assert path_remote == Path(remote_code_path)

        session.send_request('continue').wait_for_response(freeze=False)
        session.wait_for_exit()
Ejemplo n.º 4
0
def test_stop_on_entry(pyfile, run_as, start_method, with_bp):

    @pyfile
    def code_to_debug():
        import backchannel # @bp
        # import_and_enable_debugger()
        backchannel.write_json('done')

    with DebugSession() as session:
        session.initialize(
            target=(run_as, code_to_debug),
            start_method=start_method,
            debug_options=['StopOnEntry'],
            use_backchannel=True,
        )
        if bool(with_bp):
            line_numbers = get_marked_line_numbers(code_to_debug)
            bp_line = line_numbers['bp']
            session.set_breakpoints(code_to_debug, [bp_line])

        session.start_debugging()

        if bool(with_bp):
            thread_stopped, resp_stacktrace, thread_id, _ = session.wait_for_thread_stopped(reason='breakpoint')
            frames = resp_stacktrace.body['stackFrames']
            assert frames[0]['line'] == 1
            assert frames[0]['source']['path'] == Path(code_to_debug)

            session.send_request('next', {'threadId': thread_id}).wait_for_response()
            thread_stopped, resp_stacktrace, thread_id, _ = session.wait_for_thread_stopped(reason='step')
            frames = resp_stacktrace.body['stackFrames']
            assert frames[0]['line'] == 3
            assert frames[0]['source']['path'] == Path(code_to_debug)
        else:
            thread_stopped, resp_stacktrace, tid, _ = session.wait_for_thread_stopped(reason='entry')
            frames = resp_stacktrace.body['stackFrames']
            assert frames[0]['line'] == 1
            assert frames[0]['source']['path'] == Path(code_to_debug)

        session.send_request('continue').wait_for_response(freeze=False)
        session.wait_for_termination()

        assert session.read_json() == 'done'

        session.wait_for_exit()
Ejemplo n.º 5
0
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')  # @exception_line
            except Exception:
                pass

        raise_with_except()

    line_numbers = get_marked_line_numbers(code_to_debug)
    ex_line = line_numbers['exception_line']
    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': Path(code_to_debug),
            }),
        })

        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()
Ejemplo n.º 6
0
def test_module_events(pyfile, run_as, start_method):
    @pyfile
    def module2():
        # import_and_enable_debugger()
        def do_more_things():
            print('done')

    @pyfile
    def module1():
        # import_and_enable_debugger()
        import module2

        def do_something():
            module2.do_more_things()

    @pyfile
    def test_code():
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()
        from module1 import do_something
        do_something()

    bp_line = 3
    with DebugSession() as session:
        session.initialize(
            target=(run_as, test_code),
            start_method=start_method,
            ignore_unobserved=[Event('stopped')],
        )
        session.set_breakpoints(module2, [bp_line])
        session.start_debugging()

        session.wait_for_thread_stopped()
        modules = session.all_occurrences_of(Event('module'))
        modules = [(m.body['module']['name'], m.body['module']['path'])
                   for m in modules]
        assert modules[:3] == [
            ('module2', Path(module2)),
            ('module1', Path(module1)),
            ('__main__', Path(test_code)),
        ]

        session.send_request('continue').wait_for_response(freeze=False)
        session.wait_for_exit()
Ejemplo n.º 7
0
def test_flask_template_exception_no_multiproc(start_method):
    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
        part = 'badtemplate'
        link = base_link + part if base_link.endswith('/') else ('/' + part)
        web_request = get_web_content(link, {})

        hit = session.wait_for_thread_stopped()
        frames = hit.stacktrace.body['stackFrames']
        assert frames[0] == ANY.dict_with({
            'id': ANY.dap_id,
            'name': 'template' if sys.version_info[0] >= 3 else 'Jinja2 TemplateSyntaxError',
            'source': ANY.dict_with({
                'sourceReference': ANY.dap_id,
                'path': Path(FLASK1_BAD_TEMPLATE),
            }),
            'line': 8,
            'column': 1,
        })

        resp_exception_info = session.send_request(
            'exceptionInfo',
            arguments={'threadId': hit.thread_id, }
        ).wait_for_response()
        exception = resp_exception_info.body
        assert exception == ANY.dict_with({
            'exceptionId': ANY.such_that(lambda s: s.endswith('TemplateSyntaxError')),
            'breakMode': 'always',
            'description': ANY.such_that(lambda s: s.find('doesnotexist') > -1),
            'details': ANY.dict_with({
                'message': ANY.such_that(lambda s: s.find('doesnotexist') > -1),
                'typeName': ANY.such_that(lambda s: s.endswith('TemplateSyntaxError')),
            })
        })

        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()
Ejemplo n.º 8
0
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 frames[0]['source']['path'] == Path(script2)

        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 frames[0]['source']['path'] == Path(script1)

        session.send_request('continue').wait_for_response(freeze=False)
        session.wait_for_exit()
Ejemplo n.º 9
0
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,
        )
        session.set_breakpoints(testfile, [bp_line])
        session.start_debugging()
        hit = session.wait_for_thread_stopped('breakpoint')
        frames = hit.stacktrace.body['stackFrames']
        assert frames[0]['source']['path'] == Path(testfile)

        session.send_request('continue').wait_for_response(freeze=False)
        session.wait_for_exit()
Ejemplo n.º 10
0
def test_path_with_unicode(run_as, start_method):
    bp_line = 6
    testfile = os.path.join(BP_TEST_ROOT, u'ನನ್ನ_ಸ್ಕ್ರಿಪ್ಟ್.py')

    with DebugSession() as session:
        session.initialize(
            target=(run_as, testfile),
            start_method=start_method,
        )
        session.set_breakpoints(testfile, [bp_line])
        session.start_debugging()
        hit = session.wait_for_thread_stopped('breakpoint')
        frames = hit.stacktrace.body['stackFrames']
        assert frames[0]['source']['path'] == Path(testfile)
        assert u'ಏನಾದರೂ_ಮಾಡು' == frames[0]['name']

        session.send_request('continue').wait_for_response(freeze=False)
        session.wait_for_exit()
Ejemplo n.º 11
0
def test_stop_on_entry(run_as, start_method, tmpdir):
    testfile = tmpdir.join('test.py')
    with testfile.open('w') as stream:
        stream.write('''
stop_here = 1
print('done')
''')

    with DebugSession() as session:
        session.initialize(
            target=(run_as, str(testfile)),
            start_method=start_method,
            debug_options=['StopOnEntry'],
        )

        session.start_debugging()
        hit = session.wait_for_thread_stopped()
        frames = hit.stacktrace.body['stackFrames']
        assert frames[0]['source']['path'] == Path(str(testfile))

        session.send_request('continue').wait_for_response(freeze=False)
        session.wait_for_exit()
Ejemplo n.º 12
0
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.dap_id,
            'name': bp_name,
            'source': {
                'sourceReference': ANY.dap_id,
                'path': Path(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()
Ejemplo n.º 13
0
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', '--port', str(FLASK_PORT)],
            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.dap_id,
                'name': 'home',
                'source': {
                    'sourceReference': ANY.dap_id,
                    'path': Path(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()
Ejemplo n.º 14
0
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': Path(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.dap_id,
            'name': 'bad_route_' + ex_type,
            'source': {
                'sourceReference': ANY.dap_id,
                'path': Path(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()
Ejemplo n.º 15
0
def test_django_breakpoint_multiproc(start_method):
    with DebugSession() as parent_session:
        parent_session.initialize(
            start_method=start_method,
            target=('file', DJANGO1_MANAGE),
            multiprocess=True,
            program_args=['runserver'],
            debug_options=['Django'],
            cwd=DJANGO1_ROOT,
            ignore_unobserved=[Event('stopped')],
            expected_returncode=ANY.int,  # No clean way to kill Django server
        )

        bp_line = 40
        bp_var_content = 'Django-Django-Test'
        parent_session.set_breakpoints(DJANGO1_MANAGE, [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': 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 + 'home', {})

            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.dap_id,
                'name': 'home',
                'source': {
                    'sourceReference': ANY.dap_id,
                    'path': Path(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(
                freeze=False)

            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()

            child_session.wait_for_termination()
            parent_session.wait_for_exit()
Ejemplo n.º 16
0
def test_with_path_mappings(pyfile, tmpdir, run_as, start_method):
    @pyfile
    def code_to_debug():
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()
        import os
        import sys
        import backchannel
        json = backchannel.read_json()
        call_me_back_dir = json['call_me_back_dir']
        sys.path.append(call_me_back_dir)

        import call_me_back

        def call_func():
            print('break here')

        backchannel.write_json(os.path.abspath(__file__))
        call_me_back.call_me_back(call_func)
        print('done')

    bp_line = 13
    path_local = tmpdir.mkdir('local').join('code_to_debug.py').strpath
    path_remote = tmpdir.mkdir('remote').join('code_to_debug.py').strpath

    dir_local = os.path.dirname(path_local)
    dir_remote = os.path.dirname(path_remote)

    copyfile(code_to_debug, path_local)
    copyfile(code_to_debug, path_remote)

    call_me_back_dir = get_test_root('call_me_back')

    with DebugSession() as session:
        session.initialize(
            target=(run_as, path_remote),
            start_method=start_method,
            use_backchannel=True,
            path_mappings=[{
                'localRoot': dir_local,
                'remoteRoot': dir_remote,
            }],
        )
        session.set_breakpoints(path_remote, [bp_line])
        session.start_debugging()
        session.write_json({'call_me_back_dir': call_me_back_dir})
        hit = session.wait_for_thread_stopped('breakpoint')

        frames = hit.stacktrace.body['stackFrames']
        assert frames[0]['source']['path'] == Path(path_local)
        source_reference = frames[0]['source']['sourceReference']
        assert source_reference == 0  # Mapped files should be found locally.

        assert frames[1]['source']['path'].endswith('call_me_back.py')
        source_reference = frames[1]['source']['sourceReference']
        assert source_reference > 0  # Unmapped file should have a source reference.

        resp_variables = session.send_request('source',
                                              arguments={
                                                  'sourceReference':
                                                  source_reference
                                              }).wait_for_response()
        assert "def call_me_back(callback):" in (
            resp_variables.body['content'])

        remote_code_path = session.read_json()
        assert path_remote == Path(remote_code_path)

        session.send_request('continue').wait_for_response(freeze=False)
        session.wait_for_exit()
Ejemplo n.º 17
0
def test_exception_stack(pyfile, run_as, start_method, max_frames):
    @pyfile
    def code_to_debug():
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()

        def do_something(n):
            if n <= 0:
                raise ArithmeticError('bad code')  # @unhandled
            do_something2(n - 1)

        def do_something2(n):
            do_something(n - 1)

        do_something(100)

    if max_frames == 'all':
        # trace back compresses repeated text
        min_expected_lines = 100
        max_expected_lines = 220
        args = {'maxExceptionStackFrames': 0}
    elif max_frames == 'default':
        # default is all frames
        min_expected_lines = 100
        max_expected_lines = 220
        args = {}
    else:
        min_expected_lines = 10
        max_expected_lines = 21
        args = {'maxExceptionStackFrames': 10}

    line_numbers = get_marked_line_numbers(code_to_debug)
    with DebugSession() as session:
        session.initialize(
            target=(run_as, code_to_debug),
            start_method=start_method,
            ignore_unobserved=[Event('continued')],
            expected_returncode=ANY.int,
            args=args,
        )
        session.send_request('setExceptionBreakpoints', {
            'filters': ['uncaught']
        }).wait_for_response()
        session.start_debugging()

        hit = session.wait_for_thread_stopped(reason='exception')
        frames = hit.stacktrace.body['stackFrames']
        assert frames[0]['line'] == line_numbers['unhandled']

        resp_exc_info = session.send_request('exceptionInfo', {
            'threadId': hit.thread_id
        }).wait_for_response()

        expected = ANY.dict_with({
            'exceptionId':
            Regex('ArithmeticError'),
            'description':
            'bad code',
            'breakMode':
            'unhandled',
            'details':
            ANY.dict_with({
                'typeName': Regex('ArithmeticError'),
                'message': 'bad code',
                'source': Path(code_to_debug),
            }),
        })
        assert resp_exc_info.body == expected
        stack_str = resp_exc_info.body['details']['stackTrace']
        stack_line_count = len(stack_str.split('\n'))
        assert min_expected_lines <= stack_line_count <= max_expected_lines

        session.send_request('continue').wait_for_response(freeze=False)

        session.wait_for_exit()
Ejemplo n.º 18
0
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')  # @exception_line

        raise_without_except()

    line_numbers = get_marked_line_numbers(code_to_debug)
    ex_line = line_numbers['exception_line']
    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':
                Path(code_to_debug),
            }),
        })

        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()

            expected = ANY.dict_with({
                'exceptionId':
                ANY.such_that(lambda s: s.endswith('ArithmeticError')),
                'description':
                'bad code',
                'breakMode':
                'unhandled',  # Only difference from previous expected is breakMode.
                'details':
                ANY.dict_with({
                    'typeName':
                    ANY.such_that(lambda s: s.endswith('ArithmeticError')),
                    'message':
                    'bad code',
                    'source':
                    Path(code_to_debug),
                }),
            })

            assert resp_exc_info.body == expected
            session.send_request('continue').wait_for_response(freeze=False)

        session.wait_for_exit()
Ejemplo n.º 19
0
def test_django_template_exception_no_multiproc(start_method):
    with DebugSession() as session:
        session.initialize(
            start_method=start_method,
            target=('file', DJANGO1_MANAGE),
            program_args=[
                'runserver', '--noreload', '--nothreading',
                str(DJANGO_PORT)
            ],
            debug_options=['Django'],
            cwd=DJANGO1_ROOT,
            expected_returncode=ANY.int,  # No clean way to kill Django server
        )

        session.send_request('setExceptionBreakpoints',
                             arguments={
                                 'filters': ['raised', 'uncaught'],
                             }).wait_for_response()

        session.start_debugging()

        wait_for_connection(DJANGO_PORT)

        link = DJANGO_LINK + 'badtemplate'
        web_request = get_web_content(link, {})

        hit = session.wait_for_thread_stopped(reason='exception')
        frames = hit.stacktrace.body['stackFrames']
        assert frames[0] == ANY.dict_with({
            'id':
            ANY.dap_id,
            'name':
            'Django TemplateSyntaxError',
            'source':
            ANY.dict_with({
                'sourceReference': ANY.dap_id,
                'path': Path(DJANGO1_BAD_TEMPLATE),
            }),
            'line':
            8,
            'column':
            1,
        })

        # Will stop once in the plugin
        resp_exception_info = session.send_request('exceptionInfo',
                                                   arguments={
                                                       'threadId':
                                                       hit.thread_id,
                                                   }).wait_for_response()
        exception = resp_exception_info.body
        assert exception == ANY.dict_with({
            'exceptionId':
            ANY.such_that(lambda s: s.endswith('TemplateSyntaxError')),
            'breakMode':
            'always',
            'description':
            ANY.such_that(lambda s: s.find('doesnotexist') > -1),
            'details':
            ANY.dict_with({
                'message':
                ANY.such_that(lambda s: s.endswith('doesnotexist') > -1),
                'typeName':
                ANY.such_that(lambda s: s.endswith('TemplateSyntaxError')),
            })
        })

        session.send_request('continue').wait_for_response(freeze=False)

        # And a second time when the exception reaches the user code.
        hit = session.wait_for_thread_stopped(reason='exception')
        session.send_request('continue').wait_for_response(freeze=False)

        # ignore response for exception tests
        web_request.wait_for_response()

        # shutdown to web server
        link = DJANGO_LINK + 'exit'
        get_web_content(link).wait_for_response()

        session.wait_for_exit()
Ejemplo n.º 20
0
def test_with_path_mappings(pyfile, tmpdir, run_as, start_method):
    @pyfile
    def code_to_debug():
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()

        def full_function():
            # Note that this function is not called, it's there just to make the mapping explicit.
            print('cell1 line 2')  # @map_to_cell1_line_2
            print('cell1 line 3')  # @map_to_cell1_line_3

            print('cell2 line 2')  # @map_to_cell2_line_2
            print('cell2 line 3')  # @map_to_cell2_line_3

        def strip_lines(s):
            return '\n'.join([line.strip() for line in s.splitlines()])

        def create_code():
            cell1_code = compile(
                strip_lines(''' # line 1
            a = 1  # line 2
            b = 2  # line 3
            '''), '<cell1>', 'exec')

            cell2_code = compile(
                strip_lines('''# line 1
            c = 3  # line 2
            d = 4  # line 3
            '''), '<cell2>', 'exec')

            return {'cell1': cell1_code, 'cell2': cell2_code}

        code = create_code()
        exec(code['cell1'], {})
        exec(code['cell1'], {})

        exec(code['cell2'], {})
        exec(code['cell2'], {})
        print('ok')

    with DebugSession() as session:
        session.initialize(
            target=(run_as, code_to_debug),
            start_method=start_method,
        )

        marked_line_numbers = get_marked_line_numbers(code_to_debug)
        map_to_cell_1_line2 = marked_line_numbers['map_to_cell1_line_2']
        map_to_cell_2_line2 = marked_line_numbers['map_to_cell2_line_2']

        source_entry = code_to_debug
        if sys.platform == 'win32':
            # Check if it matches even not normalized.
            source_entry = code_to_debug[0].lower() + code_to_debug[1:].upper()
            source_entry = source_entry.replace('\\', '/')

        # Set breakpoints first and the map afterwards to make sure that it's reapplied.
        session.set_breakpoints(code_to_debug, [map_to_cell_1_line2])

        session.send_request('setPydevdSourceMap',
                             arguments={
                                 'source': {
                                     'path': source_entry
                                 },
                                 'pydevdSourceMaps': [
                                     {
                                         'line': map_to_cell_1_line2,
                                         'endLine': map_to_cell_1_line2 + 1,
                                         'runtimeSource': {
                                             'path': '<cell1>'
                                         },
                                         'runtimeLine': 2,
                                     },
                                     {
                                         'line': map_to_cell_2_line2,
                                         'endLine': map_to_cell_2_line2 + 1,
                                         'runtimeSource': {
                                             'path': '<cell2>'
                                         },
                                         'runtimeLine': 2,
                                     },
                                 ],
                             }).wait_for_response()

        session.start_debugging()
        hit = session.wait_for_thread_stopped('breakpoint')

        frames = hit.stacktrace.body['stackFrames']
        assert frames[0]['source']['path'] == Path(code_to_debug)

        session.set_breakpoints(code_to_debug, [map_to_cell_2_line2])
        # Leave only the cell2 mapping.
        session.send_request('setPydevdSourceMap',
                             arguments={
                                 'source': {
                                     'path': source_entry
                                 },
                                 'pydevdSourceMaps': [
                                     {
                                         'line': map_to_cell_2_line2,
                                         'endLine': map_to_cell_2_line2 + 1,
                                         'runtimeSource': {
                                             'path': '<cell2>'
                                         },
                                         'runtimeLine': 2,
                                     },
                                 ],
                             }).wait_for_response()

        session.send_request('continue').wait_for_response()

        hit = session.wait_for_thread_stopped('breakpoint')

        # Remove the cell2 mapping so that it doesn't stop again.
        session.send_request('setPydevdSourceMap',
                             arguments={
                                 'source': {
                                     'path': source_entry
                                 },
                                 'pydevdSourceMaps': [
                                     {
                                         'line': map_to_cell_1_line2,
                                         'endLine': map_to_cell_1_line2 + 1,
                                         'runtimeSource': {
                                             'path': '<cell1>'
                                         },
                                         'runtimeLine': 2,
                                     },
                                 ],
                             }).wait_for_response()

        session.send_request('continue').wait_for_response(freeze=False)
        session.wait_for_exit()
Ejemplo n.º 21
0
def test_django_exception_no_multiproc(ex_type, start_method):
    ex_line = {
        'handled': 50,
        'unhandled': 64,
    }[ex_type]

    with DebugSession() as session:
        session.initialize(
            start_method=start_method,
            target=('file', DJANGO1_MANAGE),
            program_args=[
                'runserver', '--noreload', '--nothreading',
                str(DJANGO_PORT)
            ],
            debug_options=['Django'],
            cwd=DJANGO1_ROOT,
            expected_returncode=ANY.int,  # No clean way to kill Django server
        )

        session.send_request('setExceptionBreakpoints',
                             arguments={
                                 'filters': ['raised', 'uncaught'],
                             }).wait_for_response()

        session.start_debugging()

        wait_for_connection(DJANGO_PORT)

        link = DJANGO_LINK + 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': Path(DJANGO1_MANAGE),
                'stackTrace': ANY.such_that(lambda s: True),
            }
        }

        resp_stacktrace = 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.dap_id,
            'name': 'bad_route_' + ex_type,
            'source': {
                'sourceReference': ANY.dap_id,
                'path': Path(DJANGO1_MANAGE),
            },
            '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 = DJANGO_LINK + 'exit'
        get_web_content(link).wait_for_response()

        session.wait_for_exit()
Ejemplo n.º 22
0
def test_exceptions_and_partial_exclude_rules(pyfile, run_as, start_method,
                                              scenario):
    @pyfile
    def code_to_debug():
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()

        import backchannel
        import sys
        json = backchannel.read_json()
        call_me_back_dir = json['call_me_back_dir']
        sys.path.append(call_me_back_dir)

        import call_me_back

        def call_func():
            raise RuntimeError('unhandled error')  # @raise_line

        call_me_back.call_me_back(call_func)  # @call_me_back_line
        print('done')

    line_numbers = get_marked_line_numbers(code_to_debug)
    call_me_back_dir = get_test_root('call_me_back')

    if scenario == 'exclude_code_to_debug':
        rules = [{
            'path': '**/' + os.path.basename(code_to_debug),
            'include': False
        }]
    elif scenario == 'exclude_callback_dir':
        rules = [{'path': call_me_back_dir, 'include': False}]
    else:
        raise AssertionError('Unexpected scenario: %s' % (scenario, ))

    with DebugSession() as session:
        session.initialize(
            target=(run_as, code_to_debug),
            start_method=start_method,
            use_backchannel=True,
            rules=rules,
        )
        # TODO: The process returncode doesn't match the one returned from the DAP.
        # See: https://github.com/Microsoft/ptvsd/issues/1278
        session.expected_returncode = ANY.int
        filters = ['raised', 'uncaught']

        session.send_request('setExceptionBreakpoints', {
            'filters': filters
        }).wait_for_response()

        if scenario == 'exclude_code_to_debug':
            breakpoints = session.set_breakpoints(code_to_debug, [1])
            assert breakpoints == [{
                'verified':
                False,
                'message':
                ('Breakpoint in file excluded by filters.\n'
                 'Note: may be excluded because of "justMyCode" option (default == true).'
                 ),
                'source':
                ANY.dict_with({'path': Path(code_to_debug)}),
                'line':
                1
            }]

        session.start_debugging()
        session.write_json({'call_me_back_dir': call_me_back_dir})

        if scenario == 'exclude_code_to_debug':
            # Stop at handled
            hit = session.wait_for_thread_stopped(reason='exception')
            frames = hit.stacktrace.body['stackFrames']
            # We don't stop at the raise line but rather at the callback module which is
            # not excluded.
            assert len(frames) == 1
            assert frames[0] == ANY.dict_with({
                'line':
                2,
                'source':
                ANY.dict_with({
                    'path':
                    Path(os.path.join(call_me_back_dir, 'call_me_back.py'))
                })
            })
            # assert frames[1] == ANY.dict_with({ -- filtered out
            #     'line': line_numbers['call_me_back_line'],
            #     'source': ANY.dict_with({
            #         'path': Path(code_to_debug)
            #     })
            # })
            # 'continue' should terminate the debuggee
            session.send_request('continue').wait_for_response(freeze=False)

            # Note: does not stop at unhandled exception because raise was in excluded file.

        elif scenario == 'exclude_callback_dir':
            # Stop at handled raise_line
            hit = session.wait_for_thread_stopped(reason='exception')
            frames = hit.stacktrace.body['stackFrames']
            assert [(frame['name'], basename(frame['source']['path']))
                    for frame in frames] == [
                        ('call_func', 'code_to_debug.py'),
                        # ('call_me_back', 'call_me_back.py'), -- filtered out
                        ('<module>', 'code_to_debug.py'),
                    ]
            assert frames[0] == ANY.dict_with({
                'line':
                line_numbers['raise_line'],
                'source':
                ANY.dict_with({'path': Path(code_to_debug)})
            })
            session.send_request('continue').wait_for_response()

            # Stop at handled call_me_back_line
            hit = session.wait_for_thread_stopped(reason='exception')
            frames = hit.stacktrace.body['stackFrames']
            assert [(frame['name'], basename(frame['source']['path']))
                    for frame in frames] == [
                        ('<module>', 'code_to_debug.py'),
                    ]
            assert frames[0] == ANY.dict_with({
                'line':
                line_numbers['call_me_back_line'],
                'source':
                ANY.dict_with({'path': Path(code_to_debug)})
            })
            session.send_request('continue').wait_for_response()

            # Stop at unhandled
            hit = session.wait_for_thread_stopped(reason='exception')
            frames = hit.stacktrace.body['stackFrames']
            assert [(frame['name'], basename(frame['source']['path']))
                    for frame in frames] == [
                        ('call_func', 'code_to_debug.py'),
                        # ('call_me_back', 'call_me_back.py'), -- filtered out
                        ('<module>', 'code_to_debug.py'),
                    ]

            assert frames[0] == ANY.dict_with({
                'line':
                line_numbers['raise_line'],
                'source':
                ANY.dict_with({'path': Path(code_to_debug)})
            })
            session.send_request('continue').wait_for_response(freeze=False)
        else:
            raise AssertionError('Unexpected scenario: %s' % (scenario, ))

        session.wait_for_exit()
Ejemplo n.º 23
0
def test_django_breakpoint_no_multiproc(bp_target, start_method):
    bp_file, bp_line, bp_name = {
        'code': (DJANGO1_MANAGE, 40, 'home'),
        'template': (DJANGO1_TEMPLATE, 8, 'Django Template'),
    }[bp_target]

    with DebugSession() as session:
        session.initialize(
            start_method=start_method,
            target=('file', DJANGO1_MANAGE),
            program_args=['runserver', '--noreload', '--',
                          str(DJANGO_PORT)],
            debug_options=['Django'],
            cwd=DJANGO1_ROOT,
            expected_returncode=ANY.int,  # No clean way to kill Django server
        )

        bp_var_content = 'Django-Django-Test'
        session.set_breakpoints(bp_file, [bp_line])
        session.start_debugging()

        # wait for Django server to start
        wait_for_connection(DJANGO_PORT)
        web_request = get_web_content(DJANGO_LINK + 'home', {})

        hit = session.wait_for_thread_stopped()
        frames = hit.stacktrace.body['stackFrames']
        assert frames[0] == {
            'id': ANY.dap_id,
            'name': bp_name,
            'source': {
                'sourceReference': ANY,
                'path': Path(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 = DJANGO_LINK + 'exit'
        get_web_content(link).wait_for_response()

        session.wait_for_exit()