fix: first CI run on Windows and macOS; tests now enforce closed database files

The first push of the branch ran the Tests matrix on all three operating
systems. Every Python job failed; the causes were:

- numpy missing in CI: the WD14 engine tests import it (requirements-dev)
- macOS: temp directories resolve through /private; the admin API tests
  now use the real path like the gallery roots they compare against
- Windows: the startup banner printed an emoji, which raises
  UnicodeEncodeError on a legacy-code-page console and aborted loading
  the whole node; the banner is ASCII now and a test loads the package
  under a cp1252 stdout
- Windows: gallery subfolders came back with backslashes, which neither
  the folder tree nor the search filter understand; they are "/" joined
  on every platform. A relative DEFAULT_DB_PATH kept its forward slashes
  after being joined to the extension root; it is normalised now
- Windows: sqlite connections opened with `with sqlite3.connect()` are
  not closed by the context manager and linger until garbage collection,
  which holds a file lock there. Production sites (vacuum, diagnostics,
  restore inspection) close explicitly; a restore that swaps the API's
  database object closes the previous one; PromptModel keeps a registry
  so a shutdown or a test can close every instance
- Windows: served files were still open when their temp directory was
  removed (tests now read the body), a log download test compared text
  mode newlines, two tests compared paths with a hard-coded separator

tests/open_handles.py makes the Linux run fail the way Windows would:
every database test base checks, right before deleting its files, that
nothing in the process still holds them open.
This commit is contained in:
Vito Sansevero
2026-10-08 18:24:18 -07:00
parent 08d57b408a
commit b1bfce702d
22 changed files with 229 additions and 29 deletions
+17 -4
View File
@@ -12,6 +12,11 @@ import sys
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
try:
from tests.open_handles import assert_closed # noqa: E402
except ImportError: # discovered with tests/ as the top-level directory
from open_handles import assert_closed # noqa: E402
from database.operations import PromptDatabase
from utils.hashing import generate_prompt_hash
from utils.validators import validate_prompt_text, validate_rating, validate_tags
@@ -30,8 +35,12 @@ class TestBasicFunctionality(unittest.TestCase):
def tearDown(self):
"""Clean up test fixtures."""
# Remove temporary database
if os.path.exists(self.temp_db.name):
os.unlink(self.temp_db.name)
if getattr(self, "db", None) is not None:
self.db.close_all()
assert_closed(self, self.temp_db.name)
for suffix in ("", "-wal", "-shm"):
if os.path.exists(self.temp_db.name + suffix):
os.unlink(self.temp_db.name + suffix)
def test_prompt_hash_generation(self):
"""Test prompt hash generation."""
@@ -214,8 +223,12 @@ class TestNodeIntegration(unittest.TestCase):
def tearDown(self):
"""Clean up test fixtures."""
# Remove temporary database
if os.path.exists(self.temp_db.name):
os.unlink(self.temp_db.name)
if getattr(self, "db", None) is not None:
self.db.close_all()
assert_closed(self, self.temp_db.name)
for suffix in ("", "-wal", "-shm"):
if os.path.exists(self.temp_db.name + suffix):
os.unlink(self.temp_db.name + suffix)
@patch("prompt_manager_base.PromptDatabase")
def test_node_encode_function(self, mock_db_class):