Skip to content

Commit 3aa5e97

Browse files
committed
Fix broken tests in CI and improve package management
1 parent 052b541 commit 3aa5e97

File tree

11 files changed

+96
-139
lines changed

11 files changed

+96
-139
lines changed

.github/workflows/tests.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ jobs:
6060
- '**/*.yml'
6161
- '**/*.yaml'
6262
- 'pyproject.toml'
63-
- 'requirements*.txt'
6463
- 'uv.lock'
6564
6665
- name: Install uv

CONTRIBUTING.md

Lines changed: 2 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ To extend with a new cache backend (e.g., Memcached, DynamoDB):
4646

4747
### Installation
4848

49-
#### Option 1: Using UV (Recommended for Development)
49+
#### Using UV
5050

5151
UV provides faster dependency resolution and better development experience.
5252

@@ -69,33 +69,6 @@ UV provides faster dependency resolution and better development experience.
6969
cp .env.example .env # Edit .env with your JFrog details after copying it.
7070
```
7171

72-
#### Option 2: Using pip (Traditional)
73-
74-
1. **Clone the repository**
75-
```bash
76-
git clone <repository-url>
77-
cd malifiscan
78-
```
79-
80-
2. **Setup Python environment**
81-
```bash
82-
# Create virtual environment
83-
python -m venv venv
84-
source venv/bin/activate # On Windows: venv\Scripts\activate
85-
86-
# Upgrade pip
87-
pip install --upgrade pip
88-
89-
# Install dependencies
90-
pip install -r requirements.txt
91-
```
92-
93-
3. **Configure the application**
94-
```bash
95-
# Create .env file from example (if available) or create new one
96-
cp .env.example .env # Edit .env with your JFrog details after copying it.
97-
```
98-
9972
#### Verification
10073

10174
After installation, verify everything works:
@@ -205,7 +178,7 @@ storage_service:
205178

206179
## 🔄 Development Workflow
207180

208-
### Using UV (Recommended)
181+
### Using UV
209182

210183
UV provides a faster and more reliable development experience:
211184

@@ -234,27 +207,6 @@ uv run flake8 src/ tests/
234207
uv sync --dev
235208
```
236209

237-
### Using pip/venv (Traditional)
238-
239-
```bash
240-
# Activate environment (always required)
241-
source venv/bin/activate
242-
243-
# Run the application
244-
python cli.py health check
245-
python cli.py scan crossref
246-
247-
# Run tests
248-
pytest tests/unit/ -m "not integration" # Unit tests
249-
pytest tests/ -m integration # Integration tests
250-
251-
# Install additional dependencies
252-
pip install black isort flake8
253-
254-
# Update requirements
255-
pip freeze > requirements.txt
256-
```
257-
258210
## 🧪 Testing
259211

260212
### Overview

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,9 +200,9 @@ UV is a fast Python package manager that provides better dependency resolution a
200200
python -m venv venv
201201
source venv/bin/activate # On Windows: venv\Scripts\activate
202202

203-
# Upgrade pip and install dependencies
203+
# Install dependencies from pyproject.toml
204204
pip install --upgrade pip
205-
pip install -r requirements.txt
205+
pip install -e .
206206
```
207207

208208
2. **Initialize configuration**

pyproject.toml

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,19 +28,17 @@ dependencies = [
2828
"aiofiles==24.1.0",
2929
"aiohttp==3.9.1",
3030
"aiosqlite==0.21.0",
31-
"google-cloud-storage>=3.4.0",
31+
"google-cloud-storage==3.5.0",
3232
"protobuf==6.32.1",
3333
"pydantic==1.10.12",
3434
"python-dotenv==1.1.1",
3535
"PyYAML==6.0.2",
36+
"redis==7.0.1",
3637
"rich==14.1.0",
37-
"sqlalchemy>=1.4.0",
38+
"sqlalchemy==2.0.44",
3839
]
3940

4041
[project.optional-dependencies]
41-
redis = [
42-
"redis>=5.0.0",
43-
]
4442
test = [
4543
"pytest==7.4.3",
4644
"pytest-asyncio==0.21.1",

requirements-dev.txt

Lines changed: 0 additions & 2 deletions
This file was deleted.

requirements.txt

Lines changed: 0 additions & 8 deletions
This file was deleted.

src/providers/storage/database_storage.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,20 @@ async def health_check(self) -> bool:
664664
except Exception:
665665
return False
666666

667+
def close(self) -> None:
668+
"""
669+
Close database connections and dispose of the engine.
670+
671+
This method should be called when the storage is no longer needed
672+
to ensure proper cleanup of database resources.
673+
"""
674+
try:
675+
if hasattr(self, "engine") and self.engine:
676+
self.engine.dispose()
677+
logger.debug("Database engine disposed successfully")
678+
except Exception as e:
679+
logger.warning(f"Error disposing database engine: {e}")
680+
667681
def _malicious_package_model_to_entity(
668682
self, model: MaliciousPackageModel
669683
) -> MaliciousPackage:

tests/integration/test_database_integration.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,11 @@ async def get_supported_ecosystems(self):
4848

4949
@pytest.fixture
5050
def db_storage():
51-
return DatabaseStorage(database_path=":memory:", in_memory=True)
51+
"""Create an in-memory database storage for testing with proper cleanup."""
52+
storage = DatabaseStorage(database_path=":memory:", in_memory=True)
53+
yield storage
54+
# Cleanup: dispose of the database engine to prevent resource warnings
55+
storage.close()
5256

5357

5458
@pytest.fixture

tests/unit/core/cache/test_package_cache.py

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,11 @@ def test_redis_provider_successful_connection(self):
329329
mock_redis_client = MagicMock()
330330
mock_redis_client.ping.return_value = True
331331

332-
with patch("redis.from_url", return_value=mock_redis_client):
332+
# Mock the redis module at the point where it's imported in RedisCacheProvider
333+
mock_redis_module = MagicMock()
334+
mock_redis_module.from_url.return_value = mock_redis_client
335+
336+
with patch.dict("sys.modules", {"redis": mock_redis_module}):
333337
provider = RedisCacheProvider(redis_url="redis://localhost:6379/0")
334338

335339
assert provider.is_connected() is True
@@ -338,20 +342,14 @@ def test_redis_provider_successful_connection(self):
338342

339343
def test_redis_provider_connection_failure(self):
340344
"""Test Redis provider handles connection failure gracefully."""
341-
with patch("redis.from_url", side_effect=ConnectionError("Connection refused")):
342-
provider = RedisCacheProvider(redis_url="redis://localhost:6379/0")
343-
344-
assert provider.is_connected() is False
345-
assert provider.get_backend_name() == "redis"
345+
mock_redis_module = MagicMock()
346+
mock_redis_module.from_url.side_effect = ConnectionError("Connection refused")
346347

347-
def test_redis_provider_import_error(self):
348-
"""Test Redis provider handles missing redis package."""
349-
with patch(
350-
"builtins.__import__", side_effect=ImportError("No module named 'redis'")
351-
):
348+
with patch.dict("sys.modules", {"redis": mock_redis_module}):
352349
provider = RedisCacheProvider(redis_url="redis://localhost:6379/0")
353350

354351
assert provider.is_connected() is False
352+
assert provider.get_backend_name() == "redis"
355353

356354
def test_redis_provider_no_url(self):
357355
"""Test Redis provider with no URL provided."""

tests/unit/providers/test_database_storage.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,13 @@
88

99
@pytest.fixture
1010
def db_storage():
11-
return DatabaseStorage(
11+
"""Create an in-memory database storage for testing with proper cleanup."""
12+
storage = DatabaseStorage(
1213
database_path=":memory:", in_memory=True, connection_timeout=5.0
1314
)
15+
yield storage
16+
# Cleanup: dispose of the database engine to prevent resource warnings
17+
storage.close()
1418

1519

1620
@pytest.fixture

0 commit comments

Comments
 (0)