Skip to content

Commit

Permalink
update lockable module (#11)
Browse files Browse the repository at this point in the history
move core functionality to separate library
  • Loading branch information
jupe authored Oct 5, 2020
1 parent 867d2e6 commit e9928a6
Show file tree
Hide file tree
Showing 5 changed files with 18 additions and 30 deletions.
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
pytest plugin for lockable resources.

Replacement for Jenkins lockable -plugin.
Locking is implemented using `<resource.id>.lock` files.
Locking is implemented using `<resource-id>.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`.

Expand Down Expand Up @@ -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}')
```

Expand Down
2 changes: 1 addition & 1 deletion example/test_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
37 changes: 11 additions & 26 deletions pytest_lockable/plugin.py
Original file line number Diff line number Diff line change
@@ -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):
Expand All @@ -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)
Expand All @@ -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
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
python_requires='>=3.7, <4',
install_requires=[
'pytest',
'lockable==0.1.1',
'lockable==0.2.0',
'func_timeout',
'filelock',
'pydash'
Expand Down
1 change: 1 addition & 0 deletions tests/test_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit e9928a6

Please sign in to comment.