-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathconftest.py
More file actions
110 lines (79 loc) · 3.56 KB
/
conftest.py
File metadata and controls
110 lines (79 loc) · 3.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
"""Pytest configuration and shared fixtures for the tests package."""
import sys
import tempfile
from pathlib import Path
import pytest
ROOT_DIR = Path(__file__).resolve().parents[1]
SRC_DIR = ROOT_DIR / "src"
if str(SRC_DIR) not in sys.path:
sys.path.insert(0, str(SRC_DIR)) # Ensure code_rag package is importable
def pytest_configure(config):
"""Register custom markers used throughout the tests."""
config.addinivalue_line("markers", "asyncio: mark test as async")
# Disable shared server mode during tests to avoid connection issues
import os
# Isolate user-level config so developer machines don't leak ~/.config values into tests.
# Many tests assume defaults from DEFAULT_CONFIG.
import tempfile
os.environ.setdefault("HOME", tempfile.mkdtemp(prefix="code-rag-test-home-"))
os.environ.pop("XDG_CONFIG_HOME", None)
os.environ["CODE_RAG_SHARED_SERVER"] = "false"
@pytest.fixture(scope="session")
def event_loop():
"""Provide a dedicated event loop for the entire pytest session."""
import asyncio
loop = asyncio.get_event_loop_policy().new_event_loop()
yield loop
loop.close()
@pytest.fixture(scope="session")
def mock_sentence_transformer_model():
"""Provide a lightweight mock of SentenceTransformer model for fast testing.
This mock simulates the essential behavior of a sentence-transformers model
without the 4-5 second load time. It's designed for testing lazy loading logic,
concurrency, and error handling without actually loading PyTorch weights.
Returns a factory function that creates mock models with controllable behavior.
"""
from unittest.mock import MagicMock
import numpy as np
def create_mock_model(embedding_dim=384, load_delay=0.0):
"""Create a mock model that behaves like SentenceTransformer.
Args:
embedding_dim: Dimension of embedding vectors to return
load_delay: Simulated load time in seconds (for testing wait behavior)
"""
import time
mock_model = MagicMock()
# Simulate model attributes
mock_model.get_sentence_embedding_dimension.return_value = embedding_dim
# Mock encode method to return deterministic embeddings
def mock_encode(texts, **kwargs):
if load_delay > 0:
time.sleep(load_delay)
if isinstance(texts, str):
texts = [texts]
# Return deterministic embeddings based on text hash
embeddings = []
for text in texts:
# Create a deterministic but varied embedding
seed = hash(text) % (2**31)
np.random.seed(seed)
embedding = np.random.randn(embedding_dim).astype(np.float32)
# Normalize to unit length (like real sentence-transformers)
embedding = embedding / np.linalg.norm(embedding)
embeddings.append(embedding)
# Return single array for single input, 2D numpy array for batch
if len(embeddings) > 1:
return np.array(embeddings) # 2D array for batch
else:
return embeddings[0] # 1D array for single
mock_model.encode = mock_encode
return mock_model
return create_mock_model
@pytest.fixture(scope="session")
def shared_temp_db():
"""Provide a shared temporary database directory for the entire test session."""
temp_dir = tempfile.mkdtemp()
yield temp_dir
# Cleanup happens after all tests complete
import shutil
shutil.rmtree(temp_dir, ignore_errors=True)