Пример #1
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()
Пример #2
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()
Пример #3
0
def test_run(pyfile, run_as, start_method):
    @pyfile
    def code_to_debug():
        import os
        import sys
        import backchannel
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()

        print('begin')
        assert backchannel.read_json() == 'continue'
        backchannel.write_json(os.path.abspath(sys.modules['ptvsd'].__file__))
        print('end')

    with DebugSession() as session:
        session.initialize(target=(run_as, code_to_debug),
                           start_method=start_method,
                           use_backchannel=True)
        session.start_debugging()
        assert session.timeline.is_frozen

        process_event, = session.all_occurrences_of(Event('process'))
        assert process_event == Event(
            'process',
            ANY.dict_with({
                'name':
                ANY if run_as == 'code' else ANY.such_that(lambda name: (
                    # There can be a difference in file extension (.py/.pyc/.pyo) on clean runs.
                    name == code_to_debug or name == code_to_debug + 'c' or
                    name == code_to_debug + 'o')),
            }))

        session.write_json('continue')
        ptvsd_path = session.read_json()
        expected_ptvsd_path = os.path.abspath(ptvsd.__file__)
        assert (ptvsd_path == expected_ptvsd_path
                or ptvsd_path == expected_ptvsd_path + 'c'
                or ptvsd_path == expected_ptvsd_path + 'o')

        session.wait_for_exit()
Пример #4
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()
Пример #5
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()
Пример #6
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()
Пример #7
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()
Пример #8
0
def test_return_values(pyfile, run_as, start_method):

    @pyfile
    def code_to_debug():
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()

        class MyClass(object):

            def do_something(self):
                return 'did something'

        def my_func():
            return 'did more things'

        MyClass().do_something()  # @bp
        my_func()
        print('done')

    line_numbers = get_marked_line_numbers(code_to_debug)
    print(line_numbers)

    expected1 = ANY.dict_with({
        'name': '(return) MyClass.do_something',
        'value': "'did something'",
        'type': 'str',
        'presentationHint': ANY.dict_with({
            'attributes': ANY.such_that(lambda x: 'readOnly' in x)
        }),
    })

    expected2 = ANY.dict_with({
        'name': '(return) my_func',
        'value': "'did more things'",
        'type': 'str',
        'presentationHint': ANY.dict_with({
            'attributes': ANY.such_that(lambda x: 'readOnly' in x)
        }),
    })

    with DebugSession() as session:
        session.initialize(
            target=(run_as, code_to_debug),
            start_method=start_method,
            debug_options=['ShowReturnValue'],
        )
        session.set_breakpoints(code_to_debug, [line_numbers['bp']])
        session.start_debugging()
        hit = session.wait_for_thread_stopped()

        session.send_request('next', {'threadId': hit.thread_id}).wait_for_response()
        hit = session.wait_for_thread_stopped(reason='step')

        resp_scopes = session.send_request('scopes', arguments={
            'frameId': hit.frame_id
        }).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'].startswith('(return)')
        )

        assert variables == [expected1]

        session.send_request('next', {'threadId': hit.thread_id}).wait_for_response()
        hit = session.wait_for_thread_stopped(reason='step')

        # Scope should not have changed so use the same scope
        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'].startswith('(return)')
        )

        assert variables == [expected1, expected2]

        session.send_request('continue').wait_for_response()
        session.wait_for_exit()
Пример #9
0
def test_variables_and_evaluate(pyfile, run_as, start_method):

    @pyfile
    def code_to_debug():
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()
        a = 1
        b = {"one": 1, "two": 2}
        c = 3
        print([a, b, c])

    bp_line = 6
    bp_file = code_to_debug

    with DebugSession() as session:
        session.initialize(
            target=(run_as, bp_file),
            start_method=start_method,
        )
        session.set_breakpoints(bp_file, [bp_line])
        session.start_debugging()
        hit = session.wait_for_thread_stopped()

        resp_scopes = session.send_request('scopes', arguments={
            'frameId': hit.frame_id,
        }).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'] in ['a', 'b', 'c'])
        assert len(variables) == 3

        # variables should be sorted alphabetically
        assert ['a', 'b', 'c'] == list(v['name'] for v in variables)

        # get contents of 'b'
        resp_b_variables = session.send_request('variables', arguments={
            'variablesReference': variables[1]['variablesReference']
        }).wait_for_response()
        b_variables = resp_b_variables.body['variables']
        assert len(b_variables) == 3
        assert b_variables[0] == {
            'type': 'int',
            'value': '1',
            'name': ANY.such_that(lambda x: x.find('one') > 0),
            'evaluateName': "b['one']",
            'variablesReference': 0,
        }
        assert b_variables[1] == {
            'type': 'int',
            'value': '2',
            'name': ANY.such_that(lambda x: x.find('two') > 0),
            'evaluateName': "b['two']",
            'variablesReference': 0,
        }
        assert b_variables[2] == {
            'type': 'int',
            'value': '2',
            'name': '__len__',
            'evaluateName': "len(b)",
            'variablesReference': 0,
            'presentationHint': {'attributes': ['readOnly']},
        }

        # simple variable
        resp_evaluate1 = session.send_request('evaluate', arguments={
            'expression': 'a', 'frameId': hit.frame_id,
        }).wait_for_response()
        assert resp_evaluate1.body == ANY.dict_with({
            'type': 'int',
            'result': '1'
        })

        # dict variable
        resp_evaluate2 = session.send_request('evaluate', arguments={
            'expression': 'b["one"]', 'frameId': hit.frame_id,
        }).wait_for_response()
        assert resp_evaluate2.body == ANY.dict_with({
            'type': 'int',
            'result': '1'
        })

        # expression evaluate
        resp_evaluate3 = session.send_request('evaluate', arguments={
            'expression': 'a + b["one"]', 'frameId': hit.frame_id,
        }).wait_for_response()
        assert resp_evaluate3.body == ANY.dict_with({
            'type': 'int',
            'result': '2'
        })

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