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.
Files changed (63) hide show
  1. {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/.gitlab-ci.yml +2 -2
  2. {pdmv_http_client-2.1.0/src/pdmv_http_client.egg-info → pdmv_http_client-2.2.0}/PKG-INFO +1 -1
  3. {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/pyproject.toml +5 -0
  4. {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0/src/pdmv_http_client.egg-info}/PKG-INFO +1 -1
  5. {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/src/pdmv_http_client.egg-info/SOURCES.txt +8 -0
  6. {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/src/rest/__init__.py +2 -0
  7. {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/src/rest/_version.py +3 -3
  8. pdmv_http_client-2.2.0/src/rest/applications/relmon/core.py +95 -0
  9. pdmv_http_client-2.2.0/src/rest/applications/relval/core.py +129 -0
  10. pdmv_http_client-2.2.0/tests/__init__.py +0 -0
  11. {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/tests/applications/mcm/test_invalidate_request.py +1 -0
  12. {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/tests/applications/mcm/test_resubmission.py +1 -0
  13. pdmv_http_client-2.2.0/tests/applications/relmon/test_relmon.py +95 -0
  14. pdmv_http_client-2.2.0/tests/applications/relval/test_relval.py +116 -0
  15. pdmv_http_client-2.2.0/tests/fixtures/__init__.py +0 -0
  16. pdmv_http_client-2.2.0/tests/fixtures/relmon.py +73 -0
  17. pdmv_http_client-2.2.0/tests/fixtures/relval.py +101 -0
  18. {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/.gitignore +0 -0
  19. {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/LICENSE +0 -0
  20. {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/README.md +0 -0
  21. {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/examples/README.md +0 -0
  22. {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/examples/chain_req_forcedone.py +0 -0
  23. {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/examples/chain_request_resubmission.py +0 -0
  24. {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/examples/change_priority2.py +0 -0
  25. {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/examples/clone_example.py +0 -0
  26. {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/examples/get_requests.py +0 -0
  27. {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/examples/modify_request.py +0 -0
  28. {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/setup.cfg +0 -0
  29. {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/src/pdmv_http_client.egg-info/dependency_links.txt +0 -0
  30. {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/src/pdmv_http_client.egg-info/requires.txt +0 -0
  31. {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/src/pdmv_http_client.egg-info/top_level.txt +0 -0
  32. {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/src/rest/applications/__init__.py +0 -0
  33. {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/src/rest/applications/base.py +0 -0
  34. {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/src/rest/applications/mcm/__init__.py +0 -0
  35. {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/src/rest/applications/mcm/core.py +0 -0
  36. {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/src/rest/applications/mcm/invalidate_request.py +0 -0
  37. {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/src/rest/applications/mcm/resubmission.py +0 -0
  38. {pdmv_http_client-2.1.0/src/rest/client → pdmv_http_client-2.2.0/src/rest/applications/relmon}/__init__.py +0 -0
  39. {pdmv_http_client-2.1.0/src/rest/client/auth → pdmv_http_client-2.2.0/src/rest/applications/relval}/__init__.py +0 -0
  40. {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/src/rest/applications/rereco/core.py +0 -0
  41. {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/src/rest/applications/stats/core.py +0 -0
  42. {pdmv_http_client-2.1.0/src/rest/client/auth/handlers → pdmv_http_client-2.2.0/src/rest/client}/__init__.py +0 -0
  43. {pdmv_http_client-2.1.0/src/rest/utils → pdmv_http_client-2.2.0/src/rest/client/auth}/__init__.py +0 -0
  44. {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/src/rest/client/auth/auth_interface.py +0 -0
  45. {pdmv_http_client-2.1.0/tests → pdmv_http_client-2.2.0/src/rest/client/auth/handlers}/__init__.py +0 -0
  46. {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/src/rest/client/auth/handlers/oauth2_tokens.py +0 -0
  47. {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/src/rest/client/auth/handlers/session_cookies.py +0 -0
  48. {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/src/rest/client/session.py +0 -0
  49. {pdmv_http_client-2.1.0/tests/fixtures → pdmv_http_client-2.2.0/src/rest/utils}/__init__.py +0 -0
  50. {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/src/rest/utils/logger.py +0 -0
  51. {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/src/rest/utils/miscellaneous.py +0 -0
  52. {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/src/rest/utils/shell.py +0 -0
  53. {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/tests/applications/mcm/test_rest.py +0 -0
  54. {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/tests/applications/stats/test_stats.py +0 -0
  55. {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/tests/client/README.md +0 -0
  56. {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/tests/client/auth/handlers/test_oauth2_tokens_handlers.py +0 -0
  57. {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/tests/client/auth/handlers/test_session_cookie_handler.py +0 -0
  58. {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/tests/client/test_session.py +0 -0
  59. {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/tests/fixtures/files.py +0 -0
  60. {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/tests/fixtures/mcm.py +0 -0
  61. {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/tests/fixtures/oauth.py +0 -0
  62. {pdmv_http_client-2.1.0 → pdmv_http_client-2.2.0}/tests/utils/test_shell.py +0 -0
  63. {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 -k 'TestSessionFactory or test_rest' -vv
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.1.0
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.1.0
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.1.0'
32
- __version_tuple__ = version_tuple = (2, 1, 0)
31
+ __version__ = version = '2.2.0'
32
+ __version_tuple__ = version_tuple = (2, 2, 0)
33
33
 
34
- __commit_id__ = commit_id = 'ge8e5501a4'
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
@@ -15,6 +15,7 @@ from fixtures.mcm import (
15
15
  from fixtures.oauth import stdin_enabled
16
16
 
17
17
 
18
+ @pytest.mark.slow
18
19
  @pytest.mark.usefixtures("stdin_enabled", "production_manager_or_higher")
19
20
  class TestInvalidateDeleteRequest:
20
21
  """
@@ -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
+ }