Skip to content

Commit 3cd9178

Browse files
phernandezclaude
andcommitted
refactor: centralize test environment detection in config.is_test_env
Add is_test_env property to BasicMemoryConfig that checks: - config.env == "test" - BASIC_MEMORY_ENV env var is "test" - PYTEST_CURRENT_TEST is set Replace duplicated test detection logic in: - api/app.py - mcp/server.py - services/initialization.py - telemetry.py (disables telemetry during tests) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]> Signed-off-by: phernandez <[email protected]>
1 parent 856737f commit 3cd9178

File tree

5 files changed

+26
-26
lines changed

5 files changed

+26
-26
lines changed

src/basic_memory/api/app.py

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
"""FastAPI application for basic-memory knowledge graph API."""
22

33
import asyncio
4-
import os
54
from contextlib import asynccontextmanager
65

76
from fastapi import FastAPI, HTTPException
@@ -55,12 +54,7 @@ async def lifespan(app: FastAPI): # pragma: no cover
5554
logger.info("Database connections cached in app state")
5655

5756
# Start file sync if enabled
58-
is_test_env = (
59-
app_config.env == "test"
60-
or os.getenv("BASIC_MEMORY_ENV", "").lower() == "test"
61-
or os.getenv("PYTEST_CURRENT_TEST") is not None
62-
)
63-
if app_config.sync_changes and not is_test_env:
57+
if app_config.sync_changes and not app_config.is_test_env:
6458
logger.info(f"Sync changes enabled: {app_config.sync_changes}")
6559

6660
# start file sync task in background
@@ -69,7 +63,7 @@ async def _file_sync_runner() -> None:
6963

7064
app.state.sync_task = asyncio.create_task(_file_sync_runner())
7165
else:
72-
if is_test_env:
66+
if app_config.is_test_env:
7367
logger.info("Test environment detected. Skipping file sync service.")
7468
else:
7569
logger.info("Sync changes disabled. Skipping file sync service.")

src/basic_memory/config.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,23 @@ class BasicMemoryConfig(BaseSettings):
232232
description="Whether the one-time telemetry notice has been shown to the user",
233233
)
234234

235+
@property
236+
def is_test_env(self) -> bool:
237+
"""Check if running in a test environment.
238+
239+
Returns True if any of:
240+
- env field is set to "test"
241+
- BASIC_MEMORY_ENV environment variable is "test"
242+
- PYTEST_CURRENT_TEST environment variable is set (pytest is running)
243+
244+
Used to disable features like telemetry and file watchers during tests.
245+
"""
246+
return (
247+
self.env == "test"
248+
or os.getenv("BASIC_MEMORY_ENV", "").lower() == "test"
249+
or os.getenv("PYTEST_CURRENT_TEST") is not None
250+
)
251+
235252
@property
236253
def cloud_mode_enabled(self) -> bool:
237254
"""Check if cloud mode is enabled.

src/basic_memory/mcp/server.py

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
"""
44

55
import asyncio
6-
import os
76
from contextlib import asynccontextmanager
87

98
from fastmcp import FastMCP
@@ -42,12 +41,7 @@ async def lifespan(app: FastMCP):
4241

4342
# Start file sync as background task (if enabled and not in cloud mode)
4443
sync_task = None
45-
is_test_env = (
46-
app_config.env == "test"
47-
or os.getenv("BASIC_MEMORY_ENV", "").lower() == "test"
48-
or os.getenv("PYTEST_CURRENT_TEST") is not None
49-
)
50-
if is_test_env:
44+
if app_config.is_test_env:
5145
logger.info("Test environment detected - skipping local file sync")
5246
elif app_config.sync_changes and not app_config.cloud_mode_enabled:
5347
logger.info("Starting file sync in background")

src/basic_memory/services/initialization.py

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -82,14 +82,8 @@ async def initialize_file_sync(
8282
"""
8383
# Never start file watching during tests. Even "background" watchers add tasks/threads
8484
# and can interact badly with strict asyncio teardown (especially on Windows/aiosqlite).
85-
#
86-
# Note: Some tests patch ConfigManager.config with a minimal BasicMemoryConfig that
87-
# may not set env="test". So also detect pytest via env vars.
88-
if (
89-
app_config.env == "test"
90-
or os.getenv("BASIC_MEMORY_ENV", "").lower() == "test"
91-
or os.getenv("PYTEST_CURRENT_TEST") is not None
92-
):
85+
# Skip file sync in test environments to avoid interference with tests
86+
if app_config.is_test_env:
9387
logger.info("Test environment detected - skipping file sync initialization")
9488
return None
9589

src/basic_memory/telemetry.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,15 +90,16 @@ def _get_client() -> OpenPanel:
9090

9191
# Trigger: first call to track an event
9292
# Why: lazy init avoids work if telemetry never used; disabled flag
93-
# tells OpenPanel to skip network calls when user opts out
93+
# tells OpenPanel to skip network calls when user opts out or during tests
9494
# Outcome: client ready to queue events (or silently discard if disabled)
95+
is_disabled = not config.telemetry_enabled or config.is_test_env
9596
_client = OpenPanel(
9697
client_id=OPENPANEL_CLIENT_ID,
9798
client_secret=OPENPANEL_CLIENT_SECRET,
98-
disabled=not config.telemetry_enabled,
99+
disabled=is_disabled,
99100
)
100101

101-
if config.telemetry_enabled and not _initialized:
102+
if config.telemetry_enabled and not config.is_test_env and not _initialized:
102103
# Set global properties that go with every event
103104
_client.set_global_properties(
104105
{

0 commit comments

Comments
 (0)