From 4400444619fae0173527bd713d9ba44949941eee Mon Sep 17 00:00:00 2001 From: Vito Sansevero Date: Wed, 7 Oct 2026 19:40:19 -0700 Subject: [PATCH] test: stop leaking a mocked utils.comfyui_integration and mock the IS_CHANGED clock test_image_monitor_singleton replaced utils.comfyui_integration in sys.modules with a MagicMock and never restored it, so running it before test_comfyui_integration failed eight tests. The mock was unused; drop it and install the server stub with setdefault in every owned test module. The PromptSearchList IS_CHANGED test slept 10 ms between two time.time() reads; the Windows clock ticks every 15.6 ms, so it was flaky there. Mock the clock with an incrementing counter instead. --- tests/test_api_admin.py | 2 +- tests/test_api_core.py | 2 +- tests/test_api_logging.py | 2 +- tests/test_config.py | 2 +- tests/test_gallery_roots.py | 2 +- tests/test_image_monitor_singleton.py | 20 +++++++++++++++----- tests/test_node_execution_contract.py | 13 ++++++++----- tests/test_output_dir.py | 2 +- 8 files changed, 29 insertions(+), 16 deletions(-) diff --git a/tests/test_api_admin.py b/tests/test_api_admin.py index e4c6043e..beb1a05c 100644 --- a/tests/test_api_admin.py +++ b/tests/test_api_admin.py @@ -16,7 +16,7 @@ from unittest.mock import MagicMock _mock_server = MagicMock() _mock_server.PromptServer.instance.routes = MagicMock() -sys.modules["server"] = _mock_server +sys.modules.setdefault("server", _mock_server) sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) diff --git a/tests/test_api_core.py b/tests/test_api_core.py index a280250a..67f6b813 100644 --- a/tests/test_api_core.py +++ b/tests/test_api_core.py @@ -12,7 +12,7 @@ from unittest.mock import MagicMock _mock_server = MagicMock() _mock_server.PromptServer.instance.routes = MagicMock() -sys.modules["server"] = _mock_server +sys.modules.setdefault("server", _mock_server) sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) diff --git a/tests/test_api_logging.py b/tests/test_api_logging.py index cce89469..360be5b8 100644 --- a/tests/test_api_logging.py +++ b/tests/test_api_logging.py @@ -11,7 +11,7 @@ from unittest.mock import MagicMock _mock_server = MagicMock() _mock_server.PromptServer.instance.routes = MagicMock() -sys.modules["server"] = _mock_server +sys.modules.setdefault("server", _mock_server) sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) diff --git a/tests/test_config.py b/tests/test_config.py index 09444b4e..197e6ff2 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -15,7 +15,7 @@ from unittest.mock import MagicMock # Mock ComfyUI's server module before importing config _mock_server = MagicMock() _mock_server.PromptServer.instance.routes = MagicMock() -sys.modules["server"] = _mock_server +sys.modules.setdefault("server", _mock_server) sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) diff --git a/tests/test_gallery_roots.py b/tests/test_gallery_roots.py index 4a83ac25..144372d8 100644 --- a/tests/test_gallery_roots.py +++ b/tests/test_gallery_roots.py @@ -17,7 +17,7 @@ from unittest.mock import MagicMock _mock_server = MagicMock() _mock_server.PromptServer.instance.routes = MagicMock() -sys.modules["server"] = _mock_server +sys.modules.setdefault("server", _mock_server) sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) diff --git a/tests/test_image_monitor_singleton.py b/tests/test_image_monitor_singleton.py index 538c25f6..867f5ccb 100644 --- a/tests/test_image_monitor_singleton.py +++ b/tests/test_image_monitor_singleton.py @@ -19,13 +19,12 @@ from unittest.mock import MagicMock, patch sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) -# Mock ComfyUI server before importing anything that touches config +# Mock ComfyUI server before importing anything that touches config. Only the +# first test module to run installs the stub; nothing else in sys.modules is +# replaced, so later modules (test_comfyui_integration) see the real package. _mock_server = MagicMock() _mock_server.PromptServer.instance.routes = MagicMock() -sys.modules["server"] = _mock_server - -# Mock comfyui_integration to avoid import issues -sys.modules["utils.comfyui_integration"] = MagicMock() +sys.modules.setdefault("server", _mock_server) from utils.image_monitor import get_image_monitor import utils.image_monitor as im_mod @@ -348,6 +347,17 @@ class TestHandlerScheduling(unittest.TestCase): self.assertEqual(self.processed, [first, second]) +class TestModuleIsolation(unittest.TestCase): + """This module must not leave mocks behind for later test modules.""" + + def test_comfyui_integration_is_not_replaced_by_a_mock(self): + module = sys.modules.get("utils.comfyui_integration") + self.assertFalse( + isinstance(module, MagicMock), + "utils.comfyui_integration was replaced by a MagicMock in sys.modules", + ) + + class TestMonitorThreadSafety(unittest.TestCase): """Singleton creation must be thread-safe.""" diff --git a/tests/test_node_execution_contract.py b/tests/test_node_execution_contract.py index a75a4232..3889f2ee 100644 --- a/tests/test_node_execution_contract.py +++ b/tests/test_node_execution_contract.py @@ -8,10 +8,11 @@ Ensures all nodes are properly configured for ComfyUI's execution engine: Regression tests for: https://github.com/ComfyAssets/ComfyUI_PromptManager/issues/120 """ +import itertools import os import sys -import time import unittest +import unittest.mock as mock sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) @@ -128,9 +129,12 @@ class TestIsChangedPromptSearchList(unittest.TestCase): so the node re-runs every time (database contents may have changed).""" def test_returns_different_value_on_successive_calls(self): - result1 = PromptSearchList.IS_CHANGED() - time.sleep(0.01) - result2 = PromptSearchList.IS_CHANGED() + # Mock the clock instead of sleeping: the Windows clock ticks every + # 15.6 ms, so two real time.time() reads 10 ms apart can be equal. + ticks = itertools.count(1_700_000_000.0, 1.0) + with mock.patch("time.time", side_effect=lambda: next(ticks)): + result1 = PromptSearchList.IS_CHANGED() + result2 = PromptSearchList.IS_CHANGED() self.assertNotEqual(result1, result2) def test_returns_numeric(self): @@ -141,7 +145,6 @@ class TestIsChangedPromptSearchList(unittest.TestCase): import logging # noqa: E402 import tempfile # noqa: E402 import types # noqa: E402 -import unittest.mock as mock # noqa: E402 from database.operations import PromptDatabase # noqa: E402 from prompt_manager_base import PromptManagerBase # noqa: E402 diff --git a/tests/test_output_dir.py b/tests/test_output_dir.py index 26cd27eb..dd518b03 100644 --- a/tests/test_output_dir.py +++ b/tests/test_output_dir.py @@ -16,7 +16,7 @@ sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) # Mock ComfyUI's server module before importing anything that touches config _mock_server = MagicMock() _mock_server.PromptServer.instance.routes = MagicMock() -sys.modules["server"] = _mock_server +sys.modules.setdefault("server", _mock_server) from py.api import PromptManagerAPI from py.config import GalleryConfig