pyrelukko 0.3.0__tar.gz → 0.5.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pyrelukko might be problematic. Click here for more details.
- {pyrelukko-0.3.0 → pyrelukko-0.5.0}/.gitlab-ci.yml +37 -1
- {pyrelukko-0.3.0 → pyrelukko-0.5.0}/PKG-INFO +7 -4
- pyrelukko-0.5.0/cicd/run_pytest.sh +15 -0
- {pyrelukko-0.3.0 → pyrelukko-0.5.0}/container/requirements.txt +2 -0
- {pyrelukko-0.3.0 → pyrelukko-0.5.0}/pyproject.toml +10 -7
- {pyrelukko-0.3.0 → pyrelukko-0.5.0}/src/pyrelukko/pyrelukko.py +37 -13
- {pyrelukko-0.3.0 → pyrelukko-0.5.0}/src/pyrelukko/testcontainers.py +2 -6
- {pyrelukko-0.3.0 → pyrelukko-0.5.0}/src/pyrelukko/version.py +1 -1
- {pyrelukko-0.3.0 → pyrelukko-0.5.0}/tests/conftest.py +18 -9
- {pyrelukko-0.3.0 → pyrelukko-0.5.0}/tests/test_relukko.py +57 -3
- pyrelukko-0.3.0/cicd/run_pytest.sh +0 -14
- pyrelukko-0.3.0/tests/initdb.d/20240930160154_init.up.sql +0 -19
- {pyrelukko-0.3.0 → pyrelukko-0.5.0}/LICENSE +0 -0
- {pyrelukko-0.3.0 → pyrelukko-0.5.0}/README.md +0 -0
- {pyrelukko-0.3.0 → pyrelukko-0.5.0}/cicd/build-py-rf-image.sh +0 -0
- {pyrelukko-0.3.0 → pyrelukko-0.5.0}/cicd/run_docs_pages.sh +0 -0
- {pyrelukko-0.3.0 → pyrelukko-0.5.0}/cicd/run_pylint.sh +0 -0
- {pyrelukko-0.3.0 → pyrelukko-0.5.0}/cicd/run_shellcheck.sh +0 -0
- {pyrelukko-0.3.0 → pyrelukko-0.5.0}/container/Containerfile +0 -0
- {pyrelukko-0.3.0 → pyrelukko-0.5.0}/src/pyrelukko/__init__.py +0 -0
- {pyrelukko-0.3.0 → pyrelukko-0.5.0}/src/pyrelukko/retry.py +0 -0
- {pyrelukko-0.3.0 → pyrelukko-0.5.0}/tests/cert/5d868fca.0 +0 -0
- {pyrelukko-0.3.0 → pyrelukko-0.5.0}/tests/cert/README.md +0 -0
- {pyrelukko-0.3.0 → pyrelukko-0.5.0}/tests/cert/relukko.crt +0 -0
- {pyrelukko-0.3.0 → pyrelukko-0.5.0}/tests/cert/relukko.csr +0 -0
- {pyrelukko-0.3.0 → pyrelukko-0.5.0}/tests/cert/relukko.key +0 -0
- {pyrelukko-0.3.0 → pyrelukko-0.5.0}/tests/cert/rootCA.crt +0 -0
- {pyrelukko-0.3.0 → pyrelukko-0.5.0}/tests/cert/rootCA.der +0 -0
- {pyrelukko-0.3.0 → pyrelukko-0.5.0}/tests/cert/rootCA.key +0 -0
- {pyrelukko-0.3.0 → pyrelukko-0.5.0}/tests/cert/rootCA.srl +0 -0
|
@@ -13,6 +13,19 @@ variables:
|
|
|
13
13
|
Remove this when you trigger by hand an image build and want it to use
|
|
14
14
|
the new built image with Git short sha tag (X icon on the right)!
|
|
15
15
|
value: "latest"
|
|
16
|
+
RUN_PYTEST:
|
|
17
|
+
description: Used in rules, if "true" and web triggered run the pytests.
|
|
18
|
+
value: "false"
|
|
19
|
+
options:
|
|
20
|
+
- "false"
|
|
21
|
+
- "true"
|
|
22
|
+
RELUKKO_HOSTNAME: relukko
|
|
23
|
+
RELUKKO_BIND_PORT: 3000
|
|
24
|
+
RELUKKO_API_KEY: "somerandomkey"
|
|
25
|
+
POSTGRES_USER: relukko
|
|
26
|
+
POSTGRES_PASSWORD: okkuler
|
|
27
|
+
POSTGRES_DB: relukko
|
|
28
|
+
POSTGRES_HOSTNAME: postgres
|
|
16
29
|
# RUN_DOCS_PUBLISH:
|
|
17
30
|
# description: >-
|
|
18
31
|
# Used in rules, if "true" and web triggered it generates the docs and
|
|
@@ -22,6 +35,7 @@ variables:
|
|
|
22
35
|
# - "false"
|
|
23
36
|
# - "true"
|
|
24
37
|
|
|
38
|
+
|
|
25
39
|
build-py-rf-image:
|
|
26
40
|
stage: build
|
|
27
41
|
image: docker:25
|
|
@@ -56,6 +70,7 @@ build-py-rf-image:
|
|
|
56
70
|
- if: $CI_PIPELINE_SOURCE == "web" && $BUILD_IMAGE == "true"
|
|
57
71
|
when: always
|
|
58
72
|
|
|
73
|
+
|
|
59
74
|
run-pylint:
|
|
60
75
|
stage: test
|
|
61
76
|
image: "${CI_REGISTRY_IMAGE}/${IMAGE_NAME}:${IMAGE_TAG}"
|
|
@@ -79,7 +94,26 @@ run-pylint:
|
|
|
79
94
|
|
|
80
95
|
run-pytest:
|
|
81
96
|
stage: test
|
|
82
|
-
|
|
97
|
+
services:
|
|
98
|
+
- name: postgres:16
|
|
99
|
+
alias: postgres
|
|
100
|
+
- name: registry.gitlab.com/relukko/relukko:latest
|
|
101
|
+
alias: relukko
|
|
102
|
+
variables:
|
|
103
|
+
DATABASE_URL: "postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}"
|
|
104
|
+
RELUKKO_USER: "relukko"
|
|
105
|
+
RELUKKO_PASSWORD: "relukko"
|
|
106
|
+
RELUKKO_BIND_ADDR: "0.0.0.0"
|
|
107
|
+
HEALTHCHECK_TCP_PORT: "${RELUKKO_BIND_PORT}"
|
|
108
|
+
variables:
|
|
109
|
+
FF_NETWORK_PER_BUILD: 1
|
|
110
|
+
CI_HAS_RELUKKO: true
|
|
111
|
+
CI_RELUKKO_BASE_URL: "http://${RELUKKO_HOSTNAME}:${RELUKKO_BIND_PORT}"
|
|
112
|
+
CI_RELUKKO_API_KEY: "${RELUKKO_API_KEY}"
|
|
113
|
+
parallel:
|
|
114
|
+
matrix:
|
|
115
|
+
- PIPELINE_PY_VERSION: ['3.11', '3.12', '3.13']
|
|
116
|
+
image: "registry.gitlab.com/relukko/py-tox-images/py-$PIPELINE_PY_VERSION-tox"
|
|
83
117
|
rules:
|
|
84
118
|
- if: $CI_PIPELINE_SOURCE == "merge_request_event" && $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH
|
|
85
119
|
changes:
|
|
@@ -91,6 +125,8 @@ run-pytest:
|
|
|
91
125
|
- src/**/*.py
|
|
92
126
|
- tests/test_*.py
|
|
93
127
|
- tests/conftest.py
|
|
128
|
+
- if: $CI_PIPELINE_SOURCE == "web" && $RUN_PYTEST == "true"
|
|
129
|
+
when: always
|
|
94
130
|
before_script:
|
|
95
131
|
- echo "Running PyTest."
|
|
96
132
|
script:
|
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: pyrelukko
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.0
|
|
4
4
|
Summary: Relukko client.
|
|
5
5
|
Author-email: Reto Zingg <g.d0b3rm4n@gmail.com>
|
|
6
|
-
Requires-Python: >=3.
|
|
6
|
+
Requires-Python: >=3.10
|
|
7
7
|
Description-Content-Type: text/markdown
|
|
8
|
-
Classifier: Development Status ::
|
|
8
|
+
Classifier: Development Status :: 4 - Beta
|
|
9
9
|
Classifier: Intended Audience :: Developers
|
|
10
10
|
Classifier: License :: OSI Approved :: MIT License
|
|
11
11
|
Classifier: Topic :: Internet :: WWW/HTTP
|
|
12
12
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
13
16
|
Requires-Dist: requests >=2.32.3
|
|
14
|
-
Requires-Dist: websockets >=
|
|
17
|
+
Requires-Dist: websockets >= 14.1
|
|
15
18
|
Project-URL: Homepage, https://gitlab.com/relukko/pyrelukko
|
|
16
19
|
Project-URL: Issues, https://gitlab.com/relukko/pyrelukko/-/issues
|
|
17
20
|
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# SCRIPT_DIR=$(dirname "$(readlink -f "$0")")
|
|
4
|
+
# REPO_DIR="${SCRIPT_DIR}/.."
|
|
5
|
+
|
|
6
|
+
# Main script execution
|
|
7
|
+
main() {
|
|
8
|
+
# pytest --junit-xml "${REPO_DIR}/pytest-junit.xml"
|
|
9
|
+
tox run --skip-missing-interpreters
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
# Execute the main function
|
|
13
|
+
main
|
|
14
|
+
|
|
15
|
+
# vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
|
|
@@ -7,17 +7,20 @@ readme = "README.md"
|
|
|
7
7
|
|
|
8
8
|
# https://pypi.org/pypi?%3Aaction=list_classifiers
|
|
9
9
|
classifiers = [
|
|
10
|
-
"Development Status ::
|
|
10
|
+
"Development Status :: 4 - Beta",
|
|
11
11
|
"Intended Audience :: Developers",
|
|
12
12
|
"License :: OSI Approved :: MIT License",
|
|
13
13
|
"Topic :: Internet :: WWW/HTTP",
|
|
14
14
|
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
15
|
+
"Programming Language :: Python :: 3.11",
|
|
16
|
+
"Programming Language :: Python :: 3.12",
|
|
17
|
+
"Programming Language :: Python :: 3.13",
|
|
15
18
|
]
|
|
16
|
-
requires-python = ">=3.
|
|
19
|
+
requires-python = ">=3.10"
|
|
17
20
|
dynamic = ["version", "description"]
|
|
18
21
|
dependencies = [
|
|
19
22
|
"requests >=2.32.3",
|
|
20
|
-
"websockets >=
|
|
23
|
+
"websockets >= 14.1",
|
|
21
24
|
]
|
|
22
25
|
|
|
23
26
|
[tool.flit.sdist]
|
|
@@ -41,14 +44,14 @@ pythonpath = [
|
|
|
41
44
|
|
|
42
45
|
[tool.tox]
|
|
43
46
|
requires = ["tox>=4.23"]
|
|
44
|
-
env_list = ["3.
|
|
47
|
+
env_list = ["3.11", "3.12", "3.13"]
|
|
45
48
|
|
|
46
49
|
[tool.tox.env_run_base]
|
|
47
50
|
description = "Run test under {base_python}"
|
|
48
|
-
commands = [["pytest"]]
|
|
51
|
+
commands = [["pytest", "--junit-xml", "pytest-junit.xml"]]
|
|
49
52
|
deps = ["httpx", "pytest", "testcontainers"]
|
|
50
|
-
set_env = { VIRTUALENV_DISCOVERY = "pyenv" }
|
|
51
|
-
pass_env = [ "TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE", "DOCKER_HOST" ]
|
|
53
|
+
# set_env = { VIRTUALENV_DISCOVERY = "pyenv" }
|
|
54
|
+
pass_env = [ "TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE", "DOCKER_HOST", "CI_HAS_RELUKKO", "CI_RELUKKO_*" ]
|
|
52
55
|
|
|
53
56
|
[tool.pylint.main]
|
|
54
57
|
# Files or directories to be skipped. They should be base names, not paths.
|
|
@@ -33,9 +33,18 @@ RETRY_KWARGS = [
|
|
|
33
33
|
'delay',
|
|
34
34
|
'backoff',
|
|
35
35
|
'max_delay',
|
|
36
|
-
'exceptions'
|
|
36
|
+
'exceptions',
|
|
37
37
|
]
|
|
38
38
|
|
|
39
|
+
OWN_KWARGS = [
|
|
40
|
+
'acquire_wait_for_timeout',
|
|
41
|
+
'acquire_modulo',
|
|
42
|
+
'ws_ping_interval',
|
|
43
|
+
'ws_ping_timeout',
|
|
44
|
+
'ws_wait_for_timeout',
|
|
45
|
+
]
|
|
46
|
+
OWN_KWARGS.extend(RETRY_KWARGS)
|
|
47
|
+
|
|
39
48
|
logger = logging.getLogger(__name__)
|
|
40
49
|
|
|
41
50
|
|
|
@@ -66,7 +75,12 @@ class RelukkoClient:
|
|
|
66
75
|
)
|
|
67
76
|
self._setup_session(api_key, **kwargs)
|
|
68
77
|
self._setup_http_adapters_retry(**kwargs)
|
|
69
|
-
self.
|
|
78
|
+
self.ws_wait_for_timeout = 2
|
|
79
|
+
self.ws_ping_interval = 60
|
|
80
|
+
self.ws_ping_timeout = 20
|
|
81
|
+
self.acquire_wait_for_timeout = 2
|
|
82
|
+
self.acquire_modulo = 100
|
|
83
|
+
self._setup_pyrelukko_kwargs(**kwargs)
|
|
70
84
|
|
|
71
85
|
self.base_url = self._setup_base_url(base_url)
|
|
72
86
|
self.ws_url = self._setup_ws_url(str(self.base_url))
|
|
@@ -90,10 +104,10 @@ class RelukkoClient:
|
|
|
90
104
|
self.base_url = self._setup_base_url(base_url or self.base_url)
|
|
91
105
|
self.ws_url = self._setup_ws_url(str(self.base_url))
|
|
92
106
|
self._setup_ssl_ctx(**kwargs)
|
|
93
|
-
self.
|
|
107
|
+
self._setup_pyrelukko_kwargs(**kwargs)
|
|
94
108
|
|
|
95
|
-
def
|
|
96
|
-
for kwarg in
|
|
109
|
+
def _setup_pyrelukko_kwargs(self, **kwargs):
|
|
110
|
+
for kwarg in OWN_KWARGS:
|
|
97
111
|
setattr(
|
|
98
112
|
self,
|
|
99
113
|
kwarg,
|
|
@@ -174,14 +188,17 @@ class RelukkoClient:
|
|
|
174
188
|
additional_headers=additional_headers,
|
|
175
189
|
ssl=self.ssl_ctx,
|
|
176
190
|
logger=logger,
|
|
191
|
+
ping_interval=self.ws_ping_interval,
|
|
192
|
+
ping_timeout=self.ws_ping_timeout,
|
|
177
193
|
) as websocket:
|
|
178
194
|
while self.ws_running.is_set():
|
|
179
195
|
try:
|
|
180
|
-
ws_message = await asyncio.wait_for(
|
|
196
|
+
ws_message = await asyncio.wait_for(
|
|
197
|
+
websocket.recv(), timeout=self.ws_wait_for_timeout)
|
|
181
198
|
if ws_message:
|
|
182
199
|
logger.debug("Received message: '%s'", ws_message)
|
|
183
200
|
msg: Dict = json.loads(ws_message)
|
|
184
|
-
if msg.get('
|
|
201
|
+
if msg.get('deleted'):
|
|
185
202
|
# Signal the HTTP thread to wake up
|
|
186
203
|
self.message_received.set()
|
|
187
204
|
except TimeoutError:
|
|
@@ -199,19 +216,25 @@ class RelukkoClient:
|
|
|
199
216
|
"""
|
|
200
217
|
|
|
201
218
|
start_time = time.time()
|
|
202
|
-
|
|
219
|
+
loop_counter = 0
|
|
220
|
+
got_message = False
|
|
221
|
+
res = None
|
|
203
222
|
while True:
|
|
204
223
|
elapsed_time = time.time() - start_time
|
|
205
224
|
if elapsed_time > max_run_time:
|
|
206
225
|
self.ws_running.clear()
|
|
207
226
|
_thread_store.insert(0, None)
|
|
208
227
|
return
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
228
|
+
# If self.message_recieved is True try to get lock ASAP!
|
|
229
|
+
# Otherwise only in every Xth run in case websocket broke.
|
|
230
|
+
if got_message or loop_counter % self.acquire_modulo == 0:
|
|
231
|
+
res = self._make_request(
|
|
232
|
+
url=url, method="POST", payload=payload)
|
|
233
|
+
loop_counter += 1
|
|
212
234
|
if res is None:
|
|
213
235
|
# Conflict 409
|
|
214
|
-
self.message_received.wait(
|
|
236
|
+
got_message = self.message_received.wait(
|
|
237
|
+
timeout=self.acquire_wait_for_timeout)
|
|
215
238
|
self.message_received.clear()
|
|
216
239
|
else:
|
|
217
240
|
_thread_store.insert(0, res)
|
|
@@ -277,7 +300,8 @@ class RelukkoClient:
|
|
|
277
300
|
|
|
278
301
|
thread_store = []
|
|
279
302
|
http_thread = threading.Thread(
|
|
280
|
-
target=self._acquire_relukko,
|
|
303
|
+
target=self._acquire_relukko,
|
|
304
|
+
args=(url, max_run_time, payload, thread_store))
|
|
281
305
|
http_thread.start()
|
|
282
306
|
http_thread.join()
|
|
283
307
|
self.ws_listener.join()
|
|
@@ -6,7 +6,7 @@ Testcontainers to be used in PyTests, for a fixture see tests/conftest.py
|
|
|
6
6
|
@pytest.fixture(scope="session")
|
|
7
7
|
def relukko_backend():
|
|
8
8
|
with Network() as rl_net:
|
|
9
|
-
with RelukkoDbContainer(net=rl_net,
|
|
9
|
+
with RelukkoDbContainer(net=rl_net,
|
|
10
10
|
image="postgres:16", hostname="relukkodb") as _db:
|
|
11
11
|
db_url = "postgresql://relukko:relukko@relukkodb/relukko"
|
|
12
12
|
with RelukkoContainer(rl_net, db_url=db_url) as backend:
|
|
@@ -15,7 +15,6 @@ def relukko_backend():
|
|
|
15
15
|
yield relukko, backend
|
|
16
16
|
"""
|
|
17
17
|
import socket
|
|
18
|
-
from pathlib import Path
|
|
19
18
|
|
|
20
19
|
from testcontainers.core.network import Network
|
|
21
20
|
from testcontainers.core.waiting_utils import wait_container_is_ready
|
|
@@ -25,7 +24,7 @@ from testcontainers.postgres import PostgresContainer
|
|
|
25
24
|
|
|
26
25
|
class RelukkoContainer(ServerContainer):
|
|
27
26
|
def __init__(self, net: Network,
|
|
28
|
-
image="registry.gitlab.com/relukko/relukko:
|
|
27
|
+
image="registry.gitlab.com/relukko/relukko:latest", db_url=None):
|
|
29
28
|
self.db_url = db_url
|
|
30
29
|
self.net = net
|
|
31
30
|
super(RelukkoContainer, self).__init__(image=image, port=3000)
|
|
@@ -48,7 +47,6 @@ class RelukkoContainer(ServerContainer):
|
|
|
48
47
|
class RelukkoDbContainer(PostgresContainer):
|
|
49
48
|
def __init__(
|
|
50
49
|
self, net: Network,
|
|
51
|
-
initdb_dir: Path,
|
|
52
50
|
image: str = "postgres:latest",
|
|
53
51
|
port: int = 5432,
|
|
54
52
|
username: str | None = None,
|
|
@@ -57,11 +55,9 @@ class RelukkoDbContainer(PostgresContainer):
|
|
|
57
55
|
driver: str | None = "psycopg2",
|
|
58
56
|
**kwargs) -> None:
|
|
59
57
|
self.net = net
|
|
60
|
-
self.initdb_dir = initdb_dir
|
|
61
58
|
super().__init__(image, port, username, password, dbname, driver, **kwargs)
|
|
62
59
|
|
|
63
60
|
def _configure(self) -> None:
|
|
64
|
-
self.with_volume_mapping(self.initdb_dir, "/docker-entrypoint-initdb.d", "Z")
|
|
65
61
|
self.with_env("POSTGRES_USER", "relukko")
|
|
66
62
|
self.with_env("POSTGRES_PASSWORD", "relukko")
|
|
67
63
|
self.with_env("POSTGRES_DB", "relukko")
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
# pylint: disable=all
|
|
2
|
-
__version__ = "0.
|
|
2
|
+
__version__ = "0.5.0"
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import os
|
|
1
2
|
import socket
|
|
2
3
|
import ssl
|
|
3
4
|
import threading
|
|
@@ -11,19 +12,27 @@ from pyrelukko import RelukkoClient
|
|
|
11
12
|
from pyrelukko.testcontainers import RelukkoContainer, RelukkoDbContainer
|
|
12
13
|
|
|
13
14
|
SCRIPT_DIR = Path(__file__).parent.absolute()
|
|
14
|
-
INITDB_DIR = SCRIPT_DIR / "initdb.d"
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
@pytest.fixture(scope="session")
|
|
18
18
|
def relukko_backend():
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
19
|
+
if os.environ.get("CI_HAS_RELUKKO"):
|
|
20
|
+
# Gitlab does not allow DinD networks, so Relukko runs as a service
|
|
21
|
+
# in the background of the job.
|
|
22
|
+
relukko = RelukkoClient(
|
|
23
|
+
base_url=os.environ['CI_RELUKKO_BASE_URL'],
|
|
24
|
+
api_key=os.environ['CI_RELUKKO_API_KEY']
|
|
25
|
+
)
|
|
26
|
+
yield relukko, None
|
|
27
|
+
else:
|
|
28
|
+
with Network() as rl_net:
|
|
29
|
+
with RelukkoDbContainer(net=rl_net,
|
|
30
|
+
image="postgres:16", hostname="relukkodb") as _db:
|
|
31
|
+
db_url = "postgresql://relukko:relukko@relukkodb/relukko"
|
|
32
|
+
with RelukkoContainer(rl_net, db_url=db_url) as backend:
|
|
33
|
+
relukko = RelukkoClient(
|
|
34
|
+
base_url=backend.get_api_url(), api_key="somekey")
|
|
35
|
+
yield relukko, backend
|
|
27
36
|
|
|
28
37
|
@pytest.fixture(scope="function")
|
|
29
38
|
def tls_listener():
|
|
@@ -2,7 +2,7 @@ import logging
|
|
|
2
2
|
import time
|
|
3
3
|
import ssl
|
|
4
4
|
import socket
|
|
5
|
-
from datetime import datetime, timezone
|
|
5
|
+
from datetime import datetime, timedelta, timezone
|
|
6
6
|
from pathlib import Path
|
|
7
7
|
from typing import Dict
|
|
8
8
|
|
|
@@ -59,6 +59,11 @@ def test_init_relukko_client():
|
|
|
59
59
|
assert relukko.backoff == 2.0
|
|
60
60
|
assert relukko.max_delay is None
|
|
61
61
|
assert relukko.exceptions == (requests.ConnectionError, RelukkoDoRetry)
|
|
62
|
+
assert relukko.ws_wait_for_timeout == 2
|
|
63
|
+
assert relukko.ws_ping_interval == 60
|
|
64
|
+
assert relukko.ws_ping_timeout == 20
|
|
65
|
+
assert relukko.acquire_wait_for_timeout == 2
|
|
66
|
+
assert relukko.acquire_modulo == 100
|
|
62
67
|
|
|
63
68
|
with pytest.raises(ValueError):
|
|
64
69
|
RelukkoClient(base_url=1000, api_key="")
|
|
@@ -169,6 +174,11 @@ def test_reconfigure_relukko_client():
|
|
|
169
174
|
assert relukko.backoff == 2.0
|
|
170
175
|
assert relukko.max_delay is None
|
|
171
176
|
assert relukko.exceptions == (requests.ConnectionError, RelukkoDoRetry)
|
|
177
|
+
assert relukko.ws_wait_for_timeout == 2
|
|
178
|
+
assert relukko.ws_ping_interval == 60
|
|
179
|
+
assert relukko.ws_ping_timeout == 20
|
|
180
|
+
assert relukko.acquire_wait_for_timeout == 2
|
|
181
|
+
assert relukko.acquire_modulo == 100
|
|
172
182
|
|
|
173
183
|
|
|
174
184
|
def test_reconfigure_relukko_client_extended():
|
|
@@ -178,6 +188,11 @@ def test_reconfigure_relukko_client_extended():
|
|
|
178
188
|
verify_mode = ssl.VerifyMode.CERT_NONE
|
|
179
189
|
verify_flags = ssl.VerifyFlags.VERIFY_DEFAULT
|
|
180
190
|
options = ssl.Options.OP_ALL
|
|
191
|
+
ws_wait_for_timeout = 27
|
|
192
|
+
ws_ping_interval = 600
|
|
193
|
+
ws_ping_timeout = 23
|
|
194
|
+
acquire_wait_for_timeout = 22
|
|
195
|
+
acquire_modulo = 202
|
|
181
196
|
|
|
182
197
|
relukko.reconfigure_relukko(
|
|
183
198
|
base_url="https://relukko", api_key="my-API-key", trust_env=False,
|
|
@@ -185,7 +200,10 @@ def test_reconfigure_relukko_client_extended():
|
|
|
185
200
|
status=96, other=95, backoff_factor=94, backoff_max=1000,
|
|
186
201
|
backoff_jitter=93, raise_on_redirect=False, raise_on_status=False,
|
|
187
202
|
check_hostname=False, hostname_checks_common_name=False,
|
|
188
|
-
verify_mode=verify_mode, verify_flags=verify_flags, options=options
|
|
203
|
+
verify_mode=verify_mode, verify_flags=verify_flags, options=options,
|
|
204
|
+
ws_wait_for_timeout=ws_wait_for_timeout, acquire_modulo=acquire_modulo,
|
|
205
|
+
ws_ping_interval=ws_ping_interval, ws_ping_timeout=ws_ping_timeout,
|
|
206
|
+
acquire_wait_for_timeout=acquire_wait_for_timeout,
|
|
189
207
|
)
|
|
190
208
|
|
|
191
209
|
assert relukko.session.trust_env == False
|
|
@@ -218,16 +236,29 @@ def test_reconfigure_relukko_client_extended():
|
|
|
218
236
|
assert relukko.backoff == 2.0
|
|
219
237
|
assert relukko.max_delay is None
|
|
220
238
|
assert relukko.exceptions == (requests.ConnectionError, RelukkoDoRetry)
|
|
239
|
+
assert relukko.ws_wait_for_timeout == ws_wait_for_timeout
|
|
240
|
+
assert relukko.ws_ping_interval == ws_ping_interval
|
|
241
|
+
assert relukko.ws_ping_timeout == ws_ping_timeout
|
|
242
|
+
assert relukko.acquire_wait_for_timeout == acquire_wait_for_timeout
|
|
243
|
+
assert relukko.acquire_modulo == acquire_modulo
|
|
221
244
|
|
|
222
245
|
|
|
223
246
|
def test_init_relukko_client_extented():
|
|
224
247
|
cookies = cookiejar_from_dict({"cookie1": "value1"})
|
|
248
|
+
ws_wait_for_timeout = 27
|
|
249
|
+
ws_ping_interval = 600
|
|
250
|
+
ws_ping_timeout = 23
|
|
251
|
+
acquire_wait_for_timeout = 22
|
|
252
|
+
acquire_modulo = 202
|
|
225
253
|
|
|
226
254
|
relukko = RelukkoClient(
|
|
227
255
|
base_url="http://relukko", api_key="my-API-key", trust_env=False,
|
|
228
256
|
cookies=cookies, total=100, connect=99, read=98, redirect=97,
|
|
229
257
|
status=96, other=95, backoff_factor=94, backoff_max=1000,
|
|
230
258
|
backoff_jitter=93, raise_on_redirect=False, raise_on_status=False,
|
|
259
|
+
ws_wait_for_timeout=ws_wait_for_timeout, acquire_modulo=acquire_modulo,
|
|
260
|
+
ws_ping_interval=ws_ping_interval, ws_ping_timeout=ws_ping_timeout,
|
|
261
|
+
acquire_wait_for_timeout=acquire_wait_for_timeout,
|
|
231
262
|
)
|
|
232
263
|
|
|
233
264
|
assert relukko.session.trust_env == False
|
|
@@ -253,6 +284,11 @@ def test_init_relukko_client_extented():
|
|
|
253
284
|
assert relukko.backoff == 2.0
|
|
254
285
|
assert relukko.max_delay is None
|
|
255
286
|
assert relukko.exceptions == (requests.ConnectionError, RelukkoDoRetry)
|
|
287
|
+
assert relukko.ws_wait_for_timeout == ws_wait_for_timeout
|
|
288
|
+
assert relukko.ws_ping_interval == ws_ping_interval
|
|
289
|
+
assert relukko.ws_ping_timeout == ws_ping_timeout
|
|
290
|
+
assert relukko.acquire_wait_for_timeout == acquire_wait_for_timeout
|
|
291
|
+
assert relukko.acquire_modulo == acquire_modulo
|
|
256
292
|
|
|
257
293
|
|
|
258
294
|
def test_init_relukko_client_ssl_ctx():
|
|
@@ -351,7 +387,25 @@ def test_acquire_relukko(relukko_backend):
|
|
|
351
387
|
lock = relukko.acquire_relukko("pylock", "pytest", 30)
|
|
352
388
|
end_time = time.time()
|
|
353
389
|
assert lock is None
|
|
354
|
-
assert 29 < end_time - start_time <
|
|
390
|
+
assert 29 < end_time - start_time < 37
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
def test_acquire_relukko_with_del(relukko_backend):
|
|
394
|
+
relukko, _ = relukko_backend
|
|
395
|
+
lock = relukko.acquire_relukko("Pylock", "pytest", 10)
|
|
396
|
+
id = lock['id']
|
|
397
|
+
|
|
398
|
+
expires_at = datetime.now(timezone.utc) - timedelta(minutes=2, seconds=45)
|
|
399
|
+
upd_lock = relukko.update_relukko(id, expires_at=expires_at)
|
|
400
|
+
assert id == upd_lock['id']
|
|
401
|
+
|
|
402
|
+
start_time = time.time()
|
|
403
|
+
lock = relukko.acquire_relukko("Pylock", "pytest", 60)
|
|
404
|
+
end_time = time.time()
|
|
405
|
+
|
|
406
|
+
assert lock is not None
|
|
407
|
+
assert upd_lock['id'] != lock['id']
|
|
408
|
+
assert 14 < end_time - start_time < 50
|
|
355
409
|
|
|
356
410
|
|
|
357
411
|
def test_delete_relukko(relukko_backend):
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
|
|
3
|
-
SCRIPT_DIR=$(dirname "$(readlink -f "$0")")
|
|
4
|
-
REPO_DIR="${SCRIPT_DIR}/.."
|
|
5
|
-
|
|
6
|
-
# Main script execution
|
|
7
|
-
main() {
|
|
8
|
-
pytest --junit-xml "${REPO_DIR}/pytest-junit.xml"
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
# Execute the main function
|
|
12
|
-
main
|
|
13
|
-
|
|
14
|
-
# vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
-- Add up migration script here
|
|
2
|
-
CREATE EXTENSION moddatetime;
|
|
3
|
-
|
|
4
|
-
CREATE TABLE locks (
|
|
5
|
-
id uuid DEFAULT gen_random_uuid(),
|
|
6
|
-
lock_name VARCHAR NOT NULL,
|
|
7
|
-
creator VARCHAR,
|
|
8
|
-
ip INET,
|
|
9
|
-
expires_at TIMESTAMPTZ NOT NULL DEFAULT NOW() + (10 ||' minutes')::interval ,
|
|
10
|
-
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
11
|
-
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
12
|
-
PRIMARY KEY (id),
|
|
13
|
-
UNIQUE(lock_name)
|
|
14
|
-
);
|
|
15
|
-
|
|
16
|
-
CREATE TRIGGER locks_moddatetime
|
|
17
|
-
BEFORE UPDATE ON locks
|
|
18
|
-
FOR EACH ROW
|
|
19
|
-
EXECUTE PROCEDURE moddatetime (updated_at);
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|