Files
cleveragents-core/features/tdd_engine_cache_toctou.feature
HAL9000 d54ed1440c fix(engine_cache): guard MEMORY_ENGINES with lock to prevent TOCTOU race
Add MEMORY_ENGINES_LOCK to engine_cache.py and wrap the check-and-set
in UnitOfWork.engine with it to prevent concurrent threads from creating
duplicate in-memory SQLite engines. Also fix cache-hit bug where
self._engine was never assigned on a cache hit.

Closes #7566
2026-06-02 05:51:55 -04:00

36 lines
1.6 KiB
Gherkin

Feature: Thread-safe engine cache prevents TOCTOU race on MEMORY_ENGINES
As a developer relying on the in-memory SQLite engine cache
I want MEMORY_ENGINES access to be protected by a lock
So that concurrent threads cannot create duplicate engine instances for the same URL
# --- Lock Export ---
Scenario: MEMORY_ENGINES_LOCK is exported from engine_cache module
Given the engine cache module is imported
Then MEMORY_ENGINES_LOCK should be accessible from the engine_cache module
And MEMORY_ENGINES_LOCK should be a threading.Lock instance
# --- Cache-Hit Regression ---
Scenario: A second UnitOfWork for the same in-memory URL reuses the cached engine
Given the engine cache is cleared
And a UnitOfWork is created for "sqlite:///:memory:"
When a second UnitOfWork is created for "sqlite:///:memory:"
Then both UnitOfWork instances should share the same engine instance
# --- Lock Acquisition ---
Scenario: The engine property acquires MEMORY_ENGINES_LOCK before creating an engine
Given the engine cache is cleared
And MEMORY_ENGINES_LOCK acquisition is tracked
When a UnitOfWork engine is accessed for "sqlite:///:memory:"
Then MEMORY_ENGINES_LOCK should have been acquired at least once
# --- Concurrent Access ---
Scenario: Concurrent engine creation for the same URL yields one engine instance
Given the engine cache is cleared
When 10 threads each access the engine cache for "sqlite:///:memory:"
Then all threads should have received the same engine instance
And MEMORY_ENGINES should contain exactly one entry for "sqlite:///:memory:"