Exemple #1
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()
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()
Exemple #3
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()
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()
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()
Exemple #6
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()
Exemple #7
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)
Exemple #8
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
Exemple #9
0
def test_completions_scope(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]

    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(code_to_debug, [bp_line])
        session.start_debugging()

        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 len(frames) > 0

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

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

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

        session.wait_for_exit()
Exemple #10
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()
Exemple #11
0
def test_with_no_output(pyfile, run_as, start_method):
    @pyfile
    def code_to_debug():
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()
        # Do nothing, and check if there is any output

    with DebugSession() as session:
        session.initialize(target=(run_as, code_to_debug),
                           start_method=start_method)
        session.start_debugging()
        session.wait_for_exit()
        assert b'' == session.get_stdout_as_string()
        assert b'' == session.get_stderr_as_string()
Exemple #12
0
def test_autokill(pyfile, run_as, start_method):
    @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()

    with DebugSession() as parent_session:
        parent_session.program_args += [child]
        parent_session.initialize(multiprocess=True,
                                  target=(run_as, parent),
                                  start_method=start_method,
                                  use_backchannel=True)
        parent_session.start_debugging()

        with parent_session.connect_to_next_child_session() as child_session:
            child_session.start_debugging()

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

            child_session.wait_for_termination()
            parent_session.wait_for_exit()
Exemple #13
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')
Exemple #14
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()
Exemple #15
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
Exemple #16
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()
Exemple #17
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()
Exemple #18
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
Exemple #19
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()
Exemple #20
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,
            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 frames[0]['source']['path'] == Path(testfile)
        assert u'ಏನಾದರೂ_ಮಾಡು' == frames[0]['name']

        session.send_request('continue').wait_for_response(freeze=False)
        session.wait_for_exit()
Exemple #21
0
def test_thread_count(pyfile, run_as, start_method, count):
    @pyfile
    def code_to_debug():
        import threading
        import time
        import sys
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()
        stop = False

        def worker(tid, offset):
            i = 0
            global stop
            while not stop:
                time.sleep(0.01)
                i += 1

        threads = []
        if sys.argv[1] != '1':
            for i in [111, 222]:
                thread = threading.Thread(target=worker,
                                          args=(i, len(threads)))
                threads.append(thread)
                thread.start()
        print('check here')
        stop = True

    with DebugSession() as session:
        session.initialize(
            target=(run_as, code_to_debug),
            start_method=start_method,
            program_args=[str(count)],
            ignore_unobserved=[Event('continued')],
        )
        session.set_breakpoints(code_to_debug, [19])
        session.start_debugging()
        session.wait_for_thread_stopped()
        resp_threads = session.send_request('threads').wait_for_response()

        assert len(resp_threads.body['threads']) == count

        session.send_request('continue').wait_for_response()
        session.wait_for_exit()
Exemple #22
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 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': dir_remote,
            }],
        )
        session.set_breakpoints(path_remote, [bp_line])
        session.start_debugging()
        hit = session.wait_for_thread_stopped('breakpoint')
        frames = hit.stacktrace.body['stackFrames']
        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()
Exemple #23
0
def test_args(pyfile, run_as, start_method):
    @pyfile
    def code_to_debug():
        import sys
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()
        assert sys.argv[1] == '--arg1'
        assert sys.argv[2] == 'arg2'
        assert sys.argv[3] == '-arg3'

    args = ['--arg1', 'arg2', '-arg3']
    with DebugSession() as session:
        session.initialize(
            target=(run_as, code_to_debug),
            start_method=start_method,
            program_args=args
        )
        session.start_debugging()

        session.wait_for_exit()
Exemple #24
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 compare_path(frames[0]['source']['path'], script2, show=False)

        session.send_request('continue').wait_for_response(freeze=False)
        hit = session.wait_for_thread_stopped()
        frames = hit.stacktrace.body['stackFrames']
        assert bp_script1_line == frames[0]['line']
        assert compare_path(frames[0]['source']['path'], script1, show=False)

        session.send_request('continue').wait_for_response(freeze=False)
        session.wait_for_exit()
Exemple #25
0
def test_wait_on_abnormal_exit_enabled(pyfile, run_as, start_method):

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

    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.expected_returncode = ANY.int
        assert session.read_json() == 'done'

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

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

        assert any(
            l for l in session.output_data['OUT']
            if _decode(l).startswith('Press')
        )
Exemple #26
0
def test_package_launch():
    bp_line = 2
    cwd = get_test_root('testpkgs')
    testfile = os.path.join(cwd, 'pkg1', '__main__.py')

    with DebugSession() as session:
        session.initialize(
            target=('module', 'pkg1'),
            start_method='launch',
            ignore_unobserved=[Event('continued')],
            cwd=cwd,
        )
        session.set_breakpoints(testfile, [bp_line])
        session.start_debugging()

        hit = session.wait_for_thread_stopped()
        frames = hit.stacktrace.body['stackFrames']
        assert bp_line == frames[0]['line']

        session.send_request('continue').wait_for_response(freeze=False)
        session.wait_for_exit()
Exemple #27
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()
Exemple #28
0
def test_reattach(pyfile, run_as, start_method):
    @pyfile
    def code_to_debug():
        import time
        import ptvsd
        import backchannel
        from dbgimporter import import_and_enable_debugger
        import_and_enable_debugger()
        ptvsd.break_into_debugger()
        print('first')
        backchannel.write_json('continued')
        for _ in range(0, 20):
            time.sleep(0.1)
            ptvsd.break_into_debugger()
            print('second')

    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()
        frames = hit.stacktrace.body['stackFrames']
        assert 7 == frames[0]['line']
        session.send_request('disconnect').wait_for_response(freeze=False)
        session.wait_for_disconnect()
        assert session.read_json() == 'continued'

        # re-attach
        with session.connect_with_new_session() as session2:
            session2.start_debugging()
            hit = session2.wait_for_thread_stopped()
            frames = hit.stacktrace.body['stackFrames']
            assert 12 == frames[0]['line']
            session.send_request('continue').wait_for_response(freeze=False)
            session.wait_for_exit()
Exemple #29
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.int,
            'name': bp_name,
            'source': {
                'sourceReference': ANY.int,
                'path': ANY.such_that(lambda s: compare_path(s, bp_file)),
            },
            'line': bp_line,
            'column': 1,
        }

        fid = frames[0]['id']
        resp_scopes = session.send_request('scopes',
                                           arguments={
                                               'frameId': fid
                                           }).wait_for_response()
        scopes = resp_scopes.body['scopes']
        assert len(scopes) > 0

        resp_variables = session.send_request(
            'variables',
            arguments={
                'variablesReference': scopes[0]['variablesReference']
            }).wait_for_response()
        variables = list(v for v in resp_variables.body['variables']
                         if v['name'] == 'content')
        assert variables == [{
            'name': 'content',
            'type': 'str',
            'value': repr(bp_var_content),
            'presentationHint': {
                'attributes': ['rawString']
            },
            'evaluateName': 'content'
        }]

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

        web_content = web_request.wait_for_response()
        assert web_content.find(bp_var_content) != -1

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

        session.wait_for_exit()
Exemple #30
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',
            ],
            ignore_unobserved=[Event('stopped'),
                               Event('continued')],
            debug_options=['Jinja'],
            cwd=FLASK1_ROOT,
            env=env,
            expected_returncode=ANY.int,  # No clean way to kill Flask server
        )

        bp_line = 11
        bp_var_content = 'Flask-Jinja-Test'
        parent_session.set_breakpoints(FLASK1_APP, [bp_line])
        parent_session.start_debugging()

        with parent_session.connect_to_next_child_session() as child_session:
            child_session.send_request('setBreakpoints',
                                       arguments={
                                           'source': {
                                               'path': FLASK1_APP
                                           },
                                           'breakpoints': [
                                               {
                                                   'line': bp_line
                                               },
                                           ],
                                       }).wait_for_response()
            child_session.start_debugging()

            # wait for Flask server to start
            wait_for_connection(FLASK_PORT)
            web_request = get_web_content(FLASK_LINK, {})

            thread_stopped = child_session.wait_for_next(
                Event('stopped', ANY.dict_with({'reason': 'breakpoint'})))
            assert thread_stopped.body['threadId'] is not None

            tid = thread_stopped.body['threadId']

            resp_stacktrace = child_session.send_request(
                'stackTrace', arguments={
                    'threadId': tid,
                }).wait_for_response()
            assert resp_stacktrace.body['totalFrames'] > 0
            frames = resp_stacktrace.body['stackFrames']
            assert frames[0] == {
                'id': ANY.int,
                'name': 'home',
                'source': {
                    'sourceReference': ANY.int,
                    'path':
                    ANY.such_that(lambda s: compare_path(s, FLASK1_APP)),
                },
                'line': bp_line,
                'column': 1,
            }

            fid = frames[0]['id']
            resp_scopes = child_session.send_request('scopes',
                                                     arguments={
                                                         'frameId': fid
                                                     }).wait_for_response()
            scopes = resp_scopes.body['scopes']
            assert len(scopes) > 0

            resp_variables = child_session.send_request(
                'variables',
                arguments={
                    'variablesReference': scopes[0]['variablesReference']
                }).wait_for_response()
            variables = [
                v for v in resp_variables.body['variables']
                if v['name'] == 'content'
            ]
            assert variables == [{
                'name': 'content',
                'type': 'str',
                'value': repr(bp_var_content),
                'presentationHint': {
                    'attributes': ['rawString']
                },
                'evaluateName': 'content'
            }]

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

            web_content = web_request.wait_for_response()
            assert web_content.find(bp_var_content) != -1

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

            child_session.wait_for_termination()
            parent_session.wait_for_exit()