pytest-bec-e2e 2.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 pytest-bec-e2e might be problematic. Click here for more details.
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
**/*_venv
|
|
2
|
+
**/.idea
|
|
3
|
+
*.log
|
|
4
|
+
**/__pycache__
|
|
5
|
+
**/.DS_Store
|
|
6
|
+
**/out
|
|
7
|
+
**/.vscode
|
|
8
|
+
**/.pytest_cache
|
|
9
|
+
**/*.egg*
|
|
10
|
+
|
|
11
|
+
# recovery_config files
|
|
12
|
+
recovery_config_*
|
|
13
|
+
|
|
14
|
+
# file writer data
|
|
15
|
+
**.h5
|
|
16
|
+
|
|
17
|
+
# Byte-compiled / optimized / DLL files
|
|
18
|
+
__pycache__/
|
|
19
|
+
*.py[cod]
|
|
20
|
+
*$py.class
|
|
21
|
+
|
|
22
|
+
# C extensions
|
|
23
|
+
*.so
|
|
24
|
+
|
|
25
|
+
# Distribution / packaging
|
|
26
|
+
.Python
|
|
27
|
+
build/
|
|
28
|
+
develop-eggs/
|
|
29
|
+
dist/
|
|
30
|
+
downloads/
|
|
31
|
+
eggs/
|
|
32
|
+
.eggs/
|
|
33
|
+
lib/
|
|
34
|
+
lib64/
|
|
35
|
+
parts/
|
|
36
|
+
sdist/
|
|
37
|
+
var/
|
|
38
|
+
wheels/
|
|
39
|
+
share/python-wheels/
|
|
40
|
+
*.egg-info/
|
|
41
|
+
.installed.cfg
|
|
42
|
+
*.egg
|
|
43
|
+
MANIFEST
|
|
44
|
+
|
|
45
|
+
# PyInstaller
|
|
46
|
+
# Usually these files are written by a python script from a template
|
|
47
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
48
|
+
*.manifest
|
|
49
|
+
*.spec
|
|
50
|
+
|
|
51
|
+
# Installer logs
|
|
52
|
+
pip-log.txt
|
|
53
|
+
pip-delete-this-directory.txt
|
|
54
|
+
|
|
55
|
+
# Unit test / coverage reports
|
|
56
|
+
htmlcov/
|
|
57
|
+
.tox/
|
|
58
|
+
.nox/
|
|
59
|
+
.coverage
|
|
60
|
+
.coverage.*
|
|
61
|
+
.cache
|
|
62
|
+
nosetests.xml
|
|
63
|
+
coverage.xml
|
|
64
|
+
*.cover
|
|
65
|
+
*.py,cover
|
|
66
|
+
.hypothesis/
|
|
67
|
+
.pytest_cache/
|
|
68
|
+
cover/
|
|
69
|
+
|
|
70
|
+
# Translations
|
|
71
|
+
*.mo
|
|
72
|
+
*.pot
|
|
73
|
+
|
|
74
|
+
# Django stuff:
|
|
75
|
+
*.log
|
|
76
|
+
local_settings.py
|
|
77
|
+
db.sqlite3
|
|
78
|
+
db.sqlite3-journal
|
|
79
|
+
|
|
80
|
+
# Flask stuff:
|
|
81
|
+
instance/
|
|
82
|
+
.webassets-cache
|
|
83
|
+
|
|
84
|
+
# Scrapy stuff:
|
|
85
|
+
.scrapy
|
|
86
|
+
|
|
87
|
+
# Sphinx documentation
|
|
88
|
+
docs/**/_build/
|
|
89
|
+
docs/**/autodoc/
|
|
90
|
+
docs/**/_autosummary/
|
|
91
|
+
|
|
92
|
+
# PyBuilder
|
|
93
|
+
.pybuilder/
|
|
94
|
+
target/
|
|
95
|
+
|
|
96
|
+
# Jupyter Notebook
|
|
97
|
+
.ipynb_checkpoints
|
|
98
|
+
|
|
99
|
+
# IPython
|
|
100
|
+
profile_default/
|
|
101
|
+
ipython_config.py
|
|
102
|
+
|
|
103
|
+
**.prof
|
|
104
|
+
|
|
105
|
+
# pyenv
|
|
106
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
107
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
108
|
+
# .python-version
|
|
109
|
+
|
|
110
|
+
# pipenv
|
|
111
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
112
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
113
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
114
|
+
# install all needed dependencies.
|
|
115
|
+
#Pipfile.lock
|
|
116
|
+
|
|
117
|
+
# poetry
|
|
118
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
119
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
120
|
+
# commonly ignored for libraries.
|
|
121
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
122
|
+
#poetry.lock
|
|
123
|
+
|
|
124
|
+
# pdm
|
|
125
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
126
|
+
#pdm.lock
|
|
127
|
+
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
|
128
|
+
# in version control.
|
|
129
|
+
# https://pdm.fming.dev/#use-with-ide
|
|
130
|
+
.pdm.toml
|
|
131
|
+
|
|
132
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
133
|
+
__pypackages__/
|
|
134
|
+
|
|
135
|
+
# Celery stuff
|
|
136
|
+
celerybeat-schedule
|
|
137
|
+
celerybeat.pid
|
|
138
|
+
|
|
139
|
+
# SageMath parsed files
|
|
140
|
+
*.sage.py
|
|
141
|
+
|
|
142
|
+
# Environments
|
|
143
|
+
.env
|
|
144
|
+
.venv
|
|
145
|
+
env/
|
|
146
|
+
venv/
|
|
147
|
+
ENV/
|
|
148
|
+
env.bak/
|
|
149
|
+
venv.bak/
|
|
150
|
+
|
|
151
|
+
# Spyder project settings
|
|
152
|
+
.spyderproject
|
|
153
|
+
.spyproject
|
|
154
|
+
|
|
155
|
+
# Rope project settings
|
|
156
|
+
.ropeproject
|
|
157
|
+
|
|
158
|
+
# mkdocs documentation
|
|
159
|
+
/site
|
|
160
|
+
|
|
161
|
+
# mypy
|
|
162
|
+
.mypy_cache/
|
|
163
|
+
.dmypy.json
|
|
164
|
+
dmypy.json
|
|
165
|
+
|
|
166
|
+
# Pyre type checker
|
|
167
|
+
.pyre/
|
|
168
|
+
|
|
169
|
+
# pytype static type analyzer
|
|
170
|
+
.pytype/
|
|
171
|
+
|
|
172
|
+
# Cython debug symbols
|
|
173
|
+
cython_debug/
|
|
174
|
+
|
|
175
|
+
# PyCharm
|
|
176
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
177
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
178
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
179
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
180
|
+
#.idea/
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: pytest-bec-e2e
|
|
3
|
+
Version: 2.5.0
|
|
4
|
+
Summary: BEC pytest plugin for end-to-end tests
|
|
5
|
+
Project-URL: Bug Tracker, https://gitlab.psi.ch/bec/bec/issues
|
|
6
|
+
Project-URL: Homepage, https://gitlab.psi.ch/bec/bec
|
|
7
|
+
Classifier: Development Status :: 3 - Alpha
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: Topic :: Scientific/Engineering
|
|
10
|
+
Requires-Python: >=3.10
|
|
11
|
+
Requires-Dist: bec-ipython-client
|
|
12
|
+
Requires-Dist: bec-lib
|
|
13
|
+
Requires-Dist: bec-server
|
|
14
|
+
Requires-Dist: pytest
|
|
15
|
+
Requires-Dist: pytest-redis
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "pytest-bec-e2e"
|
|
7
|
+
version = "2.5.0"
|
|
8
|
+
description = "BEC pytest plugin for end-to-end tests"
|
|
9
|
+
requires-python = ">=3.10"
|
|
10
|
+
classifiers = [
|
|
11
|
+
"Development Status :: 3 - Alpha",
|
|
12
|
+
"Programming Language :: Python :: 3",
|
|
13
|
+
"Topic :: Scientific/Engineering",
|
|
14
|
+
]
|
|
15
|
+
dependencies = [
|
|
16
|
+
"bec_lib",
|
|
17
|
+
"bec_ipython_client",
|
|
18
|
+
"bec_server",
|
|
19
|
+
"pytest",
|
|
20
|
+
"pytest_redis",
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
[project.entry-points.pytest11]
|
|
24
|
+
bec_end2end_fixtures = "pytest_bec_e2e.plugin"
|
|
25
|
+
|
|
26
|
+
[project.urls]
|
|
27
|
+
"Bug Tracker" = "https://gitlab.psi.ch/bec/bec/issues"
|
|
28
|
+
Homepage = "https://gitlab.psi.ch/bec/bec"
|
|
29
|
+
|
|
30
|
+
[tool.hatch.build.targets.wheel]
|
|
31
|
+
include = ["*"]
|
|
32
|
+
|
|
33
|
+
[tool.black]
|
|
34
|
+
line-length = 100
|
|
35
|
+
skip-magic-trailing-comma = true
|
|
File without changes
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
""" Fixtures for end-to-end tests """
|
|
2
|
+
|
|
3
|
+
# pylint: skip-file
|
|
4
|
+
import os
|
|
5
|
+
import pathlib
|
|
6
|
+
import platform
|
|
7
|
+
import shutil
|
|
8
|
+
import tempfile
|
|
9
|
+
|
|
10
|
+
import pytest
|
|
11
|
+
from pytest_redis import factories as pytest_redis_factories
|
|
12
|
+
|
|
13
|
+
from bec_ipython_client import BECIPythonClient
|
|
14
|
+
from bec_lib import BECClient, ConfigHelper, RedisConnector, ServiceConfig
|
|
15
|
+
from bec_lib.tests.utils import wait_for_empty_queue
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@pytest.hookimpl
|
|
19
|
+
def pytest_addoption(parser):
|
|
20
|
+
parser.addoption("--start-servers", action="store_true", default=False)
|
|
21
|
+
parser.addoption("--bec-redis-host", action="store", default="localhost")
|
|
22
|
+
parser.addoption("--bec-redis-cmd", action="store", default=None)
|
|
23
|
+
parser.addoption("--flush-redis", action="store_true", default=False)
|
|
24
|
+
parser.addoption("--files-path", action="store", default=None)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
redis_server_fixture = None
|
|
28
|
+
bec_redis = None
|
|
29
|
+
_start_servers = False
|
|
30
|
+
bec_servers_scope = (
|
|
31
|
+
lambda fixture_name, config: config.getoption("--flush-redis") and "function" or "session"
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
services_config_template = """
|
|
35
|
+
redis:
|
|
36
|
+
host: %(redis_host)s
|
|
37
|
+
port: %(redis_port)s
|
|
38
|
+
mongodb:
|
|
39
|
+
host: "localhost"
|
|
40
|
+
port: 27017
|
|
41
|
+
scibec:
|
|
42
|
+
host: http://localhost
|
|
43
|
+
port: 3030
|
|
44
|
+
beamline: TestBeamline
|
|
45
|
+
service_config:
|
|
46
|
+
abort_on_ctrl_c: False
|
|
47
|
+
enforce_ACLs: False
|
|
48
|
+
file_writer:
|
|
49
|
+
plugin: default_NeXus_format
|
|
50
|
+
base_path: %(file_writer_base_path)s
|
|
51
|
+
log_writer:
|
|
52
|
+
base_path: %(file_writer_base_path)s
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _check_path(file_path):
|
|
57
|
+
if os.path.exists(file_path):
|
|
58
|
+
return pathlib.Path(file_path)
|
|
59
|
+
else:
|
|
60
|
+
raise RuntimeError(
|
|
61
|
+
f"end2end tests: --files-path directory {repr(file_path)} does not exist"
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def _get_tmp_dir():
|
|
66
|
+
# on MacOS, gettempdir() returns path like /var/folders/nj/269977hs0_96bttwj2gs_jhhp48z54/T[...],
|
|
67
|
+
# and if building a Unix socket file (like pytest-redis does to connect to redis) it can
|
|
68
|
+
# exceed the 109 characters limit, so make a special case for MacOS
|
|
69
|
+
return pathlib.Path("/tmp" if platform.system() == "Darwin" else tempfile.gettempdir())
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
@pytest.hookimpl
|
|
73
|
+
def pytest_configure(config):
|
|
74
|
+
global redis_server_fixture
|
|
75
|
+
global bec_redis
|
|
76
|
+
global _start_servers
|
|
77
|
+
global _bec_servers_scope
|
|
78
|
+
|
|
79
|
+
if config.getoption("--start-servers"):
|
|
80
|
+
# configure 'datadir' == where redis Unix socket will go, and .rdb file (if any)
|
|
81
|
+
# try to use specified files path (hope it does not exceed 109 chars) or
|
|
82
|
+
# just use the normal tmp file directory except on MacOS where it must be enforced
|
|
83
|
+
# to /tmp
|
|
84
|
+
user_tmp_path = config.getoption("--files-path")
|
|
85
|
+
if user_tmp_path is not None:
|
|
86
|
+
datadir = _check_path(user_tmp_path)
|
|
87
|
+
else:
|
|
88
|
+
datadir = _get_tmp_dir()
|
|
89
|
+
# session-scoped fixture that starts redis using provided cmd
|
|
90
|
+
redis_server_fixture = pytest_redis_factories.proc.redis_proc(
|
|
91
|
+
executable=config.getoption("--bec-redis-cmd"), datadir=datadir
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
if config.getoption("--flush-redis"):
|
|
95
|
+
bec_redis = pytest_redis_factories.redisdb("redis_server_fixture")
|
|
96
|
+
_bec_servers_scope = "function" # have to restart servers at each test
|
|
97
|
+
else:
|
|
98
|
+
bec_redis = redis_server_fixture
|
|
99
|
+
else:
|
|
100
|
+
# do not automatically start redis - bec_redis will use existing
|
|
101
|
+
# process, will wait for 3 seconds max (must be running already);
|
|
102
|
+
# there is no point checking if we want to flush redis
|
|
103
|
+
# since it would remove available scans which are only populated
|
|
104
|
+
# when scan server starts
|
|
105
|
+
redis_server_fixture = pytest_redis_factories.redis_noproc(
|
|
106
|
+
host=config.getoption("--bec-redis-host"), startup_timeout=3
|
|
107
|
+
)
|
|
108
|
+
bec_redis = redis_server_fixture
|
|
109
|
+
|
|
110
|
+
_start_servers = config.getoption("--start-servers")
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
@pytest.fixture(scope=bec_servers_scope)
|
|
114
|
+
def bec_files_path(request):
|
|
115
|
+
user_tmp_path = request.config.getoption("--files-path")
|
|
116
|
+
if user_tmp_path is not None:
|
|
117
|
+
yield _check_path(user_tmp_path)
|
|
118
|
+
else:
|
|
119
|
+
if request.config.getoption("--flush-redis"):
|
|
120
|
+
request.fixturenames.append("tmp_path")
|
|
121
|
+
yield request.getfixturevalue("tmp_path")
|
|
122
|
+
else:
|
|
123
|
+
request.fixturenames.append("tmp_path_factory")
|
|
124
|
+
yield request.getfixturevalue("tmp_path_factory").mktemp("bec_files")
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
@pytest.fixture(scope=bec_servers_scope)
|
|
128
|
+
def bec_services_config_file_path(bec_files_path):
|
|
129
|
+
return pathlib.Path(bec_files_path / "services_config.yaml")
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
@pytest.fixture(scope=bec_servers_scope)
|
|
133
|
+
def bec_test_config_file_path(bec_files_path):
|
|
134
|
+
return pathlib.Path(bec_files_path / "test_config.yaml")
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
@pytest.fixture(scope=bec_servers_scope)
|
|
138
|
+
def bec_servers(
|
|
139
|
+
test_config_yaml_file_path,
|
|
140
|
+
bec_services_config_file_path,
|
|
141
|
+
bec_test_config_file_path,
|
|
142
|
+
bec_files_path,
|
|
143
|
+
redis_server_fixture,
|
|
144
|
+
):
|
|
145
|
+
# ensure configuration files are written where appropriate for tests,
|
|
146
|
+
# i.e. either in /tmp/pytest/... directory, or following user "--files-path"
|
|
147
|
+
# 1) test config (devices...)
|
|
148
|
+
shutil.copyfile(test_config_yaml_file_path, bec_test_config_file_path)
|
|
149
|
+
# 2) path where files are saved
|
|
150
|
+
file_writer_path = bec_services_config_file_path.parent # / "writer_output"
|
|
151
|
+
# file_writer_path.mkdir(exist_ok=True)
|
|
152
|
+
# 3) services config
|
|
153
|
+
with open(bec_services_config_file_path, "w") as services_config_file:
|
|
154
|
+
services_config_file.write(
|
|
155
|
+
services_config_template
|
|
156
|
+
% {
|
|
157
|
+
"redis_host": redis_server_fixture.host,
|
|
158
|
+
"redis_port": redis_server_fixture.port,
|
|
159
|
+
"file_writer_base_path": file_writer_path,
|
|
160
|
+
}
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
if _start_servers:
|
|
164
|
+
from bec_server.bec_server_utils.service_handler import ServiceHandler
|
|
165
|
+
|
|
166
|
+
# Start all BEC servers, kill them at the end
|
|
167
|
+
# when no_tmux=True, 'bec_path' indicate the cwd
|
|
168
|
+
# for the process (working directory), i.e. where log files will go
|
|
169
|
+
service_handler = ServiceHandler(
|
|
170
|
+
bec_path=bec_files_path, config_path=bec_services_config_file_path, no_tmux=True
|
|
171
|
+
)
|
|
172
|
+
processes = service_handler.start()
|
|
173
|
+
try:
|
|
174
|
+
yield
|
|
175
|
+
finally:
|
|
176
|
+
for process in processes:
|
|
177
|
+
process.terminate()
|
|
178
|
+
for process in processes:
|
|
179
|
+
os.waitpid(process.pid, 0)
|
|
180
|
+
else:
|
|
181
|
+
# Nothing to do here: servers are supposed to be started externally.
|
|
182
|
+
yield
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
@pytest.fixture
|
|
186
|
+
def bec_ipython_client_with_demo_config(bec_redis, bec_services_config_file_path, bec_servers):
|
|
187
|
+
config = ServiceConfig(bec_services_config_file_path)
|
|
188
|
+
bec = BECIPythonClient(config, RedisConnector, forced=True)
|
|
189
|
+
bec.start()
|
|
190
|
+
ConfigHelper(bec._client.connector).load_demo_config()
|
|
191
|
+
try:
|
|
192
|
+
yield bec
|
|
193
|
+
finally:
|
|
194
|
+
bec.shutdown()
|
|
195
|
+
bec._client._reset_singleton()
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
@pytest.fixture
|
|
199
|
+
def bec_client_lib_with_demo_config(bec_redis, bec_services_config_file_path, bec_servers):
|
|
200
|
+
config = ServiceConfig(bec_services_config_file_path)
|
|
201
|
+
bec = BECClient(config, RedisConnector, forced=True, wait_for_server=True)
|
|
202
|
+
bec.start()
|
|
203
|
+
ConfigHelper(bec._client.connector).load_demo_config()
|
|
204
|
+
try:
|
|
205
|
+
yield bec
|
|
206
|
+
finally:
|
|
207
|
+
bec.shutdown()
|
|
208
|
+
bec._client._reset_singleton()
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
@pytest.fixture
|
|
212
|
+
def bec_ipython_client_fixture(bec_ipython_client_with_demo_config):
|
|
213
|
+
bec = bec_ipython_client_with_demo_config
|
|
214
|
+
bec.queue.request_queue_reset()
|
|
215
|
+
bec.queue.request_scan_continuation()
|
|
216
|
+
wait_for_empty_queue(bec)
|
|
217
|
+
yield bec
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
@pytest.fixture
|
|
221
|
+
def bec_client_lib(bec_client_lib_with_demo_config):
|
|
222
|
+
bec = bec_client_lib_with_demo_config
|
|
223
|
+
bec.queue.request_queue_reset()
|
|
224
|
+
bec.queue.request_scan_continuation()
|
|
225
|
+
wait_for_empty_queue(bec)
|
|
226
|
+
yield bec
|