From dc0fc9f70a23ad16c52dc548221b2ede640f9fbe Mon Sep 17 00:00:00 2001 From: Kadino Date: Fri, 23 Dec 2022 13:59:25 -0800 Subject: [PATCH 1/3] Mitigate directory creation race condition Fixes https://github.com/pytest-dev/pytest/issues/10604 which could intermittently display unexpected behavior between checking if the path exists and requesting creation. This was fairly prevalent when pytest was being invoked in parallel by another test runner (CTest) and trying to create the same parent-folder for multiple XMLs. A modest amount of testing did not reproduce other filesystem race conditions. This notably does not work around an edge case where the parent path of the XML could be created as a file instead of a folder or link. That vanishingly rare case should cause file creation to fail on the next line, with a fairly obvious exception message. --- src/_pytest/junitxml.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/_pytest/junitxml.py b/src/_pytest/junitxml.py index 7a5170f328b..b99306ce94e 100644 --- a/src/_pytest/junitxml.py +++ b/src/_pytest/junitxml.py @@ -646,7 +646,7 @@ def pytest_sessionstart(self) -> None: def pytest_sessionfinish(self) -> None: dirname = os.path.dirname(os.path.abspath(self.logfile)) if not os.path.isdir(dirname): - os.makedirs(dirname) + os.makedirs(dirname, exist_ok=True) with open(self.logfile, "w", encoding="utf-8") as logfile: suite_stop_time = timing.time() From e5f87af9c4d2e2715bb8ed4b19662eaf2090341a Mon Sep 17 00:00:00 2001 From: Kadino Date: Fri, 23 Dec 2022 22:07:48 -0800 Subject: [PATCH 2/3] Update junitxml.py --- src/_pytest/junitxml.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/_pytest/junitxml.py b/src/_pytest/junitxml.py index b99306ce94e..9242d46d9df 100644 --- a/src/_pytest/junitxml.py +++ b/src/_pytest/junitxml.py @@ -645,8 +645,8 @@ def pytest_sessionstart(self) -> None: def pytest_sessionfinish(self) -> None: dirname = os.path.dirname(os.path.abspath(self.logfile)) - if not os.path.isdir(dirname): - os.makedirs(dirname, exist_ok=True) + # exist_ok avoids filesystem race conditions between checking path existence and requesting creation + os.makedirs(dirname, exist_ok=True) with open(self.logfile, "w", encoding="utf-8") as logfile: suite_stop_time = timing.time() From a43f889610e9f64d3b3ec163c933f348c20272ec Mon Sep 17 00:00:00 2001 From: Kadino Date: Fri, 23 Dec 2022 22:12:15 -0800 Subject: [PATCH 3/3] Create 10607.bugfix.rst --- changelog/10607.bugfix.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog/10607.bugfix.rst diff --git a/changelog/10607.bugfix.rst b/changelog/10607.bugfix.rst new file mode 100644 index 00000000000..e89504695c2 --- /dev/null +++ b/changelog/10607.bugfix.rst @@ -0,0 +1 @@ +Fix a race condition when creating junitxml reports, which could occur when multiple instances of pytest execute in parallel.