From 01675b3001737c30bd4f1ac13e405a3859f1f649 Mon Sep 17 00:00:00 2001 From: Federico Repond Date: Tue, 30 Aug 2022 15:37:45 -0300 Subject: [PATCH 1/6] change fixtures to session for improved performance --- pytest_motor/plugin.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/pytest_motor/plugin.py b/pytest_motor/plugin.py index 129896b..de7c95b 100644 --- a/pytest_motor/plugin.py +++ b/pytest_motor/plugin.py @@ -26,16 +26,12 @@ def _event_loop() -> Iterator[asyncio.AbstractEventLoop]: event_loop = pytest.fixture(fixture_function=_event_loop, scope='session', name="event_loop") -async def _root_directory(pytestconfig: PytestConfig) -> Path: +@pytest.fixture(scope='session') +async def root_directory(pytestconfig: PytestConfig) -> Path: """Return the root path of pytest.""" return pytestconfig.rootpath -root_directory = pytest.fixture(fixture_function=_root_directory, - scope='session', - name='root_directory') - - @pytest.fixture(scope='session') async def mongod_binary(root_directory: Path) -> Path: # pylint: disable=redefined-outer-name @@ -47,27 +43,27 @@ async def mongod_binary(root_directory: Path) -> Path: return binary.path -@pytest.fixture(scope='function') +@pytest.fixture(scope='session') def new_port() -> int: """Return an unused port for mongod to run on.""" port: int = 27017 with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as opened_socket: - opened_socket.bind(('127.0.0.1', 0)) # system will automaticly assign port + opened_socket.bind(("127.0.0.1", 0)) # system will automaticly assign port port = opened_socket.getsockname()[1] return port -async def _database_path(tmp_path: Path) -> AsyncIterator[Path]: +async def _database_path() -> AsyncIterator[Path]: """Yield a database path for a mongod process to store data.""" - yield tmp_path + yield "/tmp" database_path = pytest.fixture(fixture_function=_database_path, - scope='function', - name='database_path') + scope='session', + name="database_path") -@pytest.fixture(scope='function') +@pytest.fixture(scope='session') async def mongod_socket(new_port: int, database_path: Path, mongod_binary: Path) -> AsyncIterator[str]: # pylint: disable=redefined-outer-name @@ -104,4 +100,8 @@ async def motor_client(mongod_socket: str) -> AsyncIterator[AsyncIOMotorClient]: yield motor_client_ - motor_client_.close() + dbs = await motor_client_.list_database_names() + + for db in dbs: + if db not in ["config", "admin", "local"]: + await motor_client_.drop_database(db) From 4314f3a70b444c5be515dff9b765b351219b9eae Mon Sep 17 00:00:00 2001 From: Federico Repond Date: Tue, 30 Aug 2022 15:58:29 -0300 Subject: [PATCH 2/6] generic temp dir --- pytest_motor/plugin.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pytest_motor/plugin.py b/pytest_motor/plugin.py index de7c95b..2477510 100644 --- a/pytest_motor/plugin.py +++ b/pytest_motor/plugin.py @@ -1,6 +1,7 @@ """A pytest plugin which helps test applications using Motor.""" import asyncio import socket +import tempfile from pathlib import Path from typing import AsyncIterator, Iterator, List @@ -55,7 +56,8 @@ def new_port() -> int: async def _database_path() -> AsyncIterator[Path]: """Yield a database path for a mongod process to store data.""" - yield "/tmp" + with tempfile.TemporaryDirectory() as tmpdirname: + yield tmpdirname database_path = pytest.fixture(fixture_function=_database_path, From a8711eea9b0e4f44683444459c033889596937db Mon Sep 17 00:00:00 2001 From: Federico Repond Date: Tue, 30 Aug 2022 18:09:13 -0300 Subject: [PATCH 3/6] default to ubuntu 1804 --- pytest_motor/mongod_binary.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/pytest_motor/mongod_binary.py b/pytest_motor/mongod_binary.py index f571d3e..f6d6309 100644 --- a/pytest_motor/mongod_binary.py +++ b/pytest_motor/mongod_binary.py @@ -54,8 +54,10 @@ def current_platform(self) -> str: distro_name = distro.id() if distro_name == 'ubuntu': return 'linux-x86_64-' + MongodBinary.__select_ubuntu_version() - if distro_name == 'debian': + elif distro_name == 'debian': return 'linux-x86_64-' + MongodBinary.__select_debian_version() + else: + return "linux-x86_64-" + "ubuntu1804" # FUTURE: distros that may be added: Amazon Linux, CentOS, SUSE raise OSError(f"Your distro ({distro_name}) is unsupported.") @@ -135,12 +137,14 @@ def __select_debian_version() -> str: raise OSError( "Your Debian version is too old. Upgrade at least to 9.") # pragma: no cover - if distro.version() == '9.2': + if distro.version().startswith('9'): MongodBinary.warn_untested_os() return 'debian92' - if distro.version() == '10.0': + if distro.version().startswith('10'): MongodBinary.warn_untested_os() return 'debian10' + if distro.version().startswith('11'): + return 'ubuntu1804' warnings.warn("Can't detect your Debian version. Fallback to 9.2.") return 'debian92' From e754a86377e0542d6c492e15b3f35f22269a685a Mon Sep 17 00:00:00 2001 From: Federico Repond Date: Wed, 31 Aug 2022 09:33:41 -0300 Subject: [PATCH 4/6] better reuse of motor client and cleanup --- pytest_motor/plugin.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/pytest_motor/plugin.py b/pytest_motor/plugin.py index 2477510..45932b9 100644 --- a/pytest_motor/plugin.py +++ b/pytest_motor/plugin.py @@ -91,8 +91,8 @@ async def mongod_socket(new_port: int, database_path: Path, pass -@pytest.fixture(scope='function') -async def motor_client(mongod_socket: str) -> AsyncIterator[AsyncIOMotorClient]: +@pytest.fixture(scope="session") +async def __motor_client(mongod_socket: str) -> AsyncIterator[AsyncIOMotorClient]: # pylint: disable=redefined-outer-name """Yield a Motor client.""" connection_string = f'mongodb://{mongod_socket}' @@ -102,7 +102,16 @@ async def motor_client(mongod_socket: str) -> AsyncIterator[AsyncIOMotorClient]: yield motor_client_ - dbs = await motor_client_.list_database_names() + motor_client_.close() + + +@pytest.fixture(scope='function') +async def motor_client(__motor_client: AsyncIterator[AsyncIOMotorClient]) -> AsyncIterator[AsyncIOMotorClient]: + # pylint: disable=redefined-outer-name + """Yield a Motor client.""" + yield __motor_client + + dbs = await __motor_client.list_database_names() for db in dbs: if db not in ["config", "admin", "local"]: From 5c556770a29e94d5531d1afb61c93e2485fdbe92 Mon Sep 17 00:00:00 2001 From: Federico Repond Date: Wed, 31 Aug 2022 09:40:38 -0300 Subject: [PATCH 5/6] fixed typo --- pytest_motor/plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pytest_motor/plugin.py b/pytest_motor/plugin.py index 45932b9..1f76a39 100644 --- a/pytest_motor/plugin.py +++ b/pytest_motor/plugin.py @@ -115,4 +115,4 @@ async def motor_client(__motor_client: AsyncIterator[AsyncIOMotorClient]) -> Asy for db in dbs: if db not in ["config", "admin", "local"]: - await motor_client_.drop_database(db) + await __motor_client.drop_database(db) From 8ee48719b1393de3295a75151e7e1bd7f40fe480 Mon Sep 17 00:00:00 2001 From: Federico Repond Date: Wed, 14 Sep 2022 08:45:58 -0300 Subject: [PATCH 6/6] pytest-asyncio for async fistures and bumped version --- CHANGES.md | 14 ++++++++++++++ VERSION.txt | 2 +- pytest_motor/plugin.py | 19 ++++++++----------- setup.py | 2 +- 4 files changed, 24 insertions(+), 13 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 8820e23..0818f66 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,12 +1,21 @@ # Change log +## v0.3.1 + +- Reuse mongod session between tests for performance improvements + - Drops database instead of +- Generic tmp folder +- Add support for async fixtures + ## v0.3.0 + - Add support for Windows, Debian, Ubuntu 16.04, and Ubuntu 20.04. - Improve the readme. - Add section about how `pytest-motor` works. - Add installation instructions. ## v0.2.0 + - Add MacOS support. - Change the mongod binary download to be async. - Change mongod connection from using unix sockets to ports. @@ -15,21 +24,26 @@ - Add MIT license. ## v0.1.4 + - Change to async fixtures. - Fix package URL. - Refactor internal fixtures. ## v0.1.3 + - Improve the readme. - Add an example. - Add a link to pytest. - Add a link to Motor. ## v0.1.2 + - Add more package classifiers. ## v0.1.1 + - Fix package description. ## v0.1.0 + Initial release. diff --git a/VERSION.txt b/VERSION.txt index 0d91a54..9e11b32 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -0.3.0 +0.3.1 diff --git a/pytest_motor/plugin.py b/pytest_motor/plugin.py index 1f76a39..5d7870c 100644 --- a/pytest_motor/plugin.py +++ b/pytest_motor/plugin.py @@ -6,6 +6,7 @@ from typing import AsyncIterator, Iterator, List import pytest +import pytest_asyncio from _pytest.config import Config as PytestConfig from motor.motor_asyncio import AsyncIOMotorClient @@ -27,13 +28,13 @@ def _event_loop() -> Iterator[asyncio.AbstractEventLoop]: event_loop = pytest.fixture(fixture_function=_event_loop, scope='session', name="event_loop") -@pytest.fixture(scope='session') +@pytest_asyncio.fixture(scope='session') async def root_directory(pytestconfig: PytestConfig) -> Path: """Return the root path of pytest.""" return pytestconfig.rootpath -@pytest.fixture(scope='session') +@pytest_asyncio.fixture(scope='session') async def mongod_binary(root_directory: Path) -> Path: # pylint: disable=redefined-outer-name """Return a path to a mongod binary.""" @@ -54,18 +55,14 @@ def new_port() -> int: return port -async def _database_path() -> AsyncIterator[Path]: +@pytest.fixture(scope="session") +def database_path() -> Iterator[str]: """Yield a database path for a mongod process to store data.""" with tempfile.TemporaryDirectory() as tmpdirname: yield tmpdirname -database_path = pytest.fixture(fixture_function=_database_path, - scope='session', - name="database_path") - - -@pytest.fixture(scope='session') +@pytest_asyncio.fixture(scope='session') async def mongod_socket(new_port: int, database_path: Path, mongod_binary: Path) -> AsyncIterator[str]: # pylint: disable=redefined-outer-name @@ -92,7 +89,7 @@ async def mongod_socket(new_port: int, database_path: Path, @pytest.fixture(scope="session") -async def __motor_client(mongod_socket: str) -> AsyncIterator[AsyncIOMotorClient]: +def __motor_client(mongod_socket: str) -> AsyncIterator[AsyncIOMotorClient]: # pylint: disable=redefined-outer-name """Yield a Motor client.""" connection_string = f'mongodb://{mongod_socket}' @@ -105,7 +102,7 @@ async def __motor_client(mongod_socket: str) -> AsyncIterator[AsyncIOMotorClient motor_client_.close() -@pytest.fixture(scope='function') +@pytest_asyncio.fixture(scope='function') async def motor_client(__motor_client: AsyncIterator[AsyncIOMotorClient]) -> AsyncIterator[AsyncIOMotorClient]: # pylint: disable=redefined-outer-name """Yield a Motor client.""" diff --git a/setup.py b/setup.py index 8214a59..e52c696 100644 --- a/setup.py +++ b/setup.py @@ -36,5 +36,5 @@ 'Typing :: Typed', ], python_requires='>=3.6', - install_requires=['pytest', 'motor', 'aiohttp[speedups]', 'distro'], + install_requires=['pytest', 'pytest-asyncio', 'motor', 'aiohttp[speedups]', 'distro'], )