Exemplo n.º 1
0
def test_exit_normally_with_wait_on_abnormal_exit_enabled(
        debug_session, pyfile, run_as, start_method):
    @pyfile
    def code_to_debug():
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()
        print('one')
        print('two')
        print('three')

    debug_session.debug_options += ['WaitOnAbnormalExit']

    bp_line = 5
    bp_file = code_to_debug
    debug_session.initialize(target=(run_as, bp_file),
                             start_method=start_method)
    debug_session.set_breakpoints(bp_file, [bp_line])
    debug_session.start_debugging()

    debug_session.wait_for_next(Event('stopped'),
                                ANY.dict_with({'reason': 'breakpoint'}))
    debug_session.send_request('continue').wait_for_response()
    debug_session.wait_for_next(Event('continued'))
    debug_session.proceed()

    debug_session.wait_for_next(Event('exited'))
    output = [
        e.body['output']
        for e in debug_session.all_occurrences_of(Event('output'))
        if len(e.body['output']) >= 3 and e.body['category'] == 'stdout'
    ]
    assert len(output) == 3
    assert output == ['one', 'two', 'three']

    debug_session.wait_for_exit()
Exemplo n.º 2
0
def test_continue_on_disconnect_for_attach(pyfile, run_as, start_method):
    @pyfile
    def code_to_debug():
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()
        import backchannel
        backchannel.write_json('continued')

    bp_line = 4
    with DebugSession() as session:
        session.initialize(
            target=(run_as, code_to_debug),
            start_method=start_method,
            ignore_unobserved=[
                Event('continued'),
                Event('exited'),
                Event('terminated')
            ],
            use_backchannel=True,
        )
        session.set_breakpoints(code_to_debug, [bp_line])
        session.start_debugging()
        hit = session.wait_for_thread_stopped('breakpoint')
        frames = hit.stacktrace.body['stackFrames']
        assert frames[0]['line'] == bp_line
        session.send_request('disconnect').wait_for_response()
        session.wait_for_disconnect()
        assert 'continued' == session.read_json()
Exemplo n.º 3
0
def _initialize_flask_session_no_multiproc(session, start_method):
    env = {
        'FLASK_APP': 'app.py',
        'FLASK_ENV': 'development',
        'FLASK_DEBUG': '0',
    }
    if platform.system() != 'Windows':
        locale = 'en_US.utf8' if platform.system(
        ) == 'Linux' else 'en_US.UTF-8'
        env.update({
            'LC_ALL': locale,
            'LANG': locale,
        })

    session.initialize(
        start_method=start_method,
        target=('module', 'flask'),
        program_args=['run', '--no-debugger', '--no-reload', '--with-threads'],
        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
    )
Exemplo n.º 4
0
def test_subprocess(debug_session, pyfile):
    @pyfile
    def child():
        import sys
        import backchannel
        backchannel.write_json(sys.argv)

    @pyfile
    def parent():
        import os
        import subprocess
        import sys
        argv = [sys.executable]
        argv += [sys.argv[1], '--arg1', '--arg2', '--arg3']
        env = os.environ.copy()
        process = subprocess.Popen(argv,
                                   env=env,
                                   stdin=subprocess.PIPE,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE)
        process.wait()

    debug_session.multiprocess = True
    debug_session.program_args += [child]
    debug_session.prepare_to_run(filename=parent, backchannel=True)
    debug_session.start_debugging()

    root_start_request, = debug_session.all_occurrences_of(
        Request('launch') | Request('attach'))
    root_process, = debug_session.all_occurrences_of(Event('process'))
    root_pid = int(root_process.body['systemProcessId'])

    child_subprocess = debug_session.wait_for_next(Event('ptvsd_subprocess'))
    assert child_subprocess == Event(
        'ptvsd_subprocess', {
            'rootProcessId': root_pid,
            'parentProcessId': root_pid,
            'processId': ANY.int,
            'port': ANY.int,
            'rootStartRequest': {
                'seq': ANY.int,
                'type': 'request',
                'command': root_start_request.command,
                'arguments': root_start_request.arguments,
            }
        })
    child_port = child_subprocess.body['port']
    debug_session.proceed()

    child_session = DebugSession(method='attach_socket', ptvsd_port=child_port)
    child_session.ignore_unobserved = debug_session.ignore_unobserved
    child_session.connect()
    child_session.handshake()
    child_session.start_debugging()

    child_argv = debug_session.read_json()
    assert child_argv == [child, '--arg1', '--arg2', '--arg3']

    debug_session.wait_for_exit()
Exemplo n.º 5
0
def test_completions_scope(debug_session, pyfile, bp_line, run_as,
                           start_method):
    @pyfile
    def code_to_debug():
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()

        class SomeClass():
            def __init__(self, someVar):
                self.some_var = someVar

            def do_someting(self):
                someVariable = self.some_var
                return someVariable

        def someFunction(someVar):
            someVariable = someVar
            return SomeClass(someVariable).do_someting()

        someFunction('value')
        print('done')

    expected = expected_at_line[bp_line]
    debug_session.ignore_unobserved += [Event('stopped'), Event('continued')]
    debug_session.initialize(target=(run_as, code_to_debug),
                             start_method=start_method)
    debug_session.set_breakpoints(code_to_debug, [bp_line])
    debug_session.start_debugging()

    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'] > 0
    frames = resp_stacktrace.body['stackFrames']
    assert len(frames) > 0

    fid = frames[0]['id']
    resp_completions = debug_session.send_request('completions',
                                                  arguments={
                                                      'text': 'some',
                                                      'frameId': fid,
                                                      'column': 1
                                                  }).wait_for_response()
    targets = resp_completions.body['targets']

    debug_session.send_request('continue').wait_for_response()
    debug_session.wait_for_next(Event('continued'))

    targets.sort(key=lambda t: t['label'])
    expected.sort(key=lambda t: t['label'])
    assert targets == expected

    debug_session.wait_for_exit()
Exemplo n.º 6
0
def test_set_variable(debug_session, pyfile, run_as):
    @pyfile
    def code_to_debug():
        a = 1
        print(a)

    bp_line = 2
    bp_file = code_to_debug
    debug_session.common_setup(bp_file, run_as, breakpoints=[bp_line])
    debug_session.start_debugging()
    hit = debug_session.wait_for_thread_stopped()

    resp_scopes = debug_session.send_request('scopes',
                                             arguments={
                                                 'frameId': hit.frame_id
                                             }).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'] == 'a')
    assert len(variables) == 1
    assert variables[0] == {
        'type': 'int',
        'value': '1',
        'name': 'a',
        'evaluateName': "a"
    }

    resp_set_variable = debug_session.send_request(
        'setVariable',
        arguments={
            'variablesReference': scopes[0]['variablesReference'],
            'name': 'a',
            'value': '1000'
        }).wait_for_response()
    assert resp_set_variable.body == ANY.dict_with({
        'type': 'int',
        'value': '1000'
    })

    debug_session.send_request('continue').wait_for_response()
    debug_session.wait_for_next(Event('continued'))

    debug_session.wait_for_next(Event('output'))
    output = [
        e for e in debug_session.all_occurrences_of(Event('output'))
        if e.body['output'].startswith('1000')
    ]
    assert any(output)

    debug_session.wait_for_exit()
Exemplo n.º 7
0
def test_subprocess(debug_session, pyfile, start_method, run_as):
    @pyfile
    def child():
        import sys
        import backchannel
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()
        backchannel.write_json(sys.argv)

    @pyfile
    def parent():
        import os
        import subprocess
        import sys
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()
        argv = [sys.executable, sys.argv[1], '--arg1', '--arg2', '--arg3']
        env = os.environ.copy()
        process = subprocess.Popen(argv, env=env, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        process.wait()

    debug_session.program_args += [child]
    debug_session.initialize(multiprocess=True, target=(run_as, parent), start_method=start_method, use_backchannel=True)
    debug_session.start_debugging()

    root_start_request, = debug_session.all_occurrences_of(Request('launch') | Request('attach'))
    root_process, = debug_session.all_occurrences_of(Event('process'))
    root_pid = int(root_process.body['systemProcessId'])

    child_subprocess = debug_session.wait_for_next(Event('ptvsd_subprocess'))
    assert child_subprocess == Event('ptvsd_subprocess', {
        'rootProcessId': root_pid,
        'parentProcessId': root_pid,
        'processId': ANY.int,
        'port': ANY.int,
        'rootStartRequest': {
            'seq': ANY.int,
            'type': 'request',
            'command': root_start_request.command,
            'arguments': root_start_request.arguments,
        }
    })
    child_pid = child_subprocess.body['processId']
    child_port = child_subprocess.body['port']
    debug_session.proceed()

    child_session = DebugSession(start_method=START_METHOD_CMDLINE, ptvsd_port=child_port, pid=child_pid)
    child_session.ignore_unobserved = debug_session.ignore_unobserved
    child_session.connect()
    child_session.handshake()
    child_session.start_debugging()

    child_argv = debug_session.read_json()
    assert child_argv == [child, '--arg1', '--arg2', '--arg3']

    child_session.wait_for_exit()
    debug_session.wait_for_exit()
Exemplo n.º 8
0
def test_wait_on_abnormal_exit_enabled(debug_session, pyfile, run_as):
    @pyfile
    def code_to_debug():
        import sys
        print('one')
        print('two')
        print('three')
        sys.exit(12345)

    debug_session.debug_options += ['WaitOnAbnormalExit']

    bp_line = 5
    bp_file = code_to_debug
    _common_setup(debug_session, bp_file, run_as)

    debug_session.send_request('setBreakpoints',
                               arguments={
                                   'source': {
                                       'path': bp_file
                                   },
                                   'breakpoints': [
                                       {
                                           'line': bp_line
                                       },
                                   ],
                               }).wait_for_response()
    debug_session.start_debugging()

    debug_session.wait_for_next(Event('stopped'),
                                ANY.dict_with({'reason': 'breakpoint'}))
    debug_session.send_request('continue').wait_for_response()
    debug_session.wait_for_next(Event('continued'))
    debug_session.proceed()

    debug_session.expected_returncode = ANY.int

    debug_session.wait_for_next(Event('exited'))
    output = [
        e.body['output']
        for e in debug_session.all_occurrences_of(Event('output'))
        if len(e.body['output']) >= 3 and e.body['category'] == 'stdout'
    ]
    assert len(output) == 3
    assert output == ['one', 'two', 'three']

    debug_session.process.stdin.write(b' \r\n')
    debug_session.wait_for_exit()

    def _decode(text):
        if isinstance(text, bytes):
            return text.decode('utf-8')
        return text

    assert any(l for l in debug_session.output_data['OUT']
               if _decode(l).startswith('Press'))
Exemplo n.º 9
0
def test_wait_on_abnormal_exit_enabled(debug_session, pyfile, run_as,
                                       start_method):
    @pyfile
    def code_to_debug():
        import sys
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()
        print('one')
        print('two')
        print('three')
        sys.exit(12345)

    debug_session.debug_options += ['WaitOnAbnormalExit']

    bp_line = 7
    bp_file = code_to_debug
    debug_session.initialize(target=(run_as, bp_file),
                             start_method=start_method)
    debug_session.set_breakpoints(bp_file, [bp_line])
    debug_session.start_debugging()

    debug_session.wait_for_next(Event('stopped'),
                                ANY.dict_with({'reason': 'breakpoint'}))
    debug_session.send_request('continue').wait_for_response()
    debug_session.wait_for_next(Event('continued'))
    debug_session.proceed()

    debug_session.expected_returncode = ANY.int

    debug_session.wait_for_next(Event('exited'))
    output = [
        e.body['output']
        for e in debug_session.all_occurrences_of(Event('output'))
        if len(e.body['output']) >= 3 and e.body['category'] == 'stdout'
    ]
    assert len(output) == 3
    assert output == ['one', 'two', 'three']

    debug_session.process.stdin.write(b' \r\n')
    debug_session.wait_for_exit()

    def _decode(text):
        if isinstance(text, bytes):
            return text.decode('utf-8')
        return text

    assert any(l for l in debug_session.output_data['OUT']
               if _decode(l).startswith('Press'))
Exemplo n.º 10
0
def test_exit_on_disconnect_for_launch(pyfile, run_as, start_method):
    @pyfile
    def code_to_debug():
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()
        import os.path
        fp = os.join(os.path.dirname(os.path.abspath(__file__)), 'here.txt')
        # should not execute this
        with open(fp, 'w') as f:
            print('Should not continue after disconnect on launch', file=f)

    bp_line = 4
    with DebugSession() as session:
        session.initialize(
            target=(run_as, code_to_debug),
            start_method=start_method,
            ignore_unobserved=[Event('continued')],
            use_backchannel=True,
            expected_returncode=ANY.int,
        )
        session.set_breakpoints(code_to_debug, [bp_line])
        session.start_debugging()
        hit = session.wait_for_thread_stopped('breakpoint')
        frames = hit.stacktrace.body['stackFrames']
        assert frames[0]['line'] == bp_line
        session.send_request('disconnect').wait_for_response()
        session.wait_for_exit()
        fp = os.join(os.path.dirname(os.path.abspath(code_to_debug)),
                     'here.txt')
        assert not os.path.exists(fp)
Exemplo n.º 11
0
def simple_hit_paused_on_break(debug_session, pyfile, run_as):
    '''
    Starts debug session with a pre-defined code sample, yields with
    a breakpoint hit and when finished, resumes the execution
    and waits for the debug session to exit.

    :note: fixture will run with all permutations of the debug_session
    parameters as well as the run_as parameters.
    '''

    from pytests.helpers.timeline import Event

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

    bp_line = 4
    bp_file = code_to_debug
    debug_session.common_setup(bp_file, run_as, breakpoints=[bp_line])
    debug_session.start_debugging()
    hit = debug_session.wait_for_thread_stopped()

    yield hit

    debug_session.send_request('continue').wait_for_response()
    debug_session.wait_for_next(Event('continued'))

    debug_session.wait_for_exit()
Exemplo n.º 12
0
def test_breakpoint_function(pyfile, run_as, start_method):

    @pyfile
    def code_to_debug():
        # NOTE: These tests verify break_into_debugger for launch
        # and attach cases. For attach this is always after wait_for_attach
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()
        breakpoint()
        print('break here')

    with DebugSession() as session:
        session.initialize(
            target=(run_as, code_to_debug),
            start_method=start_method,
            ignore_unobserved=[Event('continued')]
        )
        session.start_debugging()
        hit = session.wait_for_thread_stopped()
        frames = hit.stacktrace.body['stackFrames']
        path = frames[0]['source']['path']
        assert path.endswith('code_to_debug.py') or path.endswith('<string>')
        assert frames[0]['line'] == 6

        session.send_request('continue').wait_for_response(freeze=False)
        session.wait_for_exit()
Exemplo n.º 13
0
def test_break_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'],
            ignore_unobserved=[Event('continued')],
            use_backchannel=True,
        )
        session.start_debugging()

        thread_stopped, resp_stacktrace, tid, _ = session.wait_for_thread_stopped()
        frames = resp_stacktrace.body['stackFrames']
        assert frames[0]['line'] == 1

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

        assert session.read_json() == 'done'

        session.wait_for_exit()
Exemplo n.º 14
0
def test_set_variable(pyfile, run_as, start_method):
    @pyfile
    def code_to_debug():
        import backchannel
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()
        import ptvsd
        a = 1
        ptvsd.break_into_debugger()
        backchannel.write_json(a)

    with DebugSession() as session:
        session.initialize(
            target=(run_as, code_to_debug),
            start_method=start_method,
            ignore_unobserved=[Event('continued')],
            use_backchannel=True,
        )
        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'] == 'a')
        assert len(variables) == 1
        assert variables[0] == {
            'type': 'int',
            'value': '1',
            'name': 'a',
            'evaluateName': "a"
        }

        resp_set_variable = session.send_request(
            'setVariable',
            arguments={
                'variablesReference': scopes[0]['variablesReference'],
                'name': 'a',
                'value': '1000'
            }).wait_for_response()
        assert resp_set_variable.body == ANY.dict_with({
            'type': 'int',
            'value': '1000'
        })

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

        assert session.read_json() == 1000

        session.wait_for_exit()
Exemplo n.º 15
0
def test_exit_normally_with_wait_on_abnormal_exit_enabled(pyfile, run_as, start_method):

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

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

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

        session.wait_for_termination()

        assert session.read_json() == 'done'

        session.wait_for_exit()
Exemplo n.º 16
0
def _common_setup(debug_session, path, run_as):
    debug_session.ignore_unobserved += [
        Event('thread', ANY.dict_with({'reason': 'started'})),
        Event('module')
    ]
    if run_as == 'file':
        debug_session.prepare_to_run(filename=path)
    elif run_as == 'module':
        debug_session.add_file_to_pythonpath(path)
        debug_session.prepare_to_run(module='code_to_debug')
    elif run_as == 'code':
        with open(path, 'r') as f:
            code = f.read()
        debug_session.prepare_to_run(code=code)
    else:
        pytest.fail()
Exemplo n.º 17
0
def test_run(debug_session, pyfile, run_as):
    @pyfile
    def code_to_debug():
        import os
        import sys
        import backchannel

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

    if run_as == 'file':
        debug_session.prepare_to_run(filename=code_to_debug, backchannel=True)
    elif run_as == 'module':
        debug_session.add_file_to_pythonpath(code_to_debug)
        debug_session.prepare_to_run(module='code_to_debug', backchannel=True)
    elif run_as == 'code':
        with open(code_to_debug, 'r') as f:
            code = f.read()
        debug_session.prepare_to_run(code=code, backchannel=True)
    else:
        pytest.fail()

    debug_session.start_debugging()
    assert debug_session.timeline.is_frozen

    process_event, = debug_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')),
        }))

    debug_session.write_json('continue')
    ptvsd_path = debug_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')

    debug_session.wait_for_exit()
Exemplo n.º 18
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'),
                               Event('continued')],
        )
        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()
Exemplo n.º 19
0
def test_log_point(pyfile, run_as, start_method):
    @pyfile
    def code_to_debug():
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()
        a = 10
        for i in range(1, a):
            print('value: %d' % i)

    bp_line = 5
    with DebugSession() as session:
        session.initialize(
            target=(run_as, code_to_debug),
            start_method=start_method,
            ignore_unobserved=[Event('continued')],
        )
        session.send_request('setBreakpoints',
                             arguments={
                                 'source': {
                                     'path': code_to_debug
                                 },
                                 'breakpoints': [{
                                     'line': bp_line,
                                     'logMessage': 'log: {a + i}'
                                 }],
                             }).wait_for_response()
        session.start_debugging()

        session.wait_for_exit()
        assert session.get_stderr_as_string() == b''

        output = session.all_occurrences_of(
            Event('output', ANY.dict_with({'category': 'stdout'})))
        output_str = ''.join(o.body['output'] for o in output)
        logged = sorted(
            int(i) for i in re.findall(r"log:\s([0-9]*)", output_str))
        values = sorted(
            int(i) for i in re.findall(r"value:\s([0-9]*)", output_str))

        # NOTE: Due to https://github.com/Microsoft/ptvsd/issues/1028 we may not get
        # all output events. Once that is fixed we should check for the exact output
        # and log value
        assert len(logged) > 0
        assert len(values) > 0
Exemplo n.º 20
0
def test_exit_normally_with_wait_on_abnormal_exit_enabled(
        debug_session, pyfile, run_as):
    @pyfile
    def code_to_debug():
        print('one')
        print('two')
        print('three')

    debug_session.debug_options += ['WaitOnAbnormalExit']

    bp_line = 3
    bp_file = code_to_debug
    _common_setup(debug_session, bp_file, run_as)

    debug_session.send_request('setBreakpoints',
                               arguments={
                                   'source': {
                                       'path': bp_file
                                   },
                                   'breakpoints': [
                                       {
                                           'line': bp_line
                                       },
                                   ],
                               }).wait_for_response()
    debug_session.start_debugging()

    debug_session.wait_for_next(Event('stopped'),
                                ANY.dict_with({'reason': 'breakpoint'}))
    debug_session.send_request('continue').wait_for_response()
    debug_session.wait_for_next(Event('continued'))
    debug_session.proceed()

    debug_session.wait_for_next(Event('exited'))
    output = [
        e.body['output']
        for e in debug_session.all_occurrences_of(Event('output'))
        if len(e.body['output']) >= 3 and e.body['category'] == 'stdout'
    ]
    assert len(output) == 3
    assert output == ['one', 'two', 'three']

    debug_session.wait_for_exit()
Exemplo n.º 21
0
def test_stack_format(pyfile, run_as, start_method, module, line):
    @pyfile
    def code_to_debug():
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()
        from test_module import do_something
        do_something()

    @pyfile
    def test_module():
        # import_and_enable_debugger()
        def do_something():
            print('break here')

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

        hit = session.wait_for_thread_stopped()
        resp_stacktrace = session.send_request('stackTrace',
                                               arguments={
                                                   'threadId': hit.thread_id,
                                                   'format': {
                                                       'module': module,
                                                       'line': line
                                                   },
                                               }).wait_for_response()
        assert resp_stacktrace.body['totalFrames'] > 0
        frames = resp_stacktrace.body['stackFrames']

        assert line == (frames[0]['name'].find(': ' + str(bp_line)) > -1)

        assert module == (frames[0]['name'].find('test_module') > -1)

        session.send_request('continue').wait_for_response(freeze=False)
        session.wait_for_exit()
Exemplo n.º 22
0
def test_break_on_entry(debug_session, pyfile, run_as, start_method):
    @pyfile
    def code_to_debug():
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()
        print('one')
        print('two')
        print('three')

    debug_session.debug_options += ['StopOnEntry']
    debug_session.initialize(target=(run_as, code_to_debug),
                             start_method=start_method)
    debug_session.start_debugging()

    thread_stopped = debug_session.wait_for_next(
        Event('stopped'), ANY.dict_with({'reason': 'step'}))
    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'] > 0
    frames = resp_stacktrace.body['stackFrames']
    assert frames[0]['line'] == 1

    debug_session.send_request('continue').wait_for_response()
    debug_session.wait_for_next(Event('continued'))

    debug_session.wait_for_next(Event('exited'))
    output = [
        e.body['output']
        for e in debug_session.all_occurrences_of(Event('output'))
        if len(e.body['output']) >= 3 and e.body['category'] == 'stdout'
    ]
    assert len(output) == 3
    assert output == ['one', 'two', 'three']

    debug_session.wait_for_exit()
Exemplo n.º 23
0
def _wait_for_child_process(debug_session):
    child_subprocess = debug_session.wait_for_next(Event('ptvsd_subprocess'))
    assert child_subprocess.body['port'] != 0

    child_port = child_subprocess.body['port']

    child_session = DebugSession(start_method=START_METHOD_CMDLINE, ptvsd_port=child_port)
    child_session.ignore_unobserved = debug_session.ignore_unobserved
    child_session.debug_options = debug_session.debug_options
    child_session.connect()
    child_session.handshake()
    return child_session
Exemplo n.º 24
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()
Exemplo n.º 25
0
def test_completions_cases(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,
            ignore_unobserved=[Event('continued')],
        )
        session.set_breakpoints(bp_file, [bp_line])
        session.start_debugging()
        hit = session.wait_for_thread_stopped()

        response = session.send_request('completions', arguments={
            'frameId': hit.frame_id,
            'text': 'b.',
            'column': 3,
        }).wait_for_response()

        labels = set(target['label'] for target in response.body['targets'])
        assert labels.issuperset(['get', 'items', 'keys', 'setdefault', 'update', 'values'])

        response = session.send_request('completions', arguments={
            'frameId': hit.frame_id,
            'text': 'x = b.setdefault',
            'column': 13,
        }).wait_for_response()

        assert response.body['targets'] == [
            {'label': 'setdefault', 'length': 6, 'start': 6, 'type': 'function'}]

        response = session.send_request('completions', arguments={
            'frameId': hit.frame_id,
            'text': 'not_there',
            'column': 10,
        }).wait_for_response()

        assert not response.body['targets']

        session.send_request('continue').wait_for_response(freeze=False)
        session.wait_for_exit()
Exemplo n.º 26
0
def test_autokill(debug_session, pyfile, start_method, run_as):
    @pyfile
    def child():
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()
        while True:
            pass

    @pyfile
    def parent():
        import backchannel
        import os
        import subprocess
        import sys
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()
        argv = [sys.executable, sys.argv[1]]
        env = os.environ.copy()
        subprocess.Popen(argv, env=env, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        backchannel.read_json()

    debug_session.program_args += [child]
    debug_session.initialize(multiprocess=True, target=(run_as, parent), start_method=start_method, use_backchannel=True)
    debug_session.start_debugging()

    child_subprocess = debug_session.wait_for_next(Event('ptvsd_subprocess'))
    child_pid = child_subprocess.body['processId']
    child_port = child_subprocess.body['port']

    debug_session.proceed()

    child_session = DebugSession(start_method=START_METHOD_CMDLINE, ptvsd_port=child_port, pid=child_pid)
    child_session.expected_returncode = ANY
    child_session.connect()
    child_session.handshake()
    child_session.start_debugging()

    if debug_session.start_method == START_METHOD_LAUNCH:
        # In launch scenario, terminate the parent process by disconnecting from it.
        debug_session.expected_returncode = ANY
        disconnect = debug_session.send_request('disconnect', {})
        debug_session.wait_for_next(Response(disconnect))
    else:
        # In attach scenario, just let the parent process run to completion.
        debug_session.expected_returncode = 0
        debug_session.write_json(None)

    debug_session.wait_for_exit()
    child_session.wait_for_exit()
Exemplo n.º 27
0
def test_with_tab_in_output(pyfile, run_as, start_method):
    @pyfile
    def code_to_debug():
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()
        print('Hello\tWorld')

    with DebugSession() as session:
        session.initialize(target=(run_as, code_to_debug),
                           start_method=start_method)
        session.start_debugging()
        session.wait_for_exit()
        output = session.all_occurrences_of(
            Event('output', ANY.dict_with({'category': 'stdout'})))
        output_str = ''.join(o.body['output'] for o in output)
        assert output_str.startswith('Hello\tWorld')
Exemplo n.º 28
0
def test_error_in_condition(pyfile, run_as, start_method, error_name):
    @pyfile
    def code_to_debug():
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()

        def do_something_bad():
            raise ArithmeticError()

        for i in range(1, 10):
            pass

    # NOTE: NameError in condition, is a special case. Pydevd is configured to skip
    # traceback for name errors. See https://github.com/Microsoft/ptvsd/issues/853
    # for more details. For all other errors we should be printing traceback.
    condition = {
        'NameError': ('x==5'),  # 'x' does not exist in the debuggee
        'OtherError': ('do_something_bad()==5')  # throws some error
    }

    bp_line = 5
    with DebugSession() as session:
        session.initialize(
            target=(run_as, code_to_debug),
            start_method=start_method,
            ignore_unobserved=[Event('continued')],
        )
        session.send_request('setBreakpoints',
                             arguments={
                                 'source': {
                                     'path': code_to_debug
                                 },
                                 'breakpoints': [{
                                     'line':
                                     bp_line,
                                     'condition':
                                     condition[error_name],
                                 }],
                             }).wait_for_response()
        session.start_debugging()

        session.wait_for_exit()
        assert session.get_stdout_as_string() == b''
        if error_name == 'NameError':
            assert session.get_stderr_as_string() == b''
        else:
            assert session.get_stderr_as_string().find(b'ArithmeticError') > 0
Exemplo n.º 29
0
def test_attach(run_as, wait_for_attach, is_attached, break_into):
    testfile = os.path.join(get_test_root('attach'), 'attach1.py')

    with DebugSession() as session:
        env = {
            'PTVSD_TEST_HOST': 'localhost',
            'PTVSD_TEST_PORT': str(session.ptvsd_port),
        }
        if wait_for_attach == 'waitOn':
            env['PTVSD_WAIT_FOR_ATTACH'] = '1'
        if is_attached == 'attachCheckOn':
            env['PTVSD_IS_ATTACHED'] = '1'
        if break_into == 'break':
            env['PTVSD_BREAK_INTO_DBG'] = '1'

        session.initialize(
            target=(run_as, testfile),
            start_method='launch',
            ignore_unobserved=[Event('continued')],
            env=env,
            use_backchannel=True,
        )
        session.start_debugging()

        if wait_for_attach == 'waitOn':
            assert session.read_json() == 'wait_for_attach'

        if is_attached == 'attachCheckOn':
            assert session.read_json() == 'is_attached'

        if break_into == 'break':
            assert session.read_json() == 'break_into_debugger'
            hit = session.wait_for_thread_stopped()
            frames = hit.stacktrace.body['stackFrames']
            assert 32 == frames[0]['line']
        else:
            # pause test
            session.write_json('pause_test')
            session.send_request('pause').wait_for_response(freeze=False)
            hit = session.wait_for_thread_stopped(reason='pause')
            frames = hit.stacktrace.body['stackFrames']
            # Note: no longer asserting line as it can even stop on different files
            # (such as as backchannel.py).
            # assert frames[0]['line'] in [27, 28, 29]

        session.send_request('continue').wait_for_response(freeze=False)
        session.wait_for_exit()
Exemplo n.º 30
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,
            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()