Пример #1
0
    def code_to_debug():
        from debug_me import backchannel, ptvsd, scratchpad
        import sys
        import time

        _, host, port, wait_for_attach, is_attached, stop_method = sys.argv
        port = int(port)
        ptvsd.enable_attach((host, port))

        if wait_for_attach:
            backchannel.send("wait_for_attach")
            ptvsd.wait_for_attach()

        if is_attached:
            backchannel.send("is_attached")
            while not ptvsd.is_attached():
                print("looping until is_attached")
                time.sleep(0.1)

        if stop_method == "break_into_debugger":
            backchannel.send("break_into_debugger?")
            assert backchannel.receive() == "proceed"
            ptvsd.break_into_debugger()
            print("break")  # @break_into_debugger
        else:
            scratchpad["paused"] = False
            backchannel.send("loop?")
            assert backchannel.receive() == "proceed"
            while not scratchpad["paused"]:
                print("looping until paused")
                time.sleep(0.1)
Пример #2
0
def test_argv_quoting(pyfile, start_method, run_as):
    @pyfile
    def args():
        import debug_me  # noqa

        args = [  # noqa
            r"regular",
            r"",
            r"with spaces"
            r'"quoted"',
            r'" quote at start',
            r'quote at end "',
            r'quote in " the middle',
            r'quotes "in the" middle',
            r"\path with\spaces",
            r"\path\with\terminal\backslash" + "\\",
            r"backslash \" before quote",
        ]

    @pyfile
    def parent():
        import debug_me  # noqa

        import sys
        import subprocess
        from args import args

        child = sys.argv[1]
        subprocess.check_call([sys.executable] + [child] + args)

    @pyfile
    def child():
        from debug_me import backchannel
        import sys

        from args import args as expected_args

        backchannel.send(expected_args)

        actual_args = sys.argv[1:]
        backchannel.send(actual_args)

    with debug.Session(start_method, backchannel=True) as session:
        backchannel = session.backchannel
        session.configure(run_as, parent, args=[child])

        session.start_debugging()

        expected_args = backchannel.receive()
        actual_args = backchannel.receive()
        assert expected_args == actual_args
Пример #3
0
    def parent():
        import os
        import subprocess
        import sys
        from debug_me import backchannel

        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.receive()
Пример #4
0
def test_stop_on_entry(pyfile, run, target, breakpoint):
    @pyfile
    def code_to_debug():
        from debug_me import backchannel  # @bp

        backchannel.send("done")

    with debug.Session() as session:
        session.config["stopOnEntry"] = True

        backchannel = session.open_backchannel()
        with run(session, target(code_to_debug)):
            if breakpoint:
                session.set_breakpoints(code_to_debug, all)

        if breakpoint:
            stop = session.wait_for_stop(
                "breakpoint",
                expected_frames=[some.dap.frame(code_to_debug, 1)])
            session.request("next", {"threadId": stop.thread_id})
            stop = session.wait_for_stop(
                "step", expected_frames=[some.dap.frame(code_to_debug, 3)])
        else:
            session.wait_for_stop(
                "entry", expected_frames=[some.dap.frame(code_to_debug, 1)])

        session.request_continue()
        assert backchannel.receive() == "done"
Пример #5
0
def test_run_submodule(run):
    with debug.Session() as session:
        session.config["cwd"] = test_data / "testpkgs"

        backchannel = session.open_backchannel()
        with run(session, targets.Module(name="pkg1.sub")):
            pass

        assert backchannel.receive() == "ok"
Пример #6
0
    def code_to_debug():
        from debug_me import backchannel
        from os import path
        import sys

        print("begin")
        backchannel.send(path.abspath(sys.modules["ptvsd"].__file__))
        assert backchannel.receive() == "continue"
        print("end")
Пример #7
0
    def code_to_debug():
        from debug_me import backchannel
        import sys

        call_me_back_dir = backchannel.receive()
        sys.path.insert(0, call_me_back_dir)

        import call_me_back

        def call_func():
            raise RuntimeError("unhandled error")  # @raise

        call_me_back.call_me_back(call_func)  # @call_me_back
        print("done")
Пример #8
0
def test_args(pyfile, target, run):
    @pyfile
    def code_to_debug():
        from debug_me import backchannel
        import sys

        backchannel.send(sys.argv)

    args = ["--arg1", "arg2", "-arg3", "--", "arg4", "-a"]

    with debug.Session() as session:
        backchannel = session.open_backchannel()
        with run(session, target(code_to_debug, args=args)):
            pass
        argv = backchannel.receive()
        assert argv == [some.str] + args
Пример #9
0
    def code_to_debug():
        from debug_me import backchannel
        import os
        import sys

        backchannel.send(os.path.abspath(__file__))
        call_me_back_dir = backchannel.receive()
        sys.path.insert(0, call_me_back_dir)

        import call_me_back

        def call_func():
            print("break here")  # @bp

        call_me_back.call_me_back(call_func)  # @call_me_back
        print("done")
Пример #10
0
    def code_to_debug():
        import multiprocessing
        import platform
        import sys
        import debug_me  # noqa

        def child_of_child(q):
            print("entering child of child")
            assert q.get() == 2
            q.put(3)
            print("leaving child of child")

        def child(q):
            print("entering child")
            assert q.get() == 1

            print("spawning child of child")
            p = multiprocessing.Process(target=child_of_child, args=(q, ))
            p.start()
            p.join()

            assert q.get() == 3
            q.put(4)
            print("leaving child")

        if __name__ == "__main__":
            from debug_me import backchannel

            if sys.version_info >= (3, 4):
                multiprocessing.set_start_method("spawn")
            else:
                assert platform.system() == "Windows"

            print("spawning child")
            q = multiprocessing.Queue()
            p = multiprocessing.Process(target=child, args=(q, ))
            p.start()
            print("child spawned")
            backchannel.send(p.pid)

            q.put(1)
            assert backchannel.receive() == "continue"
            q.put(2)
            p.join()
            assert q.get() == 4
            q.close()
            backchannel.send("done")
Пример #11
0
def test_continue_on_disconnect_for_attach(pyfile, target, run):
    @pyfile
    def code_to_debug():
        from debug_me import backchannel

        backchannel.send("continued")  # @bp

    with debug.Session() as session:
        backchannel = session.open_backchannel()
        with run(session, target(code_to_debug)):
            session.set_breakpoints(code_to_debug, all)

        session.wait_for_stop(
            "breakpoint",
            expected_frames=[some.dap.frame(code_to_debug, line="bp")])
        session.disconnect()
        assert "continued" == backchannel.receive()
Пример #12
0
def test_set_variable(pyfile, target, run):
    @pyfile
    def code_to_debug():
        from debug_me import backchannel, ptvsd

        a = 1
        ptvsd.break_into_debugger()
        backchannel.send(a)

    with debug.Session() as session:
        backchannel = session.open_backchannel()
        with run(session, target(code_to_debug)):
            pass

        stop = session.wait_for_stop()
        scopes = session.request("scopes",
                                 {"frameId": stop.frame_id})["scopes"]
        globals_ref = scopes[0]["variablesReference"]
        vars = session.request(
            "variables", {"variablesReference": globals_ref})["variables"]

        a, = (v for v in vars if v["name"] == "a")
        assert a == some.dict.containing({
            "type": "int",
            "value": "1",
            "name": "a",
            "evaluateName": "a",
            "variablesReference": 0,
        })

        set_a = session.request(
            "setVariable",
            {
                "variablesReference": globals_ref,
                "name": "a",
                "value": "1000"
            },
        )
        assert set_a == some.dict.containing({"type": "int", "value": "1000"})

        session.request_continue()
        assert backchannel.receive() == 1000
Пример #13
0
def test_with_dot_remote_root(pyfile, long_tmpdir, target, run):
    @pyfile
    def code_to_debug():
        from debug_me import backchannel
        import os

        backchannel.send(os.path.abspath(__file__))
        print("done")  # @bp

    dir_local = long_tmpdir.mkdir("local")
    dir_remote = long_tmpdir.mkdir("remote")

    path_local = dir_local / "code_to_debug.py"
    path_remote = dir_remote / "code_to_debug.py"

    code_to_debug.copy(path_local)
    code_to_debug.copy(path_remote)

    with debug.Session() as session:
        session.config["pathMappings"] = [{
            "localRoot": dir_local,
            "remoteRoot": "."
        }]

        backchannel = session.open_backchannel()
        with run(session, target(path_remote), cwd=dir_remote):
            # Set breakpoints using local path. This tests that local paths are
            # mapped to remote paths.
            session.set_breakpoints(path_local, all)

        actual_path_remote = backchannel.receive()
        assert some.path(actual_path_remote) == path_remote

        session.wait_for_stop(
            "breakpoint",
            expected_frames=[
                some.dap.frame(some.dap.source(path_local), line="bp")
            ],
        )

        session.request_continue()
Пример #14
0
        def parent(q, a):
            from debug_me import backchannel

            print("spawning child")
            p = multiprocessing.Process(target=child, args=(q, a))
            p.start()
            print("child spawned")

            q.put("child_pid?")
            what, child_pid = a.get()
            assert what == "child_pid"
            backchannel.send(child_pid)

            q.put("grandchild_pid?")
            what, grandchild_pid = a.get()
            assert what == "grandchild_pid"
            backchannel.send(grandchild_pid)

            assert backchannel.receive() == "continue"
            q.put("exit!")
            p.join()
Пример #15
0
def test_run(pyfile, target, run):
    @pyfile
    def code_to_debug():
        from debug_me import backchannel
        from os import path
        import sys

        print("begin")
        backchannel.send(path.abspath(sys.modules["ptvsd"].__file__))
        assert backchannel.receive() == "continue"
        print("end")

    with debug.Session() as session:
        backchannel = session.open_backchannel()
        with run(session, target(code_to_debug)):
            pass

        expected_ptvsd_path = path.abspath(ptvsd.__file__)
        assert backchannel.receive() == some.str.matching(
            re.escape(expected_ptvsd_path) + r"(c|o)?")

        backchannel.send("continue")
        session.wait_for_next_event("terminated")
        session.proceed()
Пример #16
0
def test_attach_api(pyfile, target, wait_for_attach, is_attached, stop_method):
    @pyfile
    def code_to_debug():
        from debug_me import backchannel, ptvsd, scratchpad
        import sys
        import time

        _, host, port, wait_for_attach, is_attached, stop_method = sys.argv
        port = int(port)
        ptvsd.enable_attach((host, port))

        if wait_for_attach:
            backchannel.send("wait_for_attach")
            ptvsd.wait_for_attach()

        if is_attached:
            backchannel.send("is_attached")
            while not ptvsd.is_attached():
                print("looping until is_attached")
                time.sleep(0.1)

        if stop_method == "break_into_debugger":
            backchannel.send("break_into_debugger?")
            assert backchannel.receive() == "proceed"
            ptvsd.break_into_debugger()
            print("break")  # @break_into_debugger
        else:
            scratchpad["paused"] = False
            backchannel.send("loop?")
            assert backchannel.receive() == "proceed"
            while not scratchpad["paused"]:
                print("looping until paused")
                time.sleep(0.1)

    with debug.Session() as session:
        host, port = runners.attach_by_socket.host, runners.attach_by_socket.port
        session.config.update({"host": host, "port": port})

        backchannel = session.open_backchannel()
        session.spawn_debuggee([
            code_to_debug, host, port, wait_for_attach, is_attached,
            stop_method
        ])
        session.wait_for_enable_attach()

        session.connect_to_adapter((host, port))
        with session.request_attach():
            pass

        if wait_for_attach:
            assert backchannel.receive() == "wait_for_attach"

        if is_attached:
            assert backchannel.receive() == "is_attached"

        if stop_method == "break_into_debugger":
            assert backchannel.receive() == "break_into_debugger?"
            backchannel.send("proceed")
            session.wait_for_stop(expected_frames=[
                some.dap.frame(code_to_debug, "break_into_debugger")
            ])
        elif stop_method == "pause":
            assert backchannel.receive() == "loop?"
            backchannel.send("proceed")
            session.request("pause", freeze=False)
            session.wait_for_stop("pause")
            session.scratchpad["paused"] = True
        else:
            pytest.fail(stop_method)

        session.request_continue()
Пример #17
0
def test_with_path_mappings(pyfile, long_tmpdir, target, run):
    @pyfile
    def code_to_debug():
        from debug_me import backchannel
        import os
        import sys

        backchannel.send(os.path.abspath(__file__))
        call_me_back_dir = backchannel.receive()
        sys.path.insert(0, call_me_back_dir)

        import call_me_back

        def call_func():
            print("break here")  # @bp

        call_me_back.call_me_back(call_func)  # @call_me_back
        print("done")

    dir_local = long_tmpdir.mkdir("local")
    dir_remote = long_tmpdir.mkdir("remote")

    path_local = dir_local / "code_to_debug.py"
    path_remote = dir_remote / "code_to_debug.py"

    code_to_debug.copy(path_local)
    code_to_debug.copy(path_remote)

    call_me_back_dir = test_data / "call_me_back"
    call_me_back_py = call_me_back_dir / "call_me_back.py"

    with debug.Session() as session:
        session.config["pathMappings"] = [{
            "localRoot": dir_local,
            "remoteRoot": dir_remote
        }]

        backchannel = session.open_backchannel()
        with run(session, target(path_remote)):
            # Set breakpoints using local path. This tests that local paths are
            # mapped to remote paths.
            session.set_breakpoints(path_local, ["bp"])

        actual_path_remote = backchannel.receive()
        assert some.path(actual_path_remote) == path_remote
        backchannel.send(call_me_back_dir)

        stop = session.wait_for_stop(
            "breakpoint",
            expected_frames=[
                some.dap.frame(
                    # Mapped files should not have a sourceReference, so that the IDE
                    # doesn't try to fetch them instead of opening the local file.
                    some.dap.source(path_local, sourceReference=0),
                    line="bp",
                ),
                some.dap.frame(
                    # Unmapped files should have a sourceReference, since there's no
                    # local file for the IDE to open.
                    some.dap.source(call_me_back_py,
                                    sourceReference=some.int.not_equal_to(0)),
                    line="callback",
                ),
                some.dap.frame(
                    # Mapped files should not have a sourceReference, so that the IDE
                    # doesn't try to fetch them instead of opening the local file.
                    some.dap.source(path_local, sourceReference=0),
                    line="call_me_back",
                ),
            ],
        )

        srcref = stop.frames[1]["source"]["sourceReference"]

        try:
            session.request("source", {"sourceReference": 0})
        except Exception as ex:
            assert "Source unavailable" in str(ex)
        else:
            pytest.fail("sourceReference=0 should not be valid")

        source = session.request("source", {"sourceReference": srcref})
        assert "def call_me_back(callback):" in source["content"]

        session.request_continue()
Пример #18
0
    def code_to_debug():
        from debug_me import backchannel

        backchannel.receive()  # @ bp1
        print("ok")  # @ bp2
Пример #19
0
    def code_to_debug():
        from debug_me import backchannel  # noqa

        assert backchannel.receive() == "proceed"
Пример #20
0
def test_subprocess(pyfile, target, run):
    @pyfile
    def child():
        import os
        import sys

        assert "ptvsd" in sys.modules

        from debug_me import backchannel, ptvsd

        backchannel.send(os.getpid())
        backchannel.send(ptvsd.__file__)
        backchannel.send(sys.argv)

    @pyfile
    def parent():
        import debug_me  # noqa
        import os
        import subprocess
        import sys

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

    with debug.Session() as parent_session:
        backchannel = parent_session.open_backchannel()

        with run(parent_session, target(parent, args=[child])):
            pass

        expected_child_config = dict(parent_session.config)
        expected_child_config.update({
            "name": some.str,
            "request": "attach",
            "subProcessId": some.int,
            "host": some.str,
            "port": some.int,
        })

        child_config = parent_session.wait_for_next_event("ptvsd_attach")
        assert child_config == expected_child_config
        parent_session.proceed()

        with debug.Session(child_config) as child_session:
            with child_session.start():
                pass

            child_pid = backchannel.receive()
            assert child_pid == child_config["subProcessId"]
            assert str(child_pid) in child_config["name"]

            ptvsd_file = backchannel.receive()
            assert ptvsd_file == ptvsd.__file__

            child_argv = backchannel.receive()
            assert child_argv == [child, "--arg1", "--arg2", "--arg3"]