Skip to content

Commit

Permalink
add to payload to allow error parsing on TS (#21483)
Browse files Browse the repository at this point in the history
partial fix for #21476,
make sure error display correctly.


two part fix:
fix "errors" to "error" in unittest payload to align with naming
everywhere else
add "result" and "test" to payload in run and discovery respectively
even on error to havae resultResolver handle correctly.
  • Loading branch information
eleanorjboyd authored Jun 23, 2023
1 parent 8c86417 commit c1ff6c3
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 27 deletions.
8 changes: 4 additions & 4 deletions pythonFiles/tests/unittestadapter/test_discovery.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ def test_simple_discovery() -> None:

assert actual["status"] == "success"
assert is_same_tree(actual.get("tests"), expected)
assert "errors" not in actual
assert "error" not in actual


def test_empty_discovery() -> None:
Expand All @@ -146,8 +146,8 @@ def test_empty_discovery() -> None:
actual = discover_tests(start_dir, pattern, None, uuid)

assert actual["status"] == "success"
assert "tests" not in actual
assert "errors" not in actual
assert "tests" in actual
assert "error" not in actual


def test_error_discovery() -> None:
Expand Down Expand Up @@ -213,4 +213,4 @@ def test_error_discovery() -> None:

assert actual["status"] == "error"
assert is_same_tree(expected, actual.get("tests"))
assert len(actual.get("errors", [])) == 1
assert len(actual.get("error", [])) == 1
12 changes: 6 additions & 6 deletions pythonFiles/tests/unittestadapter/test_execution.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def test_no_ids_run() -> None:
assert all(item in actual for item in ("cwd", "status"))
assert actual["status"] == "success"
assert actual["cwd"] == os.fspath(TEST_DATA_PATH)
if "result" in actual:
if actual["result"] is not None:
assert len(actual["result"]) == 0
else:
raise AssertionError("actual['result'] is None")
Expand All @@ -85,7 +85,7 @@ def test_single_ids_run() -> None:
assert all(item in actual for item in ("cwd", "status"))
assert actual["status"] == "success"
assert actual["cwd"] == os.fspath(TEST_DATA_PATH)
assert "result" in actual
assert actual["result"] is not None
result = actual["result"]
assert len(result) == 1
assert id in result
Expand Down Expand Up @@ -117,7 +117,7 @@ def test_subtest_run() -> None:
assert all(item in actual for item in ("cwd", "status"))
assert actual["status"] == "success"
assert actual["cwd"] == os.fspath(TEST_DATA_PATH)
assert "result" in actual
assert actual["result"] is not None
result = actual["result"]
assert len(result) == 6
for id in subtests_ids:
Expand Down Expand Up @@ -205,7 +205,7 @@ def test_multiple_ids_run(test_ids, pattern, cwd, expected_outcome) -> None:
assert all(item in actual for item in ("cwd", "status"))
assert actual["status"] == "success"
assert actual["cwd"] == cwd
assert "result" in actual
assert actual["result"] is not None
result = actual["result"]
assert len(result) == len(test_ids)
for test_id in test_ids:
Expand All @@ -230,7 +230,7 @@ def test_failed_tests():
assert all(item in actual for item in ("cwd", "status"))
assert actual["status"] == "success"
assert actual["cwd"] == os.fspath(TEST_DATA_PATH)
assert "result" in actual
assert actual["result"] is not None
result = actual["result"]
assert len(result) == len(test_ids)
for test_id in test_ids:
Expand All @@ -255,7 +255,7 @@ def test_unknown_id():
assert all(item in actual for item in ("cwd", "status"))
assert actual["status"] == "success"
assert actual["cwd"] == os.fspath(TEST_DATA_PATH)
assert "result" in actual
assert actual["result"] is not None
result = actual["result"]
assert len(result) == len(test_ids)
assert "unittest.loader._FailedTest.unknown_id" in result
Expand Down
25 changes: 13 additions & 12 deletions pythonFiles/unittestadapter/discovery.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ def parse_discovery_cli_args(args: List[str]) -> Tuple[int, Union[str, None]]:
class PayloadDict(TypedDict):
cwd: str
status: Literal["success", "error"]
tests: NotRequired[TestNode]
errors: NotRequired[List[str]]
tests: Optional[TestNode]
error: NotRequired[List[str]]


def discover_tests(
Expand All @@ -68,7 +68,7 @@ def discover_tests(
- uuid: UUID sent by the caller of the Python script, that needs to be sent back as an integrity check;
- status: Test discovery status, can be "success" or "error";
- tests: Discoverered tests if any, not present otherwise. Note that the status can be "error" but the payload can still contain tests;
- errors: Discovery errors if any, not present otherwise.
- error: Discovery error if any, not present otherwise.
Payload format for a successful discovery:
{
Expand All @@ -86,30 +86,31 @@ def discover_tests(
Payload format when there are errors:
{
"cwd": <test discovery directory>
"errors": [list of errors]
"": [list of errors]
"status": "error",
}
"""
cwd = os.path.abspath(start_dir)
payload: PayloadDict = {"cwd": cwd, "status": "success"}
payload: PayloadDict = {"cwd": cwd, "status": "success", "tests": None}
tests = None
errors: List[str] = []
error: List[str] = []

try:
loader = unittest.TestLoader()
suite = loader.discover(start_dir, pattern, top_level_dir)

tests, errors = build_test_tree(suite, cwd) # test tree built succesfully here.
tests, error = build_test_tree(suite, cwd) # test tree built succesfully here.

except Exception:
errors.append(traceback.format_exc())
error.append(traceback.format_exc())

if tests is not None:
payload["tests"] = tests
# Still include the tests in the payload even if there are errors so that the TS
# side can determine if it is from run or discovery.
payload["tests"] = tests if tests is not None else None

if len(errors):
if len(error):
payload["status"] = "error"
payload["errors"] = errors
payload["error"] = error

return payload

Expand Down
5 changes: 3 additions & 2 deletions pythonFiles/unittestadapter/execution.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ class TestExecutionStatus(str, enum.Enum):
class PayloadDict(TypedDict):
cwd: str
status: TestExecutionStatus
result: NotRequired[TestResultTypeAlias]
result: Optional[TestResultTypeAlias]
not_found: NotRequired[List[str]]
error: NotRequired[str]

Expand All @@ -185,7 +185,7 @@ def run_tests(
cwd = os.path.abspath(start_dir)
status = TestExecutionStatus.error
error = None
payload: PayloadDict = {"cwd": cwd, "status": status}
payload: PayloadDict = {"cwd": cwd, "status": status, "result": None}

try:
# If it's a file, split path and file name.
Expand Down Expand Up @@ -312,4 +312,5 @@ def send_run_data(raw_data, port, uuid):
"cwd": cwd,
"status": status,
"error": "No test ids received from buffer",
"result": None,
}
6 changes: 3 additions & 3 deletions pythonFiles/unittestadapter/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,14 +151,14 @@ def build_test_tree(
"id_": <test_directory path>
}
"""
errors = []
error = []
directory_path = pathlib.PurePath(test_directory)
root = build_test_node(test_directory, directory_path.name, TestNodeTypeEnum.folder)

for test_case in get_test_case(suite):
test_id = test_case.id()
if test_id.startswith("unittest.loader._FailedTest"):
errors.append(str(test_case._exception)) # type: ignore
error.append(str(test_case._exception)) # type: ignore
else:
# Get the static test path components: filename, class name and function name.
components = test_id.split(".")
Expand Down Expand Up @@ -206,7 +206,7 @@ def build_test_tree(
if not root["children"]:
root = None

return root, errors
return root, error


def parse_unittest_args(args: List[str]) -> Tuple[str, str, Union[str, None]]:
Expand Down

0 comments on commit c1ff6c3

Please sign in to comment.