From e9928a6f7769496a18433fd7264d68bc04655e54 Mon Sep 17 00:00:00 2001 From: Jussi Vatjus-Anttila Date: Mon, 5 Oct 2020 10:10:00 +0300 Subject: [PATCH] update lockable module (#11) move core functionality to separate library --- README.md | 6 ++++-- example/test_example.py | 2 +- pytest_lockable/plugin.py | 37 +++++++++++-------------------------- setup.py | 2 +- tests/test_plugin.py | 1 + 5 files changed, 18 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index c01aa87..91a9592 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,9 @@ pytest plugin for lockable resources. Replacement for Jenkins lockable -plugin. -Locking is implemented using `.lock` files. +Locking is implemented using `.pid` files and is released automatically. + +Resources are automatically released when pytest ends. Resources are described in json file as array of objects. Each object has some mandatory fields but can contains any other as well. Required fields are: `id`, `online`, `hostname`. @@ -83,7 +85,7 @@ Allocate lockable resource during test with given requirements ``` python def test_example(lockable): """ Simple test """ - with lockable({"my": "requirements"}) as resource: + with lockable.auto_lock({"my": "requirements"}) as resource: print(f'Testing with resource#: {resource}') ``` diff --git a/example/test_example.py b/example/test_example.py index 95f3717..ba62584 100644 --- a/example/test_example.py +++ b/example/test_example.py @@ -17,6 +17,6 @@ def test_example1(lockable_resource): def test_example2(lockable_resource, lockable): """ Simple test """ print(f'Testing with resource: {lockable_resource}') - with lockable({}) as resource: + with lockable.auto_lock({}) as resource: print(f'Testing with resource#2: {resource}') sleep(1) diff --git a/pytest_lockable/plugin.py b/pytest_lockable/plugin.py index 7ff9d14..0ad7c81 100644 --- a/pytest_lockable/plugin.py +++ b/pytest_lockable/plugin.py @@ -1,10 +1,8 @@ """ Lockable plugin for pytest """ -import json import socket import tempfile -from contextlib import contextmanager import pytest -from lockable import parse_requirements, get_requirements, read_resources_list, lock +from lockable import Lockable def pytest_addoption(parser): @@ -21,35 +19,21 @@ def pytest_addoption(parser): @pytest.fixture(scope="session", autouse=True) -def lockable(pytestconfig, record_testsuite_property): +def lockable(pytestconfig): """ pytest fixture that yields function for allocate any resource .. code-block:: python - def test_foo(lockable_allocate): - with lockable({my: "resource}) as resource: + def test_foo(lockable): + with lockable.auto_lock({my: "resource}) as resource: print(resource) """ - resource_list = read_resources_list(pytestconfig.getoption('allocation_resource_list_file')) - timeout_s = pytestconfig.getoption('allocation_timeout') - lock_folder = pytestconfig.getoption('allocation_lock_folder') - @contextmanager - def _lock(requirements, prefix='resource'): - nonlocal resource_list, timeout_s, lock_folder - requirements = parse_requirements(requirements) - predicate = get_requirements(requirements, pytestconfig.getoption('allocation_hostname')) - print(f"Use lock folder: {lock_folder}") - print(f"Requirements: {json.dumps(predicate)}") - print(f"Resource list: {json.dumps(resource_list)}") - with lock(predicate, resource_list, timeout_s, lock_folder) as resource: - for key, value in resource.items(): - record_testsuite_property(f'resource_{key}', value) - if pytestconfig.pluginmanager.hasplugin('metadata'): - # pylint: disable=protected-access - pytestconfig._metadata[f'{prefix}_{key}'] = value - yield resource + resource_list_file = pytestconfig.getoption('allocation_resource_list_file') + lock_folder = pytestconfig.getoption('allocation_lock_folder') + hostname = pytestconfig.getoption('allocation_hostname') - yield _lock + _lockable = Lockable(hostname=hostname, resource_list_file=resource_list_file, lock_folder=lock_folder) + yield _lockable @pytest.fixture(scope="session", autouse=True) @@ -61,5 +45,6 @@ def test_foo(lockable_resource): print(f'Testing with resource: {lockable_resource}') """ requirements = pytestconfig.getoption('allocation_requirements') - with lockable(requirements) as resource: + timeout_s = pytestconfig.getoption('allocation_timeout') + with lockable.auto_lock(requirements, timeout_s) as resource: yield resource diff --git a/setup.py b/setup.py index 0de72a4..5a143ee 100644 --- a/setup.py +++ b/setup.py @@ -55,7 +55,7 @@ python_requires='>=3.7, <4', install_requires=[ 'pytest', - 'lockable==0.1.1', + 'lockable==0.2.0', 'func_timeout', 'filelock', 'pydash' diff --git a/tests/test_plugin.py b/tests/test_plugin.py index 04f661f..02f5696 100644 --- a/tests/test_plugin.py +++ b/tests/test_plugin.py @@ -13,6 +13,7 @@ def test_e2e(self): example_root = join(here, "../example") exit_code = pytest.main([ "-x", # exit instantly on first error or failed test. + "-vvv", "-s", "--rootdir", example_root, "--allocation_resource_list_file", join(example_root, "resources.json"), "--allocation_lock_folder", example_root,