debugpy/tests/debugpy/test_path_mapping.py
2022-04-13 11:38:41 -07:00

146 lines
4.7 KiB
Python

# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See LICENSE in the project root
# for license information.
import pytest
import tests
from tests import debug, test_data
from tests.debug import targets
from tests.patterns import some
if not tests.full:
@pytest.fixture(params=targets.all_named)
def target(request):
return request.param
def test_with_dot_remote_root(pyfile, long_tmpdir, target, run):
@pyfile
def code_to_debug():
import os
import debuggee
from debuggee import backchannel
debuggee.setup()
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()
def test_with_path_mappings(pyfile, long_tmpdir, target, run):
@pyfile
def code_to_debug():
import debuggee
import os
import sys
from debuggee import backchannel
debuggee.setup()
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 exc:
assert "Source unavailable" in str(exc)
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()