Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions api/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@

from beanie import init_beanie
from bson import ObjectId
from fastapi_pagination.ext.motor import paginate
from fastapi_pagination.ext.pymongo import apaginate as paginate
from kernelci.api.models import (
EventHistory,
Hierarchy,
Node,
TelemetryEvent,
parse_node_obj,
)
from motor import motor_asyncio
from pymongo import AsyncMongoClient
from redis import asyncio as aioredis

from .models import User, UserGroup
Expand Down Expand Up @@ -52,10 +52,10 @@ class Database:
BOOL_VALUE_MAP = {"true": True, "false": False}

def __init__(self, service="mongodb://db:27017", db_name="kernelci"):
self._motor = motor_asyncio.AsyncIOMotorClient(service)
self._mongo = AsyncMongoClient(service)
# TBD: Make redis host configurable
self._redis = aioredis.from_url("redis://redis:6379")
self._db = self._motor[db_name]
self._db = self._mongo[db_name]

async def initialize_beanie(self):
"""Initialize Beanie ODM to use `fastapi-users` tools for MongoDB"""
Expand Down
5 changes: 2 additions & 3 deletions api/pubsub_mongo.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@
from typing import Any, Dict, List, Optional

from cloudevents.http import CloudEvent, to_json
from motor import motor_asyncio
from pymongo import ASCENDING, WriteConcern
from pymongo import ASCENDING, AsyncMongoClient, WriteConcern
from redis import asyncio as aioredis

from .config import PubSubSettings
Expand Down Expand Up @@ -87,7 +86,7 @@ def __init__(
# MongoDB setup
if mongo_client is None:
mongo_service = os.getenv("MONGO_SERVICE") or "mongodb://db:27017"
self._mongo_client = motor_asyncio.AsyncIOMotorClient(mongo_service)
self._mongo_client = AsyncMongoClient(mongo_service)
else:
self._mongo_client = mongo_client
self._mongo_db = self._mongo_client[mongo_db_name]
Expand Down
1 change: 0 additions & 1 deletion docker/api/requirements-tests.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,3 @@ pytest-dependency==0.5.1
pytest-mock==3.6.1
pytest-order==1.0.1
httpx>=0.27.0,<1.0.0
mongomock_motor==0.0.21
8 changes: 4 additions & 4 deletions docker/api/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
cloudevents==2.0.0
beanie==1.29.0
beanie==2.1.0
fastapi[all]==0.135.3
fastapi-pagination==0.12.30
fastapi-pagination==0.14.3
fastapi-users[beanie, oauth]==15.0.5
fastapi-users-db-beanie==5.0.0
MarkupSafe==2.0.1
motor==3.6.0
pymongo==4.9.0
pymongo==4.16.0
passlib==1.7.4
pydantic==2.9.2
pymongo-migrate==0.11.0
Expand Down
5 changes: 2 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ dependencies = [
"cloudevents == 2.0.0",
"beanie == 2.1.0",
"fastapi[all] == 0.135.3",
"fastapi-pagination == 0.12.30",
"fastapi-pagination == 0.14.3",
"fastapi-users[beanie, oauth] == 15.0.5",
"fastapi-users-db-beanie == 5.0.0",
"MarkupSafe == 2.0.1",
"motor == 3.6.0",
"pymongo == 4.16.0",
"passlib == 1.7.4",
"pydantic == 2.9.2",
Expand All @@ -41,7 +41,6 @@ tests = [
"pytest-mock == 3.6.1",
"pytest-order == 1.0.1",
"httpx >= 0.27.0, < 1.0.0",
"mongomock_motor == 0.0.36",
]
dev = [
"kernelci-api[tests]",
Expand Down
12 changes: 6 additions & 6 deletions tests/e2e_tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,20 @@

"""pytest fixtures for KernelCI API end-to-end tests"""

import asyncio

import pytest
from httpx import ASGITransport, AsyncClient
from kernelci.api.models import Node, Regression
from motor.motor_asyncio import AsyncIOMotorClient
from pymongo import AsyncMongoClient

from api.main import versioned_app

BASE_URL = "http://api:8000/latest/"
DB_URL = "mongodb://db:27017"
DB_NAME = "kernelci"

db_client = AsyncIOMotorClient(DB_URL)
db_client = AsyncMongoClient(DB_URL)
db = db_client[DB_NAME]
node_model_fields = set(Node.model_fields.keys())
regression_model_fields = set(Regression.model_fields.keys())
Expand Down Expand Up @@ -51,9 +53,7 @@ async def db_create(collection, obj):

@pytest.fixture(scope="session")
def event_loop():
"""Get an instance of the default event loop using database client.
The event loop will be used for all async tests.
"""
loop = db_client.get_io_loop()
"""Session-scoped event loop shared by all async tests."""
loop = asyncio.new_event_loop()
yield loop
loop.close()
15 changes: 7 additions & 8 deletions tests/unit_tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,9 @@

import fakeredis.aioredis
import pytest
from beanie import init_beanie
from fastapi import HTTPException, Request, status
from fastapi.testclient import TestClient
from httpx import ASGITransport, AsyncClient
from mongomock_motor import AsyncMongoMockClient

from api.main import (
app,
Expand Down Expand Up @@ -245,16 +243,17 @@ def mock_unsubscribe(mocker):

@pytest.fixture(autouse=True)
async def mock_init_beanie(mocker):
"""Mocks async call to Database method to initialize Beanie"""
"""Mocks async call to Database method to initialize Beanie.

All tests mock api.db.Database.* directly, so beanie never issues real
queries. Patching initialize_beanie to a no-op avoids pulling in an async
mongo mock, which beanie 2.x (pymongo AsyncMongoClient) has no replacement
for.
"""
async_mock = AsyncMock()
client = AsyncMongoMockClient()
init = await init_beanie(
document_models=[User], database=client.get_database(name="db")
)
mocker.patch(
"api.db.Database.initialize_beanie",
side_effect=async_mock,
return_value=init,
)
return async_mock

Expand Down
Loading