From 1de64a3eed4b49f14eed7ddb7029d8f038e1b9a3 Mon Sep 17 00:00:00 2001 From: Federico Stagni Date: Wed, 17 Jun 2026 12:32:03 +0200 Subject: [PATCH 1/3] fix: standardLogging tests failing in CI when handlers are modified The captureBackend() function assumed the StreamHandler was always at index 0. When other tests modified handlers, the StreamHandler could be at a different position, and the subsequent `del handlers[1:]` in gLoggerReset() would remove it. Modified captureBackend() to: 1. Find an existing StreamHandler and redirect its stream to the buffer 2. Move it to index 0 if it's not already there (so it survives del handlers[1:]) 3. If no StreamHandler exists, create one at index 0 --- .../standardLogging/test/TestLogUtilities.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/DIRAC/FrameworkSystem/private/standardLogging/test/TestLogUtilities.py b/src/DIRAC/FrameworkSystem/private/standardLogging/test/TestLogUtilities.py index bd8616f31c0..5ffd034a564 100644 --- a/src/DIRAC/FrameworkSystem/private/standardLogging/test/TestLogUtilities.py +++ b/src/DIRAC/FrameworkSystem/private/standardLogging/test/TestLogUtilities.py @@ -25,8 +25,20 @@ def captureBackend(): Modify the output to capture logs of LoggingRoot """ bufferDirac = StringIO() - if logging.getLogger("dirac").handlers: - logging.getLogger("dirac").handlers[0].stream = bufferDirac + diracLogger = logging.getLogger("dirac") + # Find an existing StreamHandler, redirect its stream, and ensure it's at index 0 + # so it survives the `del handlers[1:]` in gLoggerReset + for i, handler in enumerate(diracLogger.handlers): + if hasattr(handler, "stream"): + handler.stream = bufferDirac + if i > 0: + # Move to index 0 so it survives del handlers[1:] + diracLogger.handlers.remove(handler) + diracLogger.handlers.insert(0, handler) + return bufferDirac + # No StreamHandler found, create one at index 0 + handler = logging.StreamHandler(bufferDirac) + diracLogger.handlers.insert(0, handler) return bufferDirac From 0a6aba711e32fb3db99a0481e76949e4641a8069 Mon Sep 17 00:00:00 2001 From: Federico Stagni Date: Wed, 17 Jun 2026 15:12:35 +0200 Subject: [PATCH 2/3] fix: standardLogging tests: Python 3.14 compatibility and ensure correct formatter in CI --- .../private/standardLogging/Formatter/BaseFormatter.py | 4 ++-- .../private/standardLogging/test/TestLogUtilities.py | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/DIRAC/FrameworkSystem/private/standardLogging/Formatter/BaseFormatter.py b/src/DIRAC/FrameworkSystem/private/standardLogging/Formatter/BaseFormatter.py index 0950c523625..610d94d3d99 100644 --- a/src/DIRAC/FrameworkSystem/private/standardLogging/Formatter/BaseFormatter.py +++ b/src/DIRAC/FrameworkSystem/private/standardLogging/Formatter/BaseFormatter.py @@ -1,6 +1,7 @@ """ BaseFormatter """ + import logging import sys @@ -62,6 +63,5 @@ def format(self, record): fmt += "%(message)s%(spacer)s%(varmessage)s" - self._style._fmt = fmt # pylint: disable=no-member - self.datefmt = "%Y-%m-%d %H:%M:%S" + self._style = logging.PercentStyle(fmt) return super().format(record) diff --git a/src/DIRAC/FrameworkSystem/private/standardLogging/test/TestLogUtilities.py b/src/DIRAC/FrameworkSystem/private/standardLogging/test/TestLogUtilities.py index 5ffd034a564..11d48dae74c 100644 --- a/src/DIRAC/FrameworkSystem/private/standardLogging/test/TestLogUtilities.py +++ b/src/DIRAC/FrameworkSystem/private/standardLogging/test/TestLogUtilities.py @@ -6,6 +6,7 @@ from DIRAC.FrameworkSystem.private.standardLogging.LoggingRoot import LoggingRoot from DIRAC.FrameworkSystem.private.standardLogging.Logging import Logging +from DIRAC.FrameworkSystem.private.standardLogging.Formatter.BaseFormatter import BaseFormatter gLogger = LoggingRoot() @@ -31,6 +32,7 @@ def captureBackend(): for i, handler in enumerate(diracLogger.handlers): if hasattr(handler, "stream"): handler.stream = bufferDirac + handler.setFormatter(BaseFormatter()) if i > 0: # Move to index 0 so it survives del handlers[1:] diracLogger.handlers.remove(handler) @@ -38,6 +40,7 @@ def captureBackend(): return bufferDirac # No StreamHandler found, create one at index 0 handler = logging.StreamHandler(bufferDirac) + handler.setFormatter(BaseFormatter()) diracLogger.handlers.insert(0, handler) return bufferDirac From 0ea312fb78a3da2c1ac667d4f2fd2b679bbee0f2 Mon Sep 17 00:00:00 2001 From: Federico Stagni Date: Wed, 17 Jun 2026 15:56:39 +0200 Subject: [PATCH 3/3] test: mock away __initLogger --- .../Client/test/Test_LocalConfiguration.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/DIRAC/ConfigurationSystem/Client/test/Test_LocalConfiguration.py b/src/DIRAC/ConfigurationSystem/Client/test/Test_LocalConfiguration.py index d27b17ca70c..1f88ced415b 100644 --- a/src/DIRAC/ConfigurationSystem/Client/test/Test_LocalConfiguration.py +++ b/src/DIRAC/ConfigurationSystem/Client/test/Test_LocalConfiguration.py @@ -1,10 +1,9 @@ -""" Unit tests for PathFinder only for functions that I added -""" -from unittest import mock +"""Unit tests for PathFinder only for functions that I added""" + import pytest import random -from DIRAC import S_OK, S_ERROR +from DIRAC import S_OK import DIRAC.ConfigurationSystem.Client.LocalConfiguration @@ -88,6 +87,9 @@ def localCFG(monkeypatch): localCFG = DIRAC.ConfigurationSystem.Client.LocalConfiguration.LocalConfiguration() # It's local test, do not contact Configuration Server localCFG.disableCS() + # These tests reset the logging while testing the script init + # This would cause an empty logger to persist post-test, so we mock away the __initLogger + monkeypatch.setattr(localCFG, "_LocalConfiguration__initLogger", lambda *a, **kw: None) return localCFG