Skip to content

Commit 867d2e6

Browse files
authored
refactor locking Core functionality to separate library (#10)
1 parent 213d923 commit 867d2e6

File tree

7 files changed

+69
-321
lines changed

7 files changed

+69
-321
lines changed

.circleci/config.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,13 @@ jobs:
6565
command: |
6666
mkdir junit || true
6767
. venv/bin/activate;
68-
nosetests --with-xunit --with-coverage --cover-package=lockable --cover-html --cover-html-dir=htmlcov --cover-xml-file=coverage.xml --xunit-file=junit/results.xml
68+
nosetests --with-xunit --with-coverage --cover-package=pytest_lockable --cover-html --cover-html-dir=htmlcov --cover-xml-file=coverage.xml --xunit-file=junit/results.xml
6969
coveralls || true
7070
- run:
7171
name: pylint
7272
command: |
7373
. venv/bin/activate;
74-
pylint lockable
74+
pylint pytest_lockable
7575
- run:
7676
name: run
7777
command: |

example/conftest.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@
55
PLUGIN_DIR = os.path.join(TEST_DIR, '../')
66
sys.path.insert(0, PLUGIN_DIR)
77

8-
pytest_plugins = ("lockable.plugin", "metadata") # pylint: disable=invalid-name
8+
pytest_plugins = ("pytest_lockable.plugin", "metadata") # pylint: disable=invalid-name

lockable/plugin.py

-187
This file was deleted.
File renamed without changes.

pytest_lockable/plugin.py

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
""" Lockable plugin for pytest """
2+
import json
3+
import socket
4+
import tempfile
5+
from contextlib import contextmanager
6+
import pytest
7+
from lockable import parse_requirements, get_requirements, read_resources_list, lock
8+
9+
10+
def pytest_addoption(parser):
11+
"""
12+
register argparse-style options and ini-style config values,
13+
called once at the beginning of a test run
14+
"""
15+
group = parser.getgroup("lockable")
16+
group.addoption("--allocation_hostname", default=socket.gethostname(), help="Allocation host")
17+
group.addoption("--allocation_requirements", default=None, help="Resource requirements to be allocate")
18+
group.addoption("--allocation_timeout", default=10, help="Allocation timeout")
19+
group.addoption("--allocation_resource_list_file", default='resources.json', help="Available resorces list")
20+
group.addoption("--allocation_lock_folder", default=tempfile.gettempdir(), help="Allocation lockfiles folder")
21+
22+
23+
@pytest.fixture(scope="session", autouse=True)
24+
def lockable(pytestconfig, record_testsuite_property):
25+
"""
26+
pytest fixture that yields function for allocate any resource
27+
.. code-block:: python
28+
def test_foo(lockable_allocate):
29+
with lockable({my: "resource}) as resource:
30+
print(resource)
31+
"""
32+
resource_list = read_resources_list(pytestconfig.getoption('allocation_resource_list_file'))
33+
timeout_s = pytestconfig.getoption('allocation_timeout')
34+
lock_folder = pytestconfig.getoption('allocation_lock_folder')
35+
36+
@contextmanager
37+
def _lock(requirements, prefix='resource'):
38+
nonlocal resource_list, timeout_s, lock_folder
39+
requirements = parse_requirements(requirements)
40+
predicate = get_requirements(requirements, pytestconfig.getoption('allocation_hostname'))
41+
print(f"Use lock folder: {lock_folder}")
42+
print(f"Requirements: {json.dumps(predicate)}")
43+
print(f"Resource list: {json.dumps(resource_list)}")
44+
with lock(predicate, resource_list, timeout_s, lock_folder) as resource:
45+
for key, value in resource.items():
46+
record_testsuite_property(f'resource_{key}', value)
47+
if pytestconfig.pluginmanager.hasplugin('metadata'):
48+
# pylint: disable=protected-access
49+
pytestconfig._metadata[f'{prefix}_{key}'] = value
50+
yield resource
51+
52+
yield _lock
53+
54+
55+
@pytest.fixture(scope="session", autouse=True)
56+
def lockable_resource(pytestconfig, lockable): # pylint: disable=redefined-outer-name
57+
"""
58+
pytest fixture that lock suitable resource and yield it
59+
.. code-block:: python
60+
def test_foo(lockable_resource):
61+
print(f'Testing with resource: {lockable_resource}')
62+
"""
63+
requirements = pytestconfig.getoption('allocation_requirements')
64+
with lockable(requirements) as resource:
65+
yield resource

setup.py

+1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
python_requires='>=3.7, <4',
5656
install_requires=[
5757
'pytest',
58+
'lockable==0.1.1',
5859
'func_timeout',
5960
'filelock',
6061
'pydash'

0 commit comments

Comments
 (0)