This is an automated email from the ASF dual-hosted git repository.
potiuk pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/main by this push:
new da618aa8930 Fix flaky task_sdk test by comparing the list in unordered
fashion (#44776)
da618aa8930 is described below
commit da618aa8930a3816e6eb9ab471716ddd41aa7572
Author: Jarek Potiuk <[email protected]>
AuthorDate: Sun Dec 8 20:36:34 2024 +0100
Fix flaky task_sdk test by comparing the list in unordered fashion (#44776)
The test_reading_from_pipes can sometimes return the logs in a
different order, because the order in which messages will be read
from stdout and stderr and values are put in the log are not
deterministic. Unfortunately this is comparing list of dicts and
dicts are not hashable, so we cannot use the usual trick of converting
the list to set. Instead we are using "pytest-unordered" library
that implements `unordered` helper to run such asserts.
The native pytest for unordered collection comparision is highly
requested but apparently stalled by maintainers. See
the https://github.com/pytest-dev/pytest/issues/10032 issue.
---
hatch_build.py | 1 +
task_sdk/pyproject.toml | 1 +
task_sdk/tests/execution_time/test_supervisor.py | 79 ++++++++++++------------
3 files changed, 43 insertions(+), 38 deletions(-)
diff --git a/hatch_build.py b/hatch_build.py
index f2f72093bdb..e624baa8d2f 100644
--- a/hatch_build.py
+++ b/hatch_build.py
@@ -267,6 +267,7 @@ DEVEL_EXTRAS: dict[str, list[str]] = {
"pytest-mock>=3.12.0",
"pytest-rerunfailures>=13.0",
"pytest-timeouts>=1.2.1",
+ "pytest-unordered>=0.6.1",
"pytest-xdist>=3.5.0",
"pytest>=8.2,<9",
"requests_mock>=1.11.0",
diff --git a/task_sdk/pyproject.toml b/task_sdk/pyproject.toml
index 77061faa37c..aa0271c85fc 100644
--- a/task_sdk/pyproject.toml
+++ b/task_sdk/pyproject.toml
@@ -80,6 +80,7 @@ dev-dependencies = [
"kgb>=7.1.1",
"pytest-asyncio>=0.24.0",
"pytest-mock>=3.14.0",
+ "pytest-unordered>=0.6.1",
"pytest>=8.3.3",
]
diff --git a/task_sdk/tests/execution_time/test_supervisor.py
b/task_sdk/tests/execution_time/test_supervisor.py
index e51f418dad4..da2ea85589f 100644
--- a/task_sdk/tests/execution_time/test_supervisor.py
+++ b/task_sdk/tests/execution_time/test_supervisor.py
@@ -32,6 +32,7 @@ from unittest.mock import MagicMock
import httpx
import psutil
import pytest
+from pytest_unordered import unordered
from uuid6 import uuid7
from airflow.sdk.api import client as sdk_client
@@ -110,44 +111,46 @@ class TestWatchedSubprocess:
rc = proc.wait()
assert rc == 0
- assert captured_logs == [
- {
- "chan": "stdout",
- "event": "I'm a short message",
- "level": "info",
- "logger": "task",
- "timestamp": "2024-11-07T12:34:56.078901Z",
- },
- {
- "chan": "stderr",
- "event": "stderr message",
- "level": "error",
- "logger": "task",
- "timestamp": "2024-11-07T12:34:56.078901Z",
- },
- {
- "chan": "stdout",
- "event": "Message split across two writes",
- "level": "info",
- "logger": "task",
- "timestamp": "2024-11-07T12:34:56.078901Z",
- },
- {
- "event": "An error message",
- "level": "error",
- "logger": "airflow.foobar",
- "timestamp": instant.replace(tzinfo=None),
- },
- {
- "category": "UserWarning",
- "event": "Warning should be captured too",
- "filename": __file__,
- "level": "warning",
- "lineno": line,
- "logger": "py.warnings",
- "timestamp": instant.replace(tzinfo=None),
- },
- ]
+ assert captured_logs == unordered(
+ [
+ {
+ "chan": "stdout",
+ "event": "I'm a short message",
+ "level": "info",
+ "logger": "task",
+ "timestamp": "2024-11-07T12:34:56.078901Z",
+ },
+ {
+ "chan": "stderr",
+ "event": "stderr message",
+ "level": "error",
+ "logger": "task",
+ "timestamp": "2024-11-07T12:34:56.078901Z",
+ },
+ {
+ "chan": "stdout",
+ "event": "Message split across two writes",
+ "level": "info",
+ "logger": "task",
+ "timestamp": "2024-11-07T12:34:56.078901Z",
+ },
+ {
+ "event": "An error message",
+ "level": "error",
+ "logger": "airflow.foobar",
+ "timestamp": instant.replace(tzinfo=None),
+ },
+ {
+ "category": "UserWarning",
+ "event": "Warning should be captured too",
+ "filename": __file__,
+ "level": "warning",
+ "lineno": line,
+ "logger": "py.warnings",
+ "timestamp": instant.replace(tzinfo=None),
+ },
+ ]
+ )
def test_subprocess_sigkilled(self):
main_pid = os.getpid()