pyrelukko 0.5.0__tar.gz → 0.6.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.5.0 → pyrelukko-0.6.0}/.gitlab-ci.yml +16 -51
- {pyrelukko-0.5.0 → pyrelukko-0.6.0}/PKG-INFO +1 -1
- pyrelukko-0.6.0/cicd/run_docs_pages.sh +11 -0
- pyrelukko-0.6.0/cicd/run_pylint.sh +11 -0
- pyrelukko-0.6.0/cicd/run_pytest.sh +11 -0
- pyrelukko-0.6.0/cicd/run_shellcheck.sh +11 -0
- pyrelukko-0.6.0/cicd/tox_docs_pages.sh +17 -0
- pyrelukko-0.5.0/cicd/run_shellcheck.sh → pyrelukko-0.6.0/cicd/tox_shellcheck.sh +1 -1
- {pyrelukko-0.5.0 → pyrelukko-0.6.0}/pyproject.toml +63 -12
- {pyrelukko-0.5.0 → pyrelukko-0.6.0}/src/pyrelukko/pyrelukko.py +48 -20
- {pyrelukko-0.5.0 → pyrelukko-0.6.0}/src/pyrelukko/version.py +1 -1
- {pyrelukko-0.5.0 → pyrelukko-0.6.0}/tests/test_relukko.py +195 -0
- pyrelukko-0.5.0/cicd/build-py-rf-image.sh +0 -48
- pyrelukko-0.5.0/cicd/run_docs_pages.sh +0 -17
- pyrelukko-0.5.0/cicd/run_pylint.sh +0 -24
- pyrelukko-0.5.0/cicd/run_pytest.sh +0 -15
- pyrelukko-0.5.0/container/Containerfile +0 -5
- pyrelukko-0.5.0/container/requirements.txt +0 -5
- {pyrelukko-0.5.0 → pyrelukko-0.6.0}/LICENSE +0 -0
- {pyrelukko-0.5.0 → pyrelukko-0.6.0}/README.md +0 -0
- {pyrelukko-0.5.0 → pyrelukko-0.6.0}/src/pyrelukko/__init__.py +0 -0
- {pyrelukko-0.5.0 → pyrelukko-0.6.0}/src/pyrelukko/retry.py +0 -0
- {pyrelukko-0.5.0 → pyrelukko-0.6.0}/src/pyrelukko/testcontainers.py +0 -0
- {pyrelukko-0.5.0 → pyrelukko-0.6.0}/tests/cert/5d868fca.0 +0 -0
- {pyrelukko-0.5.0 → pyrelukko-0.6.0}/tests/cert/README.md +0 -0
- {pyrelukko-0.5.0 → pyrelukko-0.6.0}/tests/cert/relukko.crt +0 -0
- {pyrelukko-0.5.0 → pyrelukko-0.6.0}/tests/cert/relukko.csr +0 -0
- {pyrelukko-0.5.0 → pyrelukko-0.6.0}/tests/cert/relukko.key +0 -0
- {pyrelukko-0.5.0 → pyrelukko-0.6.0}/tests/cert/rootCA.crt +0 -0
- {pyrelukko-0.5.0 → pyrelukko-0.6.0}/tests/cert/rootCA.der +0 -0
- {pyrelukko-0.5.0 → pyrelukko-0.6.0}/tests/cert/rootCA.key +0 -0
- {pyrelukko-0.5.0 → pyrelukko-0.6.0}/tests/cert/rootCA.srl +0 -0
- {pyrelukko-0.5.0 → pyrelukko-0.6.0}/tests/conftest.py +0 -0
|
@@ -1,18 +1,11 @@
|
|
|
1
1
|
variables:
|
|
2
2
|
FF_TIMESTAMPS: true
|
|
3
|
-
|
|
4
|
-
description: Used in rules, if "true" and web triggered
|
|
3
|
+
RUN_PYLINT:
|
|
4
|
+
description: Used in rules, if "true" and web triggered run pylint.
|
|
5
5
|
value: "false"
|
|
6
6
|
options:
|
|
7
7
|
- "false"
|
|
8
8
|
- "true"
|
|
9
|
-
IMAGE_NAME: py-rf-image
|
|
10
|
-
IMAGE_TAG:
|
|
11
|
-
description: >-
|
|
12
|
-
The "tag" added to the image name for the test / lint image.
|
|
13
|
-
Remove this when you trigger by hand an image build and want it to use
|
|
14
|
-
the new built image with Git short sha tag (X icon on the right)!
|
|
15
|
-
value: "latest"
|
|
16
9
|
RUN_PYTEST:
|
|
17
10
|
description: Used in rules, if "true" and web triggered run the pytests.
|
|
18
11
|
value: "false"
|
|
@@ -36,44 +29,9 @@ variables:
|
|
|
36
29
|
# - "true"
|
|
37
30
|
|
|
38
31
|
|
|
39
|
-
build-py-rf-image:
|
|
40
|
-
stage: build
|
|
41
|
-
image: docker:25
|
|
42
|
-
services:
|
|
43
|
-
- name: docker:25-dind
|
|
44
|
-
alias: docker
|
|
45
|
-
before_script:
|
|
46
|
-
- docker info
|
|
47
|
-
before_script:
|
|
48
|
-
- echo "Login to Gitlab container registry"
|
|
49
|
-
- echo "$CI_REGISTRY_PASSWORD" | docker login --username $CI_REGISTRY_USER --password-stdin $CI_REGISTRY
|
|
50
|
-
script:
|
|
51
|
-
- echo "Build container image..."
|
|
52
|
-
- ./cicd/build-py-rf-image.sh
|
|
53
|
-
- echo "Export IMAGE_TAG var to next stage!"
|
|
54
|
-
- echo "IMAGE_TAG=${CI_COMMIT_SHORT_SHA}" > image_tag.env
|
|
55
|
-
- echo "Build complete."
|
|
56
|
-
artifacts:
|
|
57
|
-
reports:
|
|
58
|
-
dotenv: image_tag.env
|
|
59
|
-
rules:
|
|
60
|
-
- if: $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
|
|
61
|
-
changes:
|
|
62
|
-
- .gitlab-ci.yml
|
|
63
|
-
- cicd/build-py-rf-image.sh
|
|
64
|
-
- container/**/*
|
|
65
|
-
- if: $CI_PIPELINE_SOURCE == "merge_request_event" && $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH
|
|
66
|
-
changes:
|
|
67
|
-
- .gitlab-ci.yml
|
|
68
|
-
- cicd/build-py-rf-image.sh
|
|
69
|
-
- container/**/*
|
|
70
|
-
- if: $CI_PIPELINE_SOURCE == "web" && $BUILD_IMAGE == "true"
|
|
71
|
-
when: always
|
|
72
|
-
|
|
73
|
-
|
|
74
32
|
run-pylint:
|
|
75
33
|
stage: test
|
|
76
|
-
image: "
|
|
34
|
+
image: "registry.gitlab.com/relukko/py-tox-images/py-3.13-tox"
|
|
77
35
|
rules:
|
|
78
36
|
- if: $CI_PIPELINE_SOURCE == "merge_request_event" && $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH
|
|
79
37
|
changes:
|
|
@@ -81,6 +39,8 @@ run-pylint:
|
|
|
81
39
|
- if: $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
|
|
82
40
|
changes:
|
|
83
41
|
- src/**/*.py
|
|
42
|
+
- if: $CI_PIPELINE_SOURCE == "web" && $RUN_PYLINT == "true"
|
|
43
|
+
when: always
|
|
84
44
|
before_script:
|
|
85
45
|
- echo "Running PyLint."
|
|
86
46
|
script:
|
|
@@ -135,14 +95,18 @@ run-pytest:
|
|
|
135
95
|
when: always
|
|
136
96
|
expire_in: 2 week
|
|
137
97
|
paths:
|
|
138
|
-
- pytest-junit
|
|
98
|
+
- pytest-junit*.xml
|
|
99
|
+
- log*.html
|
|
100
|
+
- output*.xml
|
|
101
|
+
- xunit*.xml
|
|
139
102
|
reports:
|
|
140
|
-
junit:
|
|
103
|
+
junit:
|
|
104
|
+
- pytest-junit*.xml
|
|
105
|
+
- xunit*.xml
|
|
141
106
|
|
|
142
|
-
|
|
143
107
|
run-shellcheck:
|
|
144
108
|
stage: test
|
|
145
|
-
image: "
|
|
109
|
+
image: "registry.gitlab.com/relukko/py-tox-images/py-3.13-tox"
|
|
146
110
|
rules:
|
|
147
111
|
- if: $CI_PIPELINE_SOURCE == "merge_request_event" && $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH
|
|
148
112
|
changes:
|
|
@@ -154,10 +118,11 @@ run-shellcheck:
|
|
|
154
118
|
- echo "Running ShellCheck."
|
|
155
119
|
script:
|
|
156
120
|
- ./cicd/run_shellcheck.sh
|
|
157
|
-
|
|
121
|
+
|
|
122
|
+
|
|
158
123
|
# pages:
|
|
159
124
|
# stage: deploy
|
|
160
|
-
# image: "
|
|
125
|
+
# image: "registry.gitlab.com/relukko/py-tox-images/py-3.13-tox"
|
|
161
126
|
# rules:
|
|
162
127
|
# - if: $CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
|
|
163
128
|
# changes:
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# SCRIPT_DIR=$(dirname "$(readlink -f "$0")")
|
|
4
|
+
# REPO_DIR="$(readlink -f "${SCRIPT_DIR}/..")"
|
|
5
|
+
# PUBLIC_DIR="${REPO_DIR}/public"
|
|
6
|
+
|
|
7
|
+
# Main script execution
|
|
8
|
+
main() {
|
|
9
|
+
# mkdir -p "${PUBLIC_DIR}"
|
|
10
|
+
# libdoc --pythonpath ./src Relukko "${PUBLIC_DIR}/index.html"
|
|
11
|
+
echo "Not Implemented yet"
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
# Execute the main function
|
|
15
|
+
main
|
|
16
|
+
|
|
17
|
+
# vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
|
|
@@ -23,6 +23,21 @@ dependencies = [
|
|
|
23
23
|
"websockets >= 14.1",
|
|
24
24
|
]
|
|
25
25
|
|
|
26
|
+
[dependency-groups]
|
|
27
|
+
test = [
|
|
28
|
+
"httpx",
|
|
29
|
+
"pytest >= 8",
|
|
30
|
+
"requests-mock >= 1.12",
|
|
31
|
+
"testcontainers",
|
|
32
|
+
]
|
|
33
|
+
lint = [
|
|
34
|
+
"pylint >= 3",
|
|
35
|
+
"pylint-json2html"
|
|
36
|
+
]
|
|
37
|
+
coverage = [
|
|
38
|
+
"pytest-cov"
|
|
39
|
+
]
|
|
40
|
+
|
|
26
41
|
[tool.flit.sdist]
|
|
27
42
|
exclude = [".gitignore", "demo.py"]
|
|
28
43
|
|
|
@@ -34,6 +49,16 @@ Issues = "https://gitlab.com/relukko/pyrelukko/-/issues"
|
|
|
34
49
|
requires = ["flit_core >=3.2,<4", "semantic-version >= 2.10"]
|
|
35
50
|
build-backend = "flit_core.buildapi"
|
|
36
51
|
|
|
52
|
+
[tool.pylint.main]
|
|
53
|
+
# Files or directories to be skipped. They should be base names, not paths.
|
|
54
|
+
ignore = ["LICENSE", "pyproject.toml", "version.py",
|
|
55
|
+
"README.md", "demo.py", "conftest.py", ".tox"]
|
|
56
|
+
|
|
57
|
+
# Files or directories matching the regular expression patterns are skipped. The
|
|
58
|
+
# regex matches against base names, not paths. The default value ignores Emacs
|
|
59
|
+
# file locks
|
|
60
|
+
ignore-patterns = ["^\\.#", "^test_"]
|
|
61
|
+
|
|
37
62
|
[tool.pytest.ini_options]
|
|
38
63
|
testpaths = [
|
|
39
64
|
"tests",
|
|
@@ -41,24 +66,50 @@ testpaths = [
|
|
|
41
66
|
pythonpath = [
|
|
42
67
|
"src",
|
|
43
68
|
]
|
|
69
|
+
log_cli = "True"
|
|
44
70
|
|
|
45
71
|
[tool.tox]
|
|
46
72
|
requires = ["tox>=4.23"]
|
|
47
|
-
env_list = [
|
|
73
|
+
env_list = [
|
|
74
|
+
"3.11",
|
|
75
|
+
"3.12",
|
|
76
|
+
"3.13",
|
|
77
|
+
"pylint",
|
|
78
|
+
"shellcheck",
|
|
79
|
+
"docs"
|
|
80
|
+
]
|
|
48
81
|
|
|
49
82
|
[tool.tox.env_run_base]
|
|
50
83
|
description = "Run test under {base_python}"
|
|
51
|
-
commands = [["pytest", "--junit-xml", "pytest-junit.xml"]]
|
|
52
|
-
deps = ["httpx", "pytest", "testcontainers"]
|
|
53
|
-
# set_env = { VIRTUALENV_DISCOVERY = "pyenv" }
|
|
84
|
+
commands = [["pytest", "--junit-xml", "pytest-junit-{env_name}.xml", "--junit-prefix", "{env_name}"]]
|
|
54
85
|
pass_env = [ "TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE", "DOCKER_HOST", "CI_HAS_RELUKKO", "CI_RELUKKO_*" ]
|
|
86
|
+
dependency_groups = [ "test" ]
|
|
55
87
|
|
|
56
|
-
[tool.pylint
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
88
|
+
[tool.tox.env.pylint]
|
|
89
|
+
description = "Run PyLint with {base_python}"
|
|
90
|
+
dependency_groups = [ "lint" ]
|
|
91
|
+
commands = [[
|
|
92
|
+
"pylint",
|
|
93
|
+
"--verbose",
|
|
94
|
+
"--rcfile",
|
|
95
|
+
"./pyproject.toml",
|
|
96
|
+
"--output-format=json:{tox_root}/pylint.out.json,parseable:{tox_root}/pylint.out.txt,text",
|
|
97
|
+
".",
|
|
98
|
+
]
|
|
99
|
+
]
|
|
100
|
+
commands_post = [
|
|
101
|
+
[
|
|
102
|
+
"pylint-json2html",
|
|
103
|
+
"-o",
|
|
104
|
+
"{tox_root}/pylint.out.html",
|
|
105
|
+
"{tox_root}/pylint.out.json",
|
|
106
|
+
]
|
|
107
|
+
]
|
|
60
108
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
109
|
+
[tool.tox.env.shellcheck]
|
|
110
|
+
allowlist_externals = ["shellcheck", "{tox_root}/cicd/tox_shellcheck.sh"]
|
|
111
|
+
commands = [[ "{tox_root}/cicd/tox_shellcheck.sh" ]]
|
|
112
|
+
|
|
113
|
+
[tool.tox.env.docs]
|
|
114
|
+
allowlist_externals = ["{tox_root}/cicd/tox_docs_pages.sh"]
|
|
115
|
+
commands = [[ "{tox_root}/cicd/tox_docs_pages.sh" ]]
|
|
@@ -39,6 +39,8 @@ RETRY_KWARGS = [
|
|
|
39
39
|
OWN_KWARGS = [
|
|
40
40
|
'acquire_wait_for_timeout',
|
|
41
41
|
'acquire_modulo',
|
|
42
|
+
'disable_websocket',
|
|
43
|
+
'raise_when_acquire_fails',
|
|
42
44
|
'ws_ping_interval',
|
|
43
45
|
'ws_ping_timeout',
|
|
44
46
|
'ws_wait_for_timeout',
|
|
@@ -75,11 +77,13 @@ class RelukkoClient:
|
|
|
75
77
|
)
|
|
76
78
|
self._setup_session(api_key, **kwargs)
|
|
77
79
|
self._setup_http_adapters_retry(**kwargs)
|
|
78
|
-
self.
|
|
80
|
+
self.acquire_modulo = 100
|
|
81
|
+
self.acquire_wait_for_timeout = 2
|
|
82
|
+
self.disable_websocket = False
|
|
83
|
+
self.raise_when_acquire_fails = True
|
|
79
84
|
self.ws_ping_interval = 60
|
|
80
85
|
self.ws_ping_timeout = 20
|
|
81
|
-
self.
|
|
82
|
-
self.acquire_modulo = 100
|
|
86
|
+
self.ws_wait_for_timeout = 2
|
|
83
87
|
self._setup_pyrelukko_kwargs(**kwargs)
|
|
84
88
|
|
|
85
89
|
self.base_url = self._setup_base_url(base_url)
|
|
@@ -224,22 +228,29 @@ class RelukkoClient:
|
|
|
224
228
|
if elapsed_time > max_run_time:
|
|
225
229
|
self.ws_running.clear()
|
|
226
230
|
_thread_store.insert(0, None)
|
|
227
|
-
|
|
231
|
+
break
|
|
228
232
|
# If self.message_recieved is True try to get lock ASAP!
|
|
229
233
|
# Otherwise only in every Xth run in case websocket broke.
|
|
230
234
|
if got_message or loop_counter % self.acquire_modulo == 0:
|
|
231
|
-
|
|
232
|
-
|
|
235
|
+
try:
|
|
236
|
+
res = self._make_request(
|
|
237
|
+
url=url, method="POST", payload=payload)
|
|
238
|
+
except (
|
|
239
|
+
*self.exceptions, RuntimeError, requests.HTTPError) as e:
|
|
240
|
+
logger.warning("Last exception was: %s!\nGiving up!", e)
|
|
241
|
+
_thread_store.insert(0, e)
|
|
242
|
+
break
|
|
233
243
|
loop_counter += 1
|
|
234
244
|
if res is None:
|
|
235
245
|
# Conflict 409
|
|
236
246
|
got_message = self.message_received.wait(
|
|
237
247
|
timeout=self.acquire_wait_for_timeout)
|
|
238
248
|
self.message_received.clear()
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
249
|
+
continue
|
|
250
|
+
|
|
251
|
+
_thread_store.insert(0, res)
|
|
252
|
+
self.ws_running.clear()
|
|
253
|
+
break
|
|
243
254
|
|
|
244
255
|
def _check_response(self, response: requests.Response):
|
|
245
256
|
match response.status_code:
|
|
@@ -247,20 +258,27 @@ class RelukkoClient:
|
|
|
247
258
|
return response.json()
|
|
248
259
|
case 400 | 403:
|
|
249
260
|
err = response.json()
|
|
250
|
-
logger.warning(
|
|
261
|
+
logger.warning("4xx HTTP Error [%d](%s) - %s:%s",
|
|
262
|
+
response.status_code, response.reason,
|
|
263
|
+
str(err.get('status')), err.get('message'))
|
|
251
264
|
response.raise_for_status()
|
|
252
265
|
case 409:
|
|
253
266
|
err = response.json()
|
|
254
|
-
logger.
|
|
267
|
+
logger.warning("409 HTTP Error [%d](%s) - %s:%s",
|
|
268
|
+
response.status_code, response.reason,
|
|
269
|
+
str(err.get('status')), err.get('message'))
|
|
255
270
|
return None
|
|
256
271
|
case 500 | 502 | 503 | 504:
|
|
257
272
|
logger.warning("[%d](%s) %s",
|
|
258
273
|
response.status_code, response.reason, response.text)
|
|
259
|
-
raise RelukkoDoRetry(
|
|
274
|
+
raise RelukkoDoRetry(
|
|
275
|
+
f"5xx HTTP Error: [{response.status_code}]"
|
|
276
|
+
f"({response.reason})")
|
|
260
277
|
case _:
|
|
261
278
|
logger.warning("[%d](%s) %s",
|
|
262
279
|
response.status_code, response.reason, response.text)
|
|
263
|
-
raise RuntimeError(
|
|
280
|
+
raise RuntimeError(
|
|
281
|
+
f"Give up: [{response.status_code}]({response.reason})")
|
|
264
282
|
|
|
265
283
|
def _make_request(
|
|
266
284
|
self,
|
|
@@ -293,10 +311,11 @@ class RelukkoClient:
|
|
|
293
311
|
|
|
294
312
|
url = f"{self.base_url}/v1/locks/"
|
|
295
313
|
|
|
296
|
-
self.
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
314
|
+
if not self.disable_websocket:
|
|
315
|
+
self.ws_running.set()
|
|
316
|
+
self.ws_listener = threading.Thread(
|
|
317
|
+
target=asyncio.run, args=(self._websocket_listener(),))
|
|
318
|
+
self.ws_listener.start()
|
|
300
319
|
|
|
301
320
|
thread_store = []
|
|
302
321
|
http_thread = threading.Thread(
|
|
@@ -304,9 +323,18 @@ class RelukkoClient:
|
|
|
304
323
|
args=(url, max_run_time, payload, thread_store))
|
|
305
324
|
http_thread.start()
|
|
306
325
|
http_thread.join()
|
|
307
|
-
self.ws_listener.join()
|
|
308
326
|
|
|
309
|
-
|
|
327
|
+
if not self.disable_websocket:
|
|
328
|
+
self.ws_listener.join()
|
|
329
|
+
|
|
330
|
+
if thread_store:
|
|
331
|
+
if (
|
|
332
|
+
self.raise_when_acquire_fails
|
|
333
|
+
and isinstance(thread_store[0], Exception)
|
|
334
|
+
):
|
|
335
|
+
raise thread_store[0]
|
|
336
|
+
return thread_store[0]
|
|
337
|
+
return None
|
|
310
338
|
|
|
311
339
|
def get_lock(self, lock_id: str) -> Dict:
|
|
312
340
|
"""
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
# pylint: disable=all
|
|
2
|
-
__version__ = "0.
|
|
2
|
+
__version__ = "0.6.0"
|
|
@@ -8,6 +8,7 @@ from typing import Dict
|
|
|
8
8
|
|
|
9
9
|
import pytest
|
|
10
10
|
import requests
|
|
11
|
+
from requests_mock import ANY
|
|
11
12
|
from requests.adapters import HTTPAdapter
|
|
12
13
|
from requests.cookies import cookiejar_from_dict
|
|
13
14
|
from urllib3.util import parse_url
|
|
@@ -19,6 +20,8 @@ from pyrelukko.retry import retry
|
|
|
19
20
|
|
|
20
21
|
SCRIPT_DIR = Path(__file__).parent.absolute()
|
|
21
22
|
|
|
23
|
+
logging.basicConfig()
|
|
24
|
+
logging.getLogger().setLevel(logging.DEBUG)
|
|
22
25
|
logger = logging.getLogger(__name__)
|
|
23
26
|
|
|
24
27
|
|
|
@@ -64,6 +67,8 @@ def test_init_relukko_client():
|
|
|
64
67
|
assert relukko.ws_ping_timeout == 20
|
|
65
68
|
assert relukko.acquire_wait_for_timeout == 2
|
|
66
69
|
assert relukko.acquire_modulo == 100
|
|
70
|
+
assert relukko.disable_websocket == False
|
|
71
|
+
assert relukko.raise_when_acquire_fails == True
|
|
67
72
|
|
|
68
73
|
with pytest.raises(ValueError):
|
|
69
74
|
RelukkoClient(base_url=1000, api_key="")
|
|
@@ -179,6 +184,8 @@ def test_reconfigure_relukko_client():
|
|
|
179
184
|
assert relukko.ws_ping_timeout == 20
|
|
180
185
|
assert relukko.acquire_wait_for_timeout == 2
|
|
181
186
|
assert relukko.acquire_modulo == 100
|
|
187
|
+
assert relukko.disable_websocket == False
|
|
188
|
+
assert relukko.raise_when_acquire_fails == True
|
|
182
189
|
|
|
183
190
|
|
|
184
191
|
def test_reconfigure_relukko_client_extended():
|
|
@@ -204,6 +211,7 @@ def test_reconfigure_relukko_client_extended():
|
|
|
204
211
|
ws_wait_for_timeout=ws_wait_for_timeout, acquire_modulo=acquire_modulo,
|
|
205
212
|
ws_ping_interval=ws_ping_interval, ws_ping_timeout=ws_ping_timeout,
|
|
206
213
|
acquire_wait_for_timeout=acquire_wait_for_timeout,
|
|
214
|
+
disable_websocket=True, raise_when_acquire_fails=False,
|
|
207
215
|
)
|
|
208
216
|
|
|
209
217
|
assert relukko.session.trust_env == False
|
|
@@ -241,6 +249,8 @@ def test_reconfigure_relukko_client_extended():
|
|
|
241
249
|
assert relukko.ws_ping_timeout == ws_ping_timeout
|
|
242
250
|
assert relukko.acquire_wait_for_timeout == acquire_wait_for_timeout
|
|
243
251
|
assert relukko.acquire_modulo == acquire_modulo
|
|
252
|
+
assert relukko.disable_websocket == True
|
|
253
|
+
assert relukko.raise_when_acquire_fails == False
|
|
244
254
|
|
|
245
255
|
|
|
246
256
|
def test_init_relukko_client_extented():
|
|
@@ -259,6 +269,7 @@ def test_init_relukko_client_extented():
|
|
|
259
269
|
ws_wait_for_timeout=ws_wait_for_timeout, acquire_modulo=acquire_modulo,
|
|
260
270
|
ws_ping_interval=ws_ping_interval, ws_ping_timeout=ws_ping_timeout,
|
|
261
271
|
acquire_wait_for_timeout=acquire_wait_for_timeout,
|
|
272
|
+
disable_websocket=True, raise_when_acquire_fails=False,
|
|
262
273
|
)
|
|
263
274
|
|
|
264
275
|
assert relukko.session.trust_env == False
|
|
@@ -289,6 +300,8 @@ def test_init_relukko_client_extented():
|
|
|
289
300
|
assert relukko.ws_ping_timeout == ws_ping_timeout
|
|
290
301
|
assert relukko.acquire_wait_for_timeout == acquire_wait_for_timeout
|
|
291
302
|
assert relukko.acquire_modulo == acquire_modulo
|
|
303
|
+
assert relukko.disable_websocket == True
|
|
304
|
+
assert relukko.raise_when_acquire_fails == False
|
|
292
305
|
|
|
293
306
|
|
|
294
307
|
def test_init_relukko_client_ssl_ctx():
|
|
@@ -378,6 +391,188 @@ def test_reconfigre_relukko_client_retry():
|
|
|
378
391
|
assert relukko.exceptions == exceptions
|
|
379
392
|
|
|
380
393
|
|
|
394
|
+
def test_aqcuire_http_status_code_400_with_raise(requests_mock):
|
|
395
|
+
requests_mock.register_uri(
|
|
396
|
+
ANY,
|
|
397
|
+
ANY,
|
|
398
|
+
status_code=400,
|
|
399
|
+
reason="Bad Request",
|
|
400
|
+
json={"status": 400, "message": "Bad Request"},
|
|
401
|
+
)
|
|
402
|
+
|
|
403
|
+
relukko = RelukkoClient(
|
|
404
|
+
base_url="http://relukko", api_key="key",
|
|
405
|
+
delay=1, backoff=1.01, disable_websocket=True,
|
|
406
|
+
)
|
|
407
|
+
with pytest.raises(requests.HTTPError):
|
|
408
|
+
relukko.acquire_relukko("400Lock", "PyTest", 300)
|
|
409
|
+
|
|
410
|
+
|
|
411
|
+
def test_aqcuire_http_status_code_400_without_raise(requests_mock):
|
|
412
|
+
requests_mock.register_uri(
|
|
413
|
+
ANY,
|
|
414
|
+
ANY,
|
|
415
|
+
status_code=400,
|
|
416
|
+
reason="Bad Request",
|
|
417
|
+
json={"status": 400, "message": "Bad Request"},
|
|
418
|
+
)
|
|
419
|
+
|
|
420
|
+
relukko = RelukkoClient(
|
|
421
|
+
base_url="http://relukko", api_key="key",disable_websocket=True,
|
|
422
|
+
delay=1, backoff=1.01, raise_when_acquire_fails=False,
|
|
423
|
+
)
|
|
424
|
+
lock = relukko.acquire_relukko("500Lock", "PyTest", 300)
|
|
425
|
+
assert isinstance(lock, requests.exceptions.HTTPError)
|
|
426
|
+
|
|
427
|
+
|
|
428
|
+
def test_aqcuire_http_status_code_418_with_raise(requests_mock):
|
|
429
|
+
requests_mock.register_uri(
|
|
430
|
+
ANY,
|
|
431
|
+
ANY,
|
|
432
|
+
status_code=418,
|
|
433
|
+
reason="I'm a teapot",
|
|
434
|
+
text="The server refuses the attempt to brew coffee with a teapot.",
|
|
435
|
+
)
|
|
436
|
+
|
|
437
|
+
relukko = RelukkoClient(
|
|
438
|
+
base_url="http://relukko", api_key="key",
|
|
439
|
+
delay=1, backoff=1.01, disable_websocket=True,
|
|
440
|
+
)
|
|
441
|
+
with pytest.raises(RuntimeError):
|
|
442
|
+
relukko.acquire_relukko("418Lock", "PyTest", 300)
|
|
443
|
+
|
|
444
|
+
|
|
445
|
+
def test_aqcuire_http_status_code_418_without_raise(requests_mock):
|
|
446
|
+
requests_mock.register_uri(
|
|
447
|
+
ANY,
|
|
448
|
+
ANY,
|
|
449
|
+
status_code=418,
|
|
450
|
+
reason="I'm a teapot",
|
|
451
|
+
text="The server refuses the attempt to brew coffee with a teapot.",
|
|
452
|
+
)
|
|
453
|
+
|
|
454
|
+
relukko = RelukkoClient(
|
|
455
|
+
base_url="http://relukko", api_key="key",disable_websocket=True,
|
|
456
|
+
delay=1, backoff=1.01, raise_when_acquire_fails=False,
|
|
457
|
+
)
|
|
458
|
+
lock = relukko.acquire_relukko("418Lock", "PyTest", 300)
|
|
459
|
+
assert isinstance(lock, RuntimeError)
|
|
460
|
+
|
|
461
|
+
|
|
462
|
+
def test_aqcuire_http_status_code_500_with_raise(requests_mock):
|
|
463
|
+
requests_mock.register_uri(
|
|
464
|
+
ANY,
|
|
465
|
+
ANY,
|
|
466
|
+
status_code=500,
|
|
467
|
+
reason="Internal Server Error",
|
|
468
|
+
)
|
|
469
|
+
|
|
470
|
+
relukko = RelukkoClient(
|
|
471
|
+
base_url="http://relukko", api_key="key",
|
|
472
|
+
delay=1, backoff=1.01, disable_websocket=True,
|
|
473
|
+
)
|
|
474
|
+
with pytest.raises(RelukkoDoRetry):
|
|
475
|
+
relukko.acquire_relukko("500Lock", "PyTest", 300)
|
|
476
|
+
|
|
477
|
+
|
|
478
|
+
def test_aqcuire_http_status_code_500_without_raise(requests_mock):
|
|
479
|
+
requests_mock.register_uri(
|
|
480
|
+
ANY,
|
|
481
|
+
ANY,
|
|
482
|
+
status_code=500,
|
|
483
|
+
reason="Internal Server Error",
|
|
484
|
+
)
|
|
485
|
+
|
|
486
|
+
relukko = RelukkoClient(
|
|
487
|
+
base_url="http://relukko", api_key="key",disable_websocket=True,
|
|
488
|
+
delay=1, backoff=1.01, raise_when_acquire_fails=False,
|
|
489
|
+
)
|
|
490
|
+
lock = relukko.acquire_relukko("500Lock", "PyTest", 300)
|
|
491
|
+
assert isinstance(lock, RelukkoDoRetry)
|
|
492
|
+
|
|
493
|
+
|
|
494
|
+
def test_aqcuire_relukko_retry_with_max_delay(requests_mock, caplog):
|
|
495
|
+
requests_mock.register_uri(
|
|
496
|
+
ANY,
|
|
497
|
+
ANY,
|
|
498
|
+
status_code=500,
|
|
499
|
+
reason="Internal Server Error",
|
|
500
|
+
)
|
|
501
|
+
|
|
502
|
+
relukko = RelukkoClient(
|
|
503
|
+
base_url="http://relukko", api_key="key",disable_websocket=True,
|
|
504
|
+
delay=1, backoff=3, raise_when_acquire_fails=False,
|
|
505
|
+
max_delay=2,
|
|
506
|
+
)
|
|
507
|
+
|
|
508
|
+
lock = relukko.acquire_relukko("MaxDelayLock", "PyTest", 300)
|
|
509
|
+
|
|
510
|
+
one_sec_count = 0
|
|
511
|
+
two_sec_count = 0
|
|
512
|
+
for record in caplog.records:
|
|
513
|
+
if "Retrying in 2 seconds..." in record.message:
|
|
514
|
+
two_sec_count += 1
|
|
515
|
+
elif "Retrying in 1 seconds..." in record.message:
|
|
516
|
+
one_sec_count += 1
|
|
517
|
+
|
|
518
|
+
assert one_sec_count == 1
|
|
519
|
+
assert two_sec_count == 2
|
|
520
|
+
assert isinstance(lock, RelukkoDoRetry)
|
|
521
|
+
|
|
522
|
+
|
|
523
|
+
def test_get_relukko_retry_400(requests_mock):
|
|
524
|
+
requests_mock.register_uri(
|
|
525
|
+
ANY,
|
|
526
|
+
ANY,
|
|
527
|
+
status_code=400,
|
|
528
|
+
reason="Bad Request",
|
|
529
|
+
json={"status": 400, "message": "Bad Request"},
|
|
530
|
+
)
|
|
531
|
+
|
|
532
|
+
relukko = RelukkoClient(
|
|
533
|
+
base_url="http://relukko", api_key="key",disable_websocket=True,
|
|
534
|
+
delay=1, backoff=0.5, raise_when_acquire_fails=False,
|
|
535
|
+
)
|
|
536
|
+
|
|
537
|
+
with pytest.raises(requests.HTTPError):
|
|
538
|
+
relukko.get_lock("GetLock400")
|
|
539
|
+
|
|
540
|
+
|
|
541
|
+
def test_get_relukko_retry_418(requests_mock):
|
|
542
|
+
requests_mock.register_uri(
|
|
543
|
+
ANY,
|
|
544
|
+
ANY,
|
|
545
|
+
status_code=418,
|
|
546
|
+
reason="I'm a teapot",
|
|
547
|
+
text="The server refuses the attempt to brew coffee with a teapot.",
|
|
548
|
+
)
|
|
549
|
+
|
|
550
|
+
relukko = RelukkoClient(
|
|
551
|
+
base_url="http://relukko", api_key="key",disable_websocket=True,
|
|
552
|
+
delay=1, backoff=0.5, raise_when_acquire_fails=False,
|
|
553
|
+
)
|
|
554
|
+
|
|
555
|
+
with pytest.raises(RuntimeError):
|
|
556
|
+
relukko.get_lock("GetLock418")
|
|
557
|
+
|
|
558
|
+
|
|
559
|
+
def test_get_relukko_retry_500(requests_mock):
|
|
560
|
+
requests_mock.register_uri(
|
|
561
|
+
ANY,
|
|
562
|
+
ANY,
|
|
563
|
+
status_code=500,
|
|
564
|
+
reason="Internal Server Error",
|
|
565
|
+
)
|
|
566
|
+
|
|
567
|
+
relukko = RelukkoClient(
|
|
568
|
+
base_url="http://relukko", api_key="key",disable_websocket=True,
|
|
569
|
+
delay=1, backoff=0.5, raise_when_acquire_fails=False,
|
|
570
|
+
)
|
|
571
|
+
|
|
572
|
+
with pytest.raises(RelukkoDoRetry):
|
|
573
|
+
relukko.get_lock("GetLock500")
|
|
574
|
+
|
|
575
|
+
|
|
381
576
|
def test_acquire_relukko(relukko_backend):
|
|
382
577
|
relukko, _ = relukko_backend
|
|
383
578
|
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
#!/bin/sh
|
|
2
|
-
|
|
3
|
-
set -e
|
|
4
|
-
|
|
5
|
-
SCRIPT_DIR=$(dirname "$(readlink -f "$0")")
|
|
6
|
-
REPO_DIR="${SCRIPT_DIR}/.."
|
|
7
|
-
CONTAINER_DIR="${REPO_DIR}/container"
|
|
8
|
-
CONTAINER_CMD="docker"
|
|
9
|
-
|
|
10
|
-
# IMAGE_NAME should normally come from .gitlab-ci.yml file,
|
|
11
|
-
# set default for local usage.
|
|
12
|
-
if [ -z "${IMAGE_NAME+x}" ]; then
|
|
13
|
-
IMAGE_NAME=py-rf-image-local
|
|
14
|
-
fi
|
|
15
|
-
|
|
16
|
-
cd "${CONTAINER_DIR}" || exit
|
|
17
|
-
|
|
18
|
-
${CONTAINER_CMD} build -t "${IMAGE_NAME}:latest" --file Containerfile .
|
|
19
|
-
|
|
20
|
-
${CONTAINER_CMD} images
|
|
21
|
-
|
|
22
|
-
if [ -n "${CI_REGISTRY_IMAGE}" ]; then
|
|
23
|
-
# In Gitlab
|
|
24
|
-
|
|
25
|
-
# Tag with Git commit short sha and push
|
|
26
|
-
IMAGE_WITH_GIT_SHA="${CI_REGISTRY_IMAGE}/${IMAGE_NAME}:${CI_COMMIT_SHORT_SHA}"
|
|
27
|
-
echo "IMAGE_WITH_GIT_SHA: ${IMAGE_WITH_GIT_SHA}"
|
|
28
|
-
|
|
29
|
-
${CONTAINER_CMD} tag "${IMAGE_NAME}:latest" "${IMAGE_WITH_GIT_SHA}"
|
|
30
|
-
${CONTAINER_CMD} push "${IMAGE_WITH_GIT_SHA}"
|
|
31
|
-
|
|
32
|
-
if [ "${CI_COMMIT_BRANCH}" = "${CI_DEFAULT_BRANCH}" ]; then
|
|
33
|
-
# We run in default branch, also tag with latest
|
|
34
|
-
# Tag with "latest" (overwrites last 'latest' in registry) and push
|
|
35
|
-
IMAGE_WITH_LATEST="${CI_REGISTRY_IMAGE}/${IMAGE_NAME}:latest"
|
|
36
|
-
|
|
37
|
-
echo "Tag image with as 'latest': ${IMAGE_WITH_LATEST}"
|
|
38
|
-
|
|
39
|
-
${CONTAINER_CMD} tag "${IMAGE_NAME}:latest" "${IMAGE_WITH_LATEST}"
|
|
40
|
-
${CONTAINER_CMD} push "${IMAGE_WITH_LATEST}"
|
|
41
|
-
fi
|
|
42
|
-
else
|
|
43
|
-
echo "Runs locally, no pushing!"
|
|
44
|
-
fi
|
|
45
|
-
|
|
46
|
-
cd -
|
|
47
|
-
|
|
48
|
-
# vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
|
|
3
|
-
SCRIPT_DIR=$(dirname "$(readlink -f "$0")")
|
|
4
|
-
REPO_DIR="${SCRIPT_DIR}/.."
|
|
5
|
-
PUBLIC_DIR="${REPO_DIR}/public"
|
|
6
|
-
|
|
7
|
-
# Main script execution
|
|
8
|
-
main() {
|
|
9
|
-
mkdir -p "${PUBLIC_DIR}"
|
|
10
|
-
# libdoc --pythonpath ./src Relukko "${PUBLIC_DIR}/index.html"
|
|
11
|
-
echo "Not Implemented yet"
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
# Execute the main function
|
|
15
|
-
main
|
|
16
|
-
|
|
17
|
-
# vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
|
|
@@ -1,24 +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
|
-
pylint --verbose \
|
|
9
|
-
--rcfile "${REPO_DIR}/pyproject.toml" \
|
|
10
|
-
--output-format=json:pylint.out.json,parseable:pylint.out.txt,text \
|
|
11
|
-
"${REPO_DIR}"
|
|
12
|
-
pylint_exit_code=$?
|
|
13
|
-
|
|
14
|
-
pylint-json2html \
|
|
15
|
-
-o "${REPO_DIR}/pylint.out.html" \
|
|
16
|
-
"${REPO_DIR}/pylint.out.json"
|
|
17
|
-
|
|
18
|
-
return ${pylint_exit_code}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
# Execute the main function
|
|
22
|
-
main
|
|
23
|
-
|
|
24
|
-
# vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
|
|
@@ -1,15 +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
|
-
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:
|
|
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
|