pdmv-http-client 2.1.0__tar.gz → 2.2.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.
- {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/.gitlab-ci.yml +2 -2
- {pdmv_http_client-2.1.0/src/pdmv_http_client.egg-info → pdmv_http_client-2.2.0}/PKG-INFO +1 -1
- {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/pyproject.toml +5 -0
- {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0/src/pdmv_http_client.egg-info}/PKG-INFO +1 -1
- {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/src/pdmv_http_client.egg-info/SOURCES.txt +8 -0
- {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/src/rest/__init__.py +2 -0
- {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/src/rest/_version.py +3 -3
- pdmv_http_client-2.2.0/src/rest/applications/relmon/core.py +95 -0
- pdmv_http_client-2.2.0/src/rest/applications/relval/core.py +129 -0
- pdmv_http_client-2.2.0/tests/__init__.py +0 -0
- {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/tests/applications/mcm/test_invalidate_request.py +1 -0
- {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/tests/applications/mcm/test_resubmission.py +1 -0
- pdmv_http_client-2.2.0/tests/applications/relmon/test_relmon.py +95 -0
- pdmv_http_client-2.2.0/tests/applications/relval/test_relval.py +116 -0
- pdmv_http_client-2.2.0/tests/fixtures/__init__.py +0 -0
- pdmv_http_client-2.2.0/tests/fixtures/relmon.py +73 -0
- pdmv_http_client-2.2.0/tests/fixtures/relval.py +101 -0
- {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/.gitignore +0 -0
- {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/LICENSE +0 -0
- {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/README.md +0 -0
- {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/examples/README.md +0 -0
- {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/examples/chain_req_forcedone.py +0 -0
- {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/examples/chain_request_resubmission.py +0 -0
- {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/examples/change_priority2.py +0 -0
- {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/examples/clone_example.py +0 -0
- {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/examples/get_requests.py +0 -0
- {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/examples/modify_request.py +0 -0
- {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/setup.cfg +0 -0
- {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/src/pdmv_http_client.egg-info/dependency_links.txt +0 -0
- {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/src/pdmv_http_client.egg-info/requires.txt +0 -0
- {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/src/pdmv_http_client.egg-info/top_level.txt +0 -0
- {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/src/rest/applications/__init__.py +0 -0
- {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/src/rest/applications/base.py +0 -0
- {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/src/rest/applications/mcm/__init__.py +0 -0
- {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/src/rest/applications/mcm/core.py +0 -0
- {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/src/rest/applications/mcm/invalidate_request.py +0 -0
- {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/src/rest/applications/mcm/resubmission.py +0 -0
- {pdmv_http_client-2.1.0/src/rest/client → pdmv_http_client-2.2.0/src/rest/applications/relmon}/__init__.py +0 -0
- {pdmv_http_client-2.1.0/src/rest/client/auth → pdmv_http_client-2.2.0/src/rest/applications/relval}/__init__.py +0 -0
- {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/src/rest/applications/rereco/core.py +0 -0
- {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/src/rest/applications/stats/core.py +0 -0
- {pdmv_http_client-2.1.0/src/rest/client/auth/handlers → pdmv_http_client-2.2.0/src/rest/client}/__init__.py +0 -0
- {pdmv_http_client-2.1.0/src/rest/utils → pdmv_http_client-2.2.0/src/rest/client/auth}/__init__.py +0 -0
- {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/src/rest/client/auth/auth_interface.py +0 -0
- {pdmv_http_client-2.1.0/tests → pdmv_http_client-2.2.0/src/rest/client/auth/handlers}/__init__.py +0 -0
- {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/src/rest/client/auth/handlers/oauth2_tokens.py +0 -0
- {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/src/rest/client/auth/handlers/session_cookies.py +0 -0
- {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/src/rest/client/session.py +0 -0
- {pdmv_http_client-2.1.0/tests/fixtures → pdmv_http_client-2.2.0/src/rest/utils}/__init__.py +0 -0
- {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/src/rest/utils/logger.py +0 -0
- {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/src/rest/utils/miscellaneous.py +0 -0
- {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/src/rest/utils/shell.py +0 -0
- {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/tests/applications/mcm/test_rest.py +0 -0
- {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/tests/applications/stats/test_stats.py +0 -0
- {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/tests/client/README.md +0 -0
- {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/tests/client/auth/handlers/test_oauth2_tokens_handlers.py +0 -0
- {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/tests/client/auth/handlers/test_session_cookie_handler.py +0 -0
- {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/tests/client/test_session.py +0 -0
- {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/tests/fixtures/files.py +0 -0
- {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/tests/fixtures/mcm.py +0 -0
- {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/tests/fixtures/oauth.py +0 -0
- {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/tests/utils/test_shell.py +0 -0
- {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/uv.lock +0 -0
|
@@ -43,14 +43,14 @@ lint:
|
|
|
43
43
|
smoke-test:
|
|
44
44
|
extends: .test-setup
|
|
45
45
|
script:
|
|
46
|
-
- uv run pytest -
|
|
46
|
+
- uv run pytest -m 'not (slow or admin)' -vv
|
|
47
47
|
needs:
|
|
48
48
|
- lint
|
|
49
49
|
|
|
50
50
|
integration-test:
|
|
51
51
|
extends: .test-setup
|
|
52
52
|
script:
|
|
53
|
-
- uv run pytest -vv
|
|
53
|
+
- uv run pytest -m 'not admin' -vv
|
|
54
54
|
needs:
|
|
55
55
|
- smoke-test
|
|
56
56
|
rules:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pdmv-http-client
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.2.0
|
|
4
4
|
Summary: A HTTP client wrapper to handle authenticated requests to CERN internal applications
|
|
5
5
|
Maintainer-email: PdmV Service <pdmv.service@cern.ch>, PPD Technical Support <cms-PPD-technical-support@cern.ch>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -51,6 +51,11 @@ log_cli_level = "INFO"
|
|
|
51
51
|
pythonpath = [
|
|
52
52
|
"tests"
|
|
53
53
|
]
|
|
54
|
+
addopts = "--strict-markers"
|
|
55
|
+
markers = [
|
|
56
|
+
"slow: tests which require too much time to run and could have collateral actions",
|
|
57
|
+
"admin: tests which require administrator permissions in the application to success"
|
|
58
|
+
]
|
|
54
59
|
|
|
55
60
|
[[tool.uv.index]]
|
|
56
61
|
name = "testpypi"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pdmv-http-client
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.2.0
|
|
4
4
|
Summary: A HTTP client wrapper to handle authenticated requests to CERN internal applications
|
|
5
5
|
Maintainer-email: PdmV Service <pdmv.service@cern.ch>, PPD Technical Support <cms-PPD-technical-support@cern.ch>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -24,6 +24,10 @@ src/rest/applications/mcm/__init__.py
|
|
|
24
24
|
src/rest/applications/mcm/core.py
|
|
25
25
|
src/rest/applications/mcm/invalidate_request.py
|
|
26
26
|
src/rest/applications/mcm/resubmission.py
|
|
27
|
+
src/rest/applications/relmon/__init__.py
|
|
28
|
+
src/rest/applications/relmon/core.py
|
|
29
|
+
src/rest/applications/relval/__init__.py
|
|
30
|
+
src/rest/applications/relval/core.py
|
|
27
31
|
src/rest/applications/rereco/core.py
|
|
28
32
|
src/rest/applications/stats/core.py
|
|
29
33
|
src/rest/client/__init__.py
|
|
@@ -41,6 +45,8 @@ tests/__init__.py
|
|
|
41
45
|
tests/applications/mcm/test_invalidate_request.py
|
|
42
46
|
tests/applications/mcm/test_rest.py
|
|
43
47
|
tests/applications/mcm/test_resubmission.py
|
|
48
|
+
tests/applications/relmon/test_relmon.py
|
|
49
|
+
tests/applications/relval/test_relval.py
|
|
44
50
|
tests/applications/stats/test_stats.py
|
|
45
51
|
tests/client/README.md
|
|
46
52
|
tests/client/test_session.py
|
|
@@ -50,4 +56,6 @@ tests/fixtures/__init__.py
|
|
|
50
56
|
tests/fixtures/files.py
|
|
51
57
|
tests/fixtures/mcm.py
|
|
52
58
|
tests/fixtures/oauth.py
|
|
59
|
+
tests/fixtures/relmon.py
|
|
60
|
+
tests/fixtures/relval.py
|
|
53
61
|
tests/utils/test_shell.py
|
|
@@ -6,5 +6,7 @@ Just to keep backward compatibility.
|
|
|
6
6
|
|
|
7
7
|
from rest.applications.base import BaseClient
|
|
8
8
|
from rest.applications.mcm.core import McM
|
|
9
|
+
from rest.applications.relmon.core import RelMonService
|
|
10
|
+
from rest.applications.relval.core import RelVal
|
|
9
11
|
from rest.applications.rereco.core import ReReco
|
|
10
12
|
from rest.applications.stats.core import Stats2
|
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '2.
|
|
32
|
-
__version_tuple__ = version_tuple = (2,
|
|
31
|
+
__version__ = version = '2.2.0'
|
|
32
|
+
__version_tuple__ = version_tuple = (2, 2, 0)
|
|
33
33
|
|
|
34
|
-
__commit_id__ = commit_id = '
|
|
34
|
+
__commit_id__ = commit_id = 'gd7c2f07c4'
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"""
|
|
2
|
+
REST client for the RelMonService application.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Any, Dict, Optional, Union
|
|
6
|
+
from urllib.parse import urlencode
|
|
7
|
+
|
|
8
|
+
from rest.applications.base import BaseClient
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class RelMonService(BaseClient):
|
|
12
|
+
"""
|
|
13
|
+
Initializes an HTTP client for querying RelMonService.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
def __init__(
|
|
17
|
+
self,
|
|
18
|
+
id: str = BaseClient.SSO,
|
|
19
|
+
debug: bool = False,
|
|
20
|
+
cookie: Union[str, None] = None,
|
|
21
|
+
dev: bool = True,
|
|
22
|
+
client_id: str = "",
|
|
23
|
+
client_secret: str = "",
|
|
24
|
+
):
|
|
25
|
+
super().__init__(
|
|
26
|
+
app="relmonservice",
|
|
27
|
+
id=id,
|
|
28
|
+
debug=debug,
|
|
29
|
+
cookie=cookie,
|
|
30
|
+
dev=dev,
|
|
31
|
+
client_id=client_id,
|
|
32
|
+
client_secret=client_secret,
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
# -----------------
|
|
36
|
+
# RelMonService APIs
|
|
37
|
+
# -----------------
|
|
38
|
+
|
|
39
|
+
def get_relmons(
|
|
40
|
+
self,
|
|
41
|
+
page: int = 0,
|
|
42
|
+
limit: Optional[int] = None,
|
|
43
|
+
query: Optional[str] = None,
|
|
44
|
+
) -> Dict[str, Any]:
|
|
45
|
+
"""
|
|
46
|
+
Fetch RelMons from database.
|
|
47
|
+
"""
|
|
48
|
+
params = {"page": page}
|
|
49
|
+
if limit is not None:
|
|
50
|
+
params["limit"] = limit
|
|
51
|
+
if query:
|
|
52
|
+
params["q"] = query
|
|
53
|
+
|
|
54
|
+
qs = f"?{urlencode(params)}" if params else ""
|
|
55
|
+
return self._get(url=f"api/get_relmons{qs}")
|
|
56
|
+
|
|
57
|
+
def create(self, relmon: Dict[str, Any]) -> Dict[str, Any]:
|
|
58
|
+
"""
|
|
59
|
+
Create a new RelMon.
|
|
60
|
+
"""
|
|
61
|
+
return self._post(url="api/create", data=relmon)
|
|
62
|
+
|
|
63
|
+
def reset(self, relmon_id: str) -> Dict[str, Any]:
|
|
64
|
+
"""
|
|
65
|
+
Reset a RelMon by ID.
|
|
66
|
+
"""
|
|
67
|
+
return self._post(url="api/reset", data={"id": relmon_id})
|
|
68
|
+
|
|
69
|
+
def delete(self, relmon_id: str) -> Dict[str, Any]:
|
|
70
|
+
"""
|
|
71
|
+
Delete a RelMon by ID.
|
|
72
|
+
"""
|
|
73
|
+
request_body = {"id": relmon_id}
|
|
74
|
+
request_endpoint = f"{self.server}api/delete"
|
|
75
|
+
response = self.session.delete(url=request_endpoint, json=request_body)
|
|
76
|
+
response.raise_for_status()
|
|
77
|
+
return response.json()
|
|
78
|
+
|
|
79
|
+
def edit(self, relmon: Dict[str, Any]) -> Dict[str, Any]:
|
|
80
|
+
"""
|
|
81
|
+
Edit an existing RelMon.
|
|
82
|
+
"""
|
|
83
|
+
return self._post(url="api/edit", data=relmon)
|
|
84
|
+
|
|
85
|
+
def tick(self) -> Dict[str, Any]:
|
|
86
|
+
"""
|
|
87
|
+
Trigger a controller tick.
|
|
88
|
+
"""
|
|
89
|
+
return self._get(url="api/tick")
|
|
90
|
+
|
|
91
|
+
def user(self) -> Dict[str, Any]:
|
|
92
|
+
"""
|
|
93
|
+
Get user info.
|
|
94
|
+
"""
|
|
95
|
+
return self._get(url="api/user")
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
"""
|
|
2
|
+
REST client for the RelVal application.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Union
|
|
6
|
+
|
|
7
|
+
from rest.applications.base import BaseClient
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class RelVal(BaseClient):
|
|
11
|
+
"""
|
|
12
|
+
Initializes an HTTP client for querying RelVal.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
def __init__(
|
|
16
|
+
self,
|
|
17
|
+
id: str = BaseClient.SSO,
|
|
18
|
+
debug: bool = False,
|
|
19
|
+
cookie: Union[str, None] = None,
|
|
20
|
+
dev: bool = True,
|
|
21
|
+
client_id: str = "",
|
|
22
|
+
client_secret: str = "",
|
|
23
|
+
):
|
|
24
|
+
# Set the HTTP session
|
|
25
|
+
super().__init__(
|
|
26
|
+
app="relval",
|
|
27
|
+
id=id,
|
|
28
|
+
debug=debug,
|
|
29
|
+
cookie=cookie,
|
|
30
|
+
dev=dev,
|
|
31
|
+
client_id=client_id,
|
|
32
|
+
client_secret=client_secret,
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
# RelVal methods
|
|
36
|
+
|
|
37
|
+
def create(self, data):
|
|
38
|
+
"""
|
|
39
|
+
Create a new RelVal.
|
|
40
|
+
Requires manager role.
|
|
41
|
+
"""
|
|
42
|
+
return self._put(url="api/relvals/create", data=data)
|
|
43
|
+
|
|
44
|
+
def delete(self, data):
|
|
45
|
+
"""
|
|
46
|
+
Delete one or multiple RelVals.
|
|
47
|
+
Requires manager role.
|
|
48
|
+
"""
|
|
49
|
+
response = self.session.delete(
|
|
50
|
+
url=f"{self.server}api/relvals/delete", json=data
|
|
51
|
+
)
|
|
52
|
+
response.raise_for_status()
|
|
53
|
+
return response.json()
|
|
54
|
+
|
|
55
|
+
def update(self, data):
|
|
56
|
+
"""
|
|
57
|
+
Update one or multiple RelVals.
|
|
58
|
+
Requires manager role.
|
|
59
|
+
"""
|
|
60
|
+
return self._post(url="api/relvals/update", data=data)
|
|
61
|
+
|
|
62
|
+
def get_relval(self, prepid: str):
|
|
63
|
+
"""
|
|
64
|
+
Retrieve a single RelVal by its prepid.
|
|
65
|
+
"""
|
|
66
|
+
return self._get(url=f"api/relvals/get/{prepid}")
|
|
67
|
+
|
|
68
|
+
def get_editable(self, prepid: str = None):
|
|
69
|
+
"""
|
|
70
|
+
Get information on which RelVal fields are editable.
|
|
71
|
+
If prepid is given, return for a specific RelVal.
|
|
72
|
+
"""
|
|
73
|
+
url = "api/relvals/get_editable"
|
|
74
|
+
if prepid:
|
|
75
|
+
url += f"/{prepid}"
|
|
76
|
+
return self._get(url=url)
|
|
77
|
+
|
|
78
|
+
def get_cmsdriver(self, prepid: str):
|
|
79
|
+
"""
|
|
80
|
+
Get a bash script with cmsDriver.py commands of RelVal.
|
|
81
|
+
"""
|
|
82
|
+
response = self.session.get(
|
|
83
|
+
url=f"{self.server}api/relvals/get_cmsdriver/{prepid}"
|
|
84
|
+
)
|
|
85
|
+
response.raise_for_status()
|
|
86
|
+
return response.text
|
|
87
|
+
|
|
88
|
+
def get_config_upload(self, prepid: str):
|
|
89
|
+
"""
|
|
90
|
+
Get a bash script to upload configs to ReqMgr config cache.
|
|
91
|
+
"""
|
|
92
|
+
response = self.session.get(
|
|
93
|
+
url=f"{self.server}api/relvals/get_config_upload/{prepid}"
|
|
94
|
+
)
|
|
95
|
+
response.raise_for_status()
|
|
96
|
+
return response.text
|
|
97
|
+
|
|
98
|
+
def get_dict(self, prepid: str):
|
|
99
|
+
"""
|
|
100
|
+
Get a dictionary with job information for ReqMgr2.
|
|
101
|
+
"""
|
|
102
|
+
return self._get(url=f"api/relvals/get_dict/{prepid}")
|
|
103
|
+
|
|
104
|
+
def get_default_step(self):
|
|
105
|
+
"""
|
|
106
|
+
Get a default (empty) step that could be used as a template.
|
|
107
|
+
"""
|
|
108
|
+
return self._get(url="api/relvals/get_default_step")
|
|
109
|
+
|
|
110
|
+
def next_status(self, data):
|
|
111
|
+
"""
|
|
112
|
+
Move one or multiple RelVals to next status.
|
|
113
|
+
Requires manager role.
|
|
114
|
+
"""
|
|
115
|
+
return self._post(url="api/relvals/next_status", data=data)
|
|
116
|
+
|
|
117
|
+
def previous_status(self, data):
|
|
118
|
+
"""
|
|
119
|
+
Move one or multiple RelVals to previous status.
|
|
120
|
+
Requires manager role.
|
|
121
|
+
"""
|
|
122
|
+
return self._post(url="api/relvals/previous_status", data=data)
|
|
123
|
+
|
|
124
|
+
def update_workflows(self, data):
|
|
125
|
+
"""
|
|
126
|
+
Trigger one or multiple RelVal updates from Stats2 (ReqMgr2 + DBS).
|
|
127
|
+
Requires manager role.
|
|
128
|
+
"""
|
|
129
|
+
return self._post(url="api/relvals/update_workflows", data=data)
|
|
File without changes
|
{pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/tests/applications/mcm/test_resubmission.py
RENAMED
|
@@ -19,6 +19,7 @@ from rest.applications.mcm.core import McM
|
|
|
19
19
|
from rest.applications.mcm.resubmission import ChainRequestResubmitter
|
|
20
20
|
|
|
21
21
|
|
|
22
|
+
@pytest.mark.slow
|
|
22
23
|
@pytest.mark.usefixtures("stdin_enabled", "production_manager_or_higher")
|
|
23
24
|
class TestChainRequestResubmitter:
|
|
24
25
|
"""
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"""Include some tests to check the RelMon module to interact with the API."""
|
|
2
|
+
|
|
3
|
+
import time
|
|
4
|
+
from copy import deepcopy
|
|
5
|
+
from typing import Any, Dict, Optional, Union
|
|
6
|
+
|
|
7
|
+
import pytest
|
|
8
|
+
from fixtures.oauth import session_cookie_issues
|
|
9
|
+
from fixtures.relmon import relmon, relmon_development
|
|
10
|
+
|
|
11
|
+
from rest.applications.relmon.core import RelMonService
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def test_get_relmons(relmon_development: RelMonService):
|
|
15
|
+
default_response = relmon_development.get_relmons()
|
|
16
|
+
|
|
17
|
+
assert (
|
|
18
|
+
isinstance(default_response, dict) and default_response
|
|
19
|
+
), "Unable to retrieve RelMons from web service!"
|
|
20
|
+
assert default_response.get("total_rows", -1) > 0, "Unexpected number of rows"
|
|
21
|
+
assert (
|
|
22
|
+
len(default_response.get("data", [])) > 0
|
|
23
|
+
), "No data available from the application"
|
|
24
|
+
|
|
25
|
+
with_limit = relmon_development.get_relmons(limit=1)
|
|
26
|
+
assert (
|
|
27
|
+
len(with_limit.get("data", [])) == 1
|
|
28
|
+
), "Unexpected number of element while using limit"
|
|
29
|
+
|
|
30
|
+
with_query_for_name = relmon_development.get_relmons(query="^CMSSW_13_*$")
|
|
31
|
+
assert (
|
|
32
|
+
len(with_query_for_name.get("data", [])) > 0
|
|
33
|
+
), "Unexpected number of element while using query"
|
|
34
|
+
for record in with_query_for_name.get("data", []):
|
|
35
|
+
assert record.get("name", "").startswith(
|
|
36
|
+
"CMSSW_13"
|
|
37
|
+
), "Unexpected element in subset!"
|
|
38
|
+
|
|
39
|
+
with_query_for_none = relmon_development.get_relmons(query="^NotExist_Pattern$")
|
|
40
|
+
assert (
|
|
41
|
+
len(with_query_for_none.get("data", [])) == 0
|
|
42
|
+
), "There should be no element here!"
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def test_get_relmons(relmon_development: RelMonService):
|
|
46
|
+
user_info = relmon_development.user()
|
|
47
|
+
assert isinstance(user_info, dict) and user_info, "No user information available"
|
|
48
|
+
assert user_info.get("login"), "Login information is not available"
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
@pytest.mark.admin
|
|
52
|
+
def test_tick(relmon_development: RelMonService):
|
|
53
|
+
perform_tick = relmon_development.tick()
|
|
54
|
+
assert isinstance(perform_tick, dict) and perform_tick
|
|
55
|
+
assert perform_tick.get("message") == "OK"
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@pytest.mark.slow
|
|
59
|
+
def test_crud(relmon_development: RelMonService, relmon: Dict[str, Any]):
|
|
60
|
+
# Create a new RelMon
|
|
61
|
+
create_instance = deepcopy(relmon)
|
|
62
|
+
create_instance["name"] = f"TestFromHTTPClient_{int(time.time())}"
|
|
63
|
+
create_response = relmon_development.create(relmon=create_instance)
|
|
64
|
+
assert create_response.get("message") == "OK"
|
|
65
|
+
|
|
66
|
+
instance = relmon_development.get_relmons(query=create_instance["name"]).get(
|
|
67
|
+
"data", []
|
|
68
|
+
)
|
|
69
|
+
assert instance
|
|
70
|
+
assert instance[-1].get("name") == create_instance["name"]
|
|
71
|
+
instance = instance[-1]
|
|
72
|
+
|
|
73
|
+
# Reset the RelMon
|
|
74
|
+
reset_response = relmon_development.reset(relmon_id=instance["_id"])
|
|
75
|
+
assert reset_response.get("message") == "OK"
|
|
76
|
+
|
|
77
|
+
# Edit the RelMon
|
|
78
|
+
edit_new_name = f"TestFromHTTPClient_{int(time.time())}"
|
|
79
|
+
instance["name"] = edit_new_name
|
|
80
|
+
edit_response = relmon_development.edit(relmon=instance)
|
|
81
|
+
assert edit_response.get("message") == "OK"
|
|
82
|
+
|
|
83
|
+
instance = relmon_development.get_relmons(query=edit_new_name).get("data", [])
|
|
84
|
+
assert instance
|
|
85
|
+
assert instance[-1].get("name") == edit_new_name
|
|
86
|
+
instance = instance[-1]
|
|
87
|
+
|
|
88
|
+
# Wait some time before deleting
|
|
89
|
+
# Otherwise, the backend stores the operation
|
|
90
|
+
# but executes it in a lazy mode.
|
|
91
|
+
time.sleep(2)
|
|
92
|
+
|
|
93
|
+
# Delete the RelMon
|
|
94
|
+
delete_response = relmon_development.delete(relmon_id=instance["_id"])
|
|
95
|
+
assert delete_response.get("message") == "OK"
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"""Check the RelVal module and its correctness."""
|
|
2
|
+
|
|
3
|
+
from copy import deepcopy
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
6
|
+
from fixtures.oauth import session_cookie_issues
|
|
7
|
+
from fixtures.relval import relval, relval_development, sample_relval_id
|
|
8
|
+
|
|
9
|
+
from rest.applications.relval.core import RelVal
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def test_get_relval(relval_development: RelVal, sample_relval_id: str):
|
|
13
|
+
relval = relval_development.get_relval(prepid=sample_relval_id)
|
|
14
|
+
assert (
|
|
15
|
+
isinstance(relval, dict) and relval
|
|
16
|
+
), "Unable to retrieve RelMons from web service!"
|
|
17
|
+
|
|
18
|
+
assert relval.get("response", {}), "Unable to find the RelVal content!"
|
|
19
|
+
assert relval.get("response", {}).get("prepid") == sample_relval_id
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def test_get_editable(relval_development: RelVal, sample_relval_id: str):
|
|
23
|
+
editable_for_relval = relval_development.get_editable(prepid=sample_relval_id)
|
|
24
|
+
assert (
|
|
25
|
+
isinstance(editable_for_relval, dict) and editable_for_relval
|
|
26
|
+
), "Unable to retrieve RelMons from web service!"
|
|
27
|
+
assert editable_for_relval.get("response", {})
|
|
28
|
+
assert editable_for_relval.get("response", {}).get("editing_info")
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def test_get_cmsdriver(relval_development: RelVal, sample_relval_id: str):
|
|
32
|
+
driver_response = relval_development.get_cmsdriver(prepid=sample_relval_id)
|
|
33
|
+
assert isinstance(driver_response, str) and driver_response
|
|
34
|
+
assert "/cvmfs/cms.cern.ch/cmsset_default.sh" in driver_response
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def test_get_config_upload(relval_development: RelVal, sample_relval_id: str):
|
|
38
|
+
config_response = relval_development.get_config_upload(prepid=sample_relval_id)
|
|
39
|
+
assert isinstance(config_response, str) and config_response
|
|
40
|
+
assert "$PYTHON_INT config_uploader.py --file" in config_response
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def test_get_dict(relval_development: RelVal, sample_relval_id: str):
|
|
44
|
+
reqmgr2_for_relval = relval_development.get_dict(prepid=sample_relval_id)
|
|
45
|
+
assert isinstance(reqmgr2_for_relval, dict) and reqmgr2_for_relval
|
|
46
|
+
assert "CMSSWVersion" in reqmgr2_for_relval
|
|
47
|
+
assert "AcquisitionEra" in reqmgr2_for_relval
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def test_get_default_step(relval_development: RelVal):
|
|
51
|
+
default_step_response = relval_development.get_default_step()
|
|
52
|
+
assert isinstance(default_step_response, dict) and default_step_response
|
|
53
|
+
|
|
54
|
+
driver_content = default_step_response.get("response", {}).get("driver")
|
|
55
|
+
assert isinstance(driver_content, dict) and driver_content
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@pytest.mark.slow
|
|
59
|
+
def test_crud(relval_development: RelVal, relval: dict):
|
|
60
|
+
# Create a new RelVal in the application.
|
|
61
|
+
create_relval_response = relval_development.create(data=relval)
|
|
62
|
+
assert isinstance(create_relval_response, dict) and create_relval_response
|
|
63
|
+
assert isinstance(
|
|
64
|
+
create_relval_response.get("success"), bool
|
|
65
|
+
) and create_relval_response.get("success")
|
|
66
|
+
|
|
67
|
+
relval_instance = create_relval_response.get("response", {})
|
|
68
|
+
assert isinstance(relval_instance, dict) and relval_instance
|
|
69
|
+
|
|
70
|
+
# Update the created RelVal
|
|
71
|
+
new_notes = "RelVal instance for testing the PdmV HTTP client"
|
|
72
|
+
relval_instance["notes"] = new_notes
|
|
73
|
+
update_relval_response = relval_development.update(data=relval_instance)
|
|
74
|
+
assert isinstance(update_relval_response, dict) and update_relval_response
|
|
75
|
+
assert isinstance(
|
|
76
|
+
update_relval_response.get("success"), bool
|
|
77
|
+
) and update_relval_response.get("success")
|
|
78
|
+
|
|
79
|
+
relval_instance = update_relval_response.get("response", {})
|
|
80
|
+
assert isinstance(relval_instance, dict) and relval_instance
|
|
81
|
+
assert relval_instance["notes"] == new_notes
|
|
82
|
+
|
|
83
|
+
# Send to the next status
|
|
84
|
+
initial_status = relval_instance["status"]
|
|
85
|
+
next_status_response = relval_development.next_status(data=relval_instance)
|
|
86
|
+
assert isinstance(next_status_response, dict) and next_status_response
|
|
87
|
+
assert isinstance(
|
|
88
|
+
next_status_response.get("success"), bool
|
|
89
|
+
) and next_status_response.get("success")
|
|
90
|
+
|
|
91
|
+
relval_instance = next_status_response.get("response", {})
|
|
92
|
+
assert isinstance(relval_instance, dict) and relval_instance
|
|
93
|
+
assert relval_instance["status"] != initial_status
|
|
94
|
+
|
|
95
|
+
# Send to the previous status
|
|
96
|
+
previous_status_response = relval_development.previous_status(data=relval_instance)
|
|
97
|
+
assert isinstance(previous_status_response, dict) and previous_status_response
|
|
98
|
+
assert isinstance(
|
|
99
|
+
previous_status_response.get("success"), bool
|
|
100
|
+
) and previous_status_response.get("success")
|
|
101
|
+
|
|
102
|
+
relval_instance = previous_status_response.get("response", {})
|
|
103
|
+
assert isinstance(relval_instance, dict) and relval_instance
|
|
104
|
+
assert relval_instance["status"] == initial_status
|
|
105
|
+
|
|
106
|
+
# Delete the instance
|
|
107
|
+
delete_response = relval_development.delete(data=relval_instance)
|
|
108
|
+
assert isinstance(delete_response, dict) and delete_response
|
|
109
|
+
assert isinstance(delete_response.get("success"), bool) and delete_response.get(
|
|
110
|
+
"success"
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
still_exists_response = relval_development.get_relval(
|
|
114
|
+
prepid=relval_instance["prepid"]
|
|
115
|
+
)
|
|
116
|
+
assert still_exists_response["success"] == False
|
|
File without changes
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"""Fixture for the RelMon tests."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Dict, Optional, Union
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
6
|
+
|
|
7
|
+
from rest.applications.relmon.core import RelMonService
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@pytest.fixture
|
|
11
|
+
def relmon_development() -> RelMonService:
|
|
12
|
+
return RelMonService(id=RelMonService.SSO, dev=True)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@pytest.fixture
|
|
16
|
+
def relmon() -> Dict[str, Any]:
|
|
17
|
+
return {
|
|
18
|
+
"name": "",
|
|
19
|
+
"categories": [
|
|
20
|
+
{
|
|
21
|
+
"name": "Data",
|
|
22
|
+
"hlt": "both",
|
|
23
|
+
"automatic_pairing": True,
|
|
24
|
+
"reference": [],
|
|
25
|
+
"target": [],
|
|
26
|
+
"rerun": False,
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"name": "FullSim",
|
|
30
|
+
"hlt": "both",
|
|
31
|
+
"automatic_pairing": True,
|
|
32
|
+
"reference": [],
|
|
33
|
+
"target": [],
|
|
34
|
+
"rerun": False,
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"name": "FastSim",
|
|
38
|
+
"hlt": "both",
|
|
39
|
+
"automatic_pairing": True,
|
|
40
|
+
"reference": [],
|
|
41
|
+
"target": [],
|
|
42
|
+
"rerun": False,
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"name": "Generator",
|
|
46
|
+
"hlt": "no",
|
|
47
|
+
"automatic_pairing": True,
|
|
48
|
+
"reference": [],
|
|
49
|
+
"target": [],
|
|
50
|
+
"rerun": False,
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"name": "FullSim_PU",
|
|
54
|
+
"hlt": "both",
|
|
55
|
+
"automatic_pairing": True,
|
|
56
|
+
"reference": [
|
|
57
|
+
"pdmvserv_RVCMSSW_12_3_0_pre6ZMM_14__2026D88PU200_rsb_220417_125145_9614"
|
|
58
|
+
],
|
|
59
|
+
"target": [
|
|
60
|
+
"pdmvserv_RVCMSSW_12_3_0_pre6ZMM_14__2026D88PU200_rsb_220417_125145_9614"
|
|
61
|
+
],
|
|
62
|
+
"rerun": False,
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"name": "FastSim_PU",
|
|
66
|
+
"hlt": "both",
|
|
67
|
+
"automatic_pairing": True,
|
|
68
|
+
"reference": [],
|
|
69
|
+
"target": [],
|
|
70
|
+
"rerun": False,
|
|
71
|
+
},
|
|
72
|
+
],
|
|
73
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"""Fixture for the RelVal tests."""
|
|
2
|
+
|
|
3
|
+
import time
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
6
|
+
|
|
7
|
+
from rest.applications.relval.core import RelVal
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@pytest.fixture
|
|
11
|
+
def relval_development() -> RelVal:
|
|
12
|
+
return RelVal(id=RelVal.SSO, dev=True)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@pytest.fixture
|
|
16
|
+
def sample_relval_id() -> str:
|
|
17
|
+
return "CMSSW_13_0_13__RV270_MiniToMini_2023DataReference-EGamma0_Run2023D-22Sep2023_v2-00001"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@pytest.fixture
|
|
21
|
+
def relval() -> dict:
|
|
22
|
+
return {
|
|
23
|
+
"_id": f"CMSSW_15_1_0_pre5__Phase2_{int(time.time())}-00001",
|
|
24
|
+
"batch_name": "Phase2_Run4D110_PU",
|
|
25
|
+
"campaign_timestamp": 0,
|
|
26
|
+
"cmssw_release": "CMSSW_15_1_0_pre5",
|
|
27
|
+
"cpu_cores": 4,
|
|
28
|
+
"execute_steps": False,
|
|
29
|
+
"fragment": "",
|
|
30
|
+
"history": [],
|
|
31
|
+
"job_dict_overwrite": {},
|
|
32
|
+
"label": "STD_Run4D110_PU",
|
|
33
|
+
"matrix": "upgrade",
|
|
34
|
+
"memory": 16000,
|
|
35
|
+
"notes": "",
|
|
36
|
+
"output_datasets": [],
|
|
37
|
+
"prepid": "",
|
|
38
|
+
"sample_tag": "Phase2_D110",
|
|
39
|
+
"scram_arch": "",
|
|
40
|
+
"size_per_event": 1,
|
|
41
|
+
"status": "new",
|
|
42
|
+
"steps": [
|
|
43
|
+
{
|
|
44
|
+
"cmssw_release": "",
|
|
45
|
+
"config_id": "",
|
|
46
|
+
"driver": {
|
|
47
|
+
"beamspot": "DBrealisticHLLHC",
|
|
48
|
+
"conditions": "auto:phase2_realistic_T33_13TeV",
|
|
49
|
+
"customise": "SLHCUpgradeSimulations/Configuration/aging.customise_aging_1000",
|
|
50
|
+
"customise_commands": "",
|
|
51
|
+
"data": False,
|
|
52
|
+
"datatier": ["GEN-SIM"],
|
|
53
|
+
"era": "Phase2C20I13M9",
|
|
54
|
+
"eventcontent": ["FEVTDEBUG"],
|
|
55
|
+
"extra": "",
|
|
56
|
+
"fast": False,
|
|
57
|
+
"filetype": "",
|
|
58
|
+
"fragment_name": "SingleMuFlatPt2To100_cfi",
|
|
59
|
+
"geometry": "ExtendedRun4D115",
|
|
60
|
+
"hltProcess": "",
|
|
61
|
+
"mc": False,
|
|
62
|
+
"nStreams": "1",
|
|
63
|
+
"number": "10",
|
|
64
|
+
"pileup": "",
|
|
65
|
+
"pileup_input": "",
|
|
66
|
+
"process": "",
|
|
67
|
+
"relval": "9000,100",
|
|
68
|
+
"runUnscheduled": False,
|
|
69
|
+
"scenario": "",
|
|
70
|
+
"step": ["GEN", "SIM"],
|
|
71
|
+
},
|
|
72
|
+
"events_per_lumi": "",
|
|
73
|
+
"gpu": {
|
|
74
|
+
"cuda_capabilities": [],
|
|
75
|
+
"cuda_driver_version": "",
|
|
76
|
+
"cuda_runtime": "",
|
|
77
|
+
"cuda_runtime_version": "",
|
|
78
|
+
"gpu_memory": "",
|
|
79
|
+
"gpu_name": "",
|
|
80
|
+
"requires": "forbidden",
|
|
81
|
+
},
|
|
82
|
+
"input": {
|
|
83
|
+
"dataset": "",
|
|
84
|
+
"events": 0,
|
|
85
|
+
"label": "",
|
|
86
|
+
"lumisection": {},
|
|
87
|
+
"run": [],
|
|
88
|
+
},
|
|
89
|
+
"keep_output": True,
|
|
90
|
+
"lumis_per_job": "10",
|
|
91
|
+
"name": "SingleMuFlatPt2To100_Run4D115_GenSimHLBeamSpot",
|
|
92
|
+
"resolved_globaltag": "",
|
|
93
|
+
"scram_arch": "",
|
|
94
|
+
"step_type": "driver",
|
|
95
|
+
}
|
|
96
|
+
],
|
|
97
|
+
"time_per_event": 1,
|
|
98
|
+
"workflow_id": 32104,
|
|
99
|
+
"workflow_name": "SingleMuFlatPt2To100",
|
|
100
|
+
"workflows": [],
|
|
101
|
+
}
|
|
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
|
{pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/src/pdmv_http_client.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/src/pdmv_http_client.egg-info/requires.txt
RENAMED
|
File without changes
|
{pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/src/pdmv_http_client.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/src/rest/applications/mcm/invalidate_request.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pdmv_http_client-2.1.0/src/rest/utils → pdmv_http_client-2.2.0/src/rest/client/auth}/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{pdmv_http_client-2.1.0/tests → pdmv_http_client-2.2.0/src/rest/client/auth/handlers}/__init__.py
RENAMED
|
File without changes
|
{pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/src/rest/client/auth/handlers/oauth2_tokens.py
RENAMED
|
File without changes
|
{pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/src/rest/client/auth/handlers/session_cookies.py
RENAMED
|
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
|