Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit178a0b2

Browse files
authored
Fix bug with symlink for pytest execution (#22952)
Fixes#22938
1 parentbae7d40 commit178a0b2

File tree

3 files changed

+86
-14
lines changed

3 files changed

+86
-14
lines changed

‎pythonFiles/tests/pytestadapter/expected_execution_test_output.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -684,3 +684,15 @@
684684
"subtest":None,
685685
},
686686
}
687+
688+
# Constant for the symlink execution test where TEST_DATA_PATH / "root" the target and TEST_DATA_PATH / "symlink_folder" the symlink
689+
test_a_symlink_path=TEST_DATA_PATH/"symlink_folder"/"tests"/"test_a.py"
690+
symlink_run_expected_execution_output= {
691+
get_absolute_test_id("test_a.py::test_a_function",test_a_symlink_path): {
692+
"test":get_absolute_test_id("test_a.py::test_a_function",test_a_symlink_path),
693+
"outcome":"success",
694+
"message":None,
695+
"traceback":None,
696+
"subtest":None,
697+
}
698+
}

‎pythonFiles/tests/pytestadapter/test_execution.py

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# Copyright (c) Microsoft Corporation. All rights reserved.
22
# Licensed under the MIT License.
3+
importjson
34
importos
45
importshutil
56
fromtypingimportAny,Dict,List
@@ -8,7 +9,13 @@
89

910
fromtests.pytestadapterimportexpected_execution_test_output
1011

11-
from .helpersimportTEST_DATA_PATH,runner,runner_with_cwd
12+
from .helpersimport (
13+
TEST_DATA_PATH,
14+
create_symlink,
15+
get_absolute_test_id,
16+
runner,
17+
runner_with_cwd,
18+
)
1219

1320

1421
deftest_config_file():
@@ -276,3 +283,50 @@ def test_pytest_execution(test_ids, expected_const):
276283
ifactual_result_dict[key]["traceback"]isnotNone:
277284
actual_result_dict[key]["traceback"]="TRACEBACK"
278285
assertactual_result_dict==expected_const
286+
287+
288+
deftest_symlink_run():
289+
"""
290+
Test to test pytest discovery with the command line arg --rootdir specified as a symlink path.
291+
Discovery should succeed and testids should be relative to the symlinked root directory.
292+
"""
293+
withcreate_symlink(TEST_DATA_PATH,"root","symlink_folder")as (
294+
source,
295+
destination,
296+
):
297+
assertdestination.is_symlink()
298+
test_a_path=TEST_DATA_PATH/"symlink_folder"/"tests"/"test_a.py"
299+
test_a_id=get_absolute_test_id(
300+
"tests/test_a.py::test_a_function",
301+
test_a_path,
302+
)
303+
304+
# Run pytest with the cwd being the resolved symlink path (as it will be when we run the subprocess from node).
305+
actual=runner_with_cwd(
306+
[f"--rootdir={os.fspath(destination)}",test_a_id],source
307+
)
308+
309+
expected_const= (
310+
expected_execution_test_output.symlink_run_expected_execution_output
311+
)
312+
assertactual
313+
actual_list:List[Dict[str,Any]]=actual
314+
ifactual_listisnotNone:
315+
assertactual_list.pop(-1).get("eot")
316+
actual_item=actual_list.pop(0)
317+
try:
318+
# Check if all requirements
319+
assertall(
320+
iteminactual_item.keys()foritemin ("status","cwd","result")
321+
),"Required keys are missing"
322+
assertactual_item.get("status")=="success","Status is not 'success'"
323+
assertactual_item.get("cwd")==os.fspath(
324+
destination
325+
),f"CWD does not match:{os.fspath(destination)}"
326+
actual_result_dict=dict()
327+
actual_result_dict.update(actual_item["result"])
328+
assertactual_result_dict==expected_const
329+
exceptAssertionErrorase:
330+
# Print the actual_item in JSON format if an assertion fails
331+
print(json.dumps(actual_item,indent=4))
332+
pytest.fail(str(e))

‎pythonFiles/vscode_pytest/__init__.py

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,8 @@ def pytest_report_teststatus(report, config):
225225
config -- configuration object.
226226
"""
227227
cwd=pathlib.Path.cwd()
228+
ifSYMLINK_PATH:
229+
cwd=SYMLINK_PATH
228230

229231
ifreport.when=="call":
230232
traceback=None
@@ -348,10 +350,7 @@ def pytest_sessionfinish(session, exitstatus):
348350
cwd=pathlib.Path.cwd()
349351
ifSYMLINK_PATH:
350352
print("Plugin warning[vscode-pytest]: SYMLINK set, adjusting cwd.")
351-
# Get relative between the cwd (resolved path) and the node path.
352-
rel_path=os.path.relpath(cwd,pathlib.Path.cwd())
353-
# Calculate the new node path by making it relative to the symlink path.
354-
cwd=pathlib.Path(os.path.join(SYMLINK_PATH,rel_path))
353+
cwd=pathlib.Path(SYMLINK_PATH)
355354

356355
ifIS_DISCOVERY:
357356
ifnot (exitstatus==0orexitstatus==1orexitstatus==5):
@@ -681,9 +680,9 @@ def get_node_path(node: Any) -> pathlib.Path:
681680
A function that returns the path of a node given the switch to pathlib.Path.
682681
It also evaluates if the node is a symlink and returns the equivalent path.
683682
"""
684-
path=getattr(node,"path",None)orpathlib.Path(node.fspath)
683+
node_path=getattr(node,"path",None)orpathlib.Path(node.fspath)
685684

686-
ifnotpath:
685+
ifnotnode_path:
687686
raiseVSCodePytestError(
688687
f"Unable to find path for node:{node}, node.path:{node.path}, node.fspath:{node.fspath}"
689688
)
@@ -692,17 +691,24 @@ def get_node_path(node: Any) -> pathlib.Path:
692691
ifSYMLINK_PATHandnotisinstance(node,pytest.Session):
693692
# Get relative between the cwd (resolved path) and the node path.
694693
try:
695-
rel_path=path.relative_to(pathlib.Path.cwd())
696-
697-
# Calculate the new node path by making it relative to the symlink path.
698-
sym_path=pathlib.Path(os.path.join(SYMLINK_PATH,rel_path))
699-
returnsym_path
694+
# check to see if the node path contains the symlink root already
695+
common_path=os.path.commonpath([SYMLINK_PATH,node_path])
696+
ifcommon_path==os.fsdecode(SYMLINK_PATH):
697+
# node path is already relative to the SYMLINK_PATH root therefore return
698+
returnnode_path
699+
else:
700+
# if the node path is not a symlink, then we need to calculate the equivalent symlink path
701+
# get the relative path between the cwd and the node path (as the node path is not a symlink)
702+
rel_path=node_path.relative_to(pathlib.Path.cwd())
703+
# combine the difference between the cwd and the node path with the symlink path
704+
sym_path=pathlib.Path(os.path.join(SYMLINK_PATH,rel_path))
705+
returnsym_path
700706
exceptExceptionase:
701707
raiseVSCodePytestError(
702708
f"Error occurred while calculating symlink equivalent from node path:{e}"
703-
"\n SYMLINK_PATH: {SYMLINK_PATH},\n node path: {path},\n cwd: {{pathlib.Path.cwd()}}"
709+
f"\n SYMLINK_PATH:{SYMLINK_PATH},\n node path:{node_path},\n cwd:{pathlib.Path.cwd()}"
704710
)
705-
returnpath
711+
returnnode_path
706712

707713

708714
__socket=None

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp