diracx-testing 0.0.1a23__py3-none-any.whl → 0.0.1a25__py3-none-any.whl

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.
@@ -0,0 +1,67 @@
1
+ from __future__ import annotations
2
+
3
+ import tomllib
4
+ from collections import defaultdict
5
+ from importlib.metadata import PackageNotFoundError, distribution, entry_points
6
+
7
+ import pytest
8
+
9
+
10
+ def get_installed_entry_points():
11
+ """Retrieve the installed entry points from the environment."""
12
+ entry_pts = entry_points()
13
+ diracx_eps = defaultdict(dict)
14
+ for group in entry_pts.groups:
15
+ if "diracx" in group:
16
+ for ep in entry_pts.select(group=group):
17
+ diracx_eps[group][ep.name] = ep.value
18
+ return dict(diracx_eps)
19
+
20
+
21
+ def get_entry_points_from_toml(toml_file):
22
+ """Parse entry points from pyproject.toml."""
23
+ with open(toml_file, "rb") as f:
24
+ pyproject = tomllib.load(f)
25
+ package_name = pyproject["project"]["name"]
26
+ return package_name, pyproject.get("project", {}).get("entry-points", {})
27
+
28
+
29
+ def get_current_entry_points(repo_base) -> bool:
30
+ """Create current entry points dict for comparison."""
31
+ current_eps = {}
32
+ for toml_file in repo_base.glob("diracx-*/pyproject.toml"):
33
+ package_name, entry_pts = get_entry_points_from_toml(f"{toml_file}")
34
+ # Ignore packages that are not installed
35
+ try:
36
+ distribution(package_name)
37
+ except PackageNotFoundError:
38
+ continue
39
+ # Merge the entry points
40
+ for key, value in entry_pts.items():
41
+ current_eps[key] = current_eps.get(key, {}) | value
42
+ return current_eps
43
+
44
+
45
+ @pytest.fixture(scope="session", autouse=True)
46
+ def verify_entry_points(request, pytestconfig):
47
+ try:
48
+ ini_toml_name = tomllib.loads(pytestconfig.inipath.read_text())["project"][
49
+ "name"
50
+ ]
51
+ except tomllib.TOMLDecodeError:
52
+ return
53
+ if ini_toml_name == "diracx":
54
+ repo_base = pytestconfig.inipath.parent
55
+ elif ini_toml_name.startswith("diracx-"):
56
+ repo_base = pytestconfig.inipath.parent.parent
57
+ else:
58
+ return
59
+
60
+ installed_eps = get_installed_entry_points()
61
+ current_eps = get_current_entry_points(repo_base)
62
+
63
+ if installed_eps != current_eps:
64
+ pytest.fail(
65
+ "Project and installed entry-points are not consistent. "
66
+ "You should run `pip install -r requirements-dev.txt`",
67
+ )
@@ -42,8 +42,8 @@ class MockOSDBMixin:
42
42
  from diracx.db.sql.utils import DateNowColumn
43
43
 
44
44
  # Dynamically create a subclass of BaseSQLDB so we get clearer errors
45
- MockedDB = type(f"Mocked{self.__class__.__name__}", (sql_utils.BaseSQLDB,), {})
46
- self._sql_db = MockedDB(connection_kwargs["sqlalchemy_dsn"])
45
+ mocked_db = type(f"Mocked{self.__class__.__name__}", (sql_utils.BaseSQLDB,), {})
46
+ self._sql_db = mocked_db(connection_kwargs["sqlalchemy_dsn"])
47
47
 
48
48
  # Dynamically create the table definition based on the fields
49
49
  columns = [
@@ -53,16 +53,16 @@ class MockOSDBMixin:
53
53
  for field, field_type in self.fields.items():
54
54
  match field_type["type"]:
55
55
  case "date":
56
- ColumnType = DateNowColumn
56
+ column_type = DateNowColumn
57
57
  case "long":
58
- ColumnType = partial(Column, type_=Integer)
58
+ column_type = partial(Column, type_=Integer)
59
59
  case "keyword":
60
- ColumnType = partial(Column, type_=String(255))
60
+ column_type = partial(Column, type_=String(255))
61
61
  case "text":
62
- ColumnType = partial(Column, type_=String(64 * 1024))
62
+ column_type = partial(Column, type_=String(64 * 1024))
63
63
  case _:
64
64
  raise NotImplementedError(f"Unknown field type: {field_type=}")
65
- columns.append(ColumnType(field, default=None))
65
+ columns.append(column_type(field, default=None))
66
66
  self._sql_db.metadata = MetaData()
67
67
  self._table = Table("dummy", self._sql_db.metadata, *columns)
68
68
 
@@ -72,18 +72,22 @@ class MockOSDBMixin:
72
72
  yield
73
73
 
74
74
  async def __aenter__(self):
75
- await self._sql_db.__aenter__()
75
+ """Enter the request context.
76
+
77
+ This is a no-op as the real OpenSearch class doesn't use transactions.
78
+ Instead we enter a transaction in each method that needs it.
79
+ """
76
80
  return self
77
81
 
78
82
  async def __aexit__(self, exc_type, exc_value, traceback):
79
- await self._sql_db.__aexit__(exc_type, exc_value, traceback)
83
+ pass
80
84
 
81
85
  async def create_index_template(self) -> None:
82
86
  async with self._sql_db.engine.begin() as conn:
83
87
  await conn.run_sync(self._sql_db.metadata.create_all)
84
88
 
85
89
  async def upsert(self, doc_id, document) -> None:
86
- async with self:
90
+ async with self._sql_db:
87
91
  values = {}
88
92
  for key, value in document.items():
89
93
  if key in self.fields:
@@ -106,7 +110,7 @@ class MockOSDBMixin:
106
110
  per_page: int = 100,
107
111
  page: int | None = None,
108
112
  ) -> tuple[int, list[dict[Any, Any]]]:
109
- async with self:
113
+ async with self._sql_db:
110
114
  # Apply selection
111
115
  if parameters:
112
116
  columns = []
@@ -150,7 +154,8 @@ class MockOSDBMixin:
150
154
  return results
151
155
 
152
156
  async def ping(self):
153
- return await self._sql_db.ping()
157
+ async with self._sql_db:
158
+ return await self._sql_db.ping()
154
159
 
155
160
 
156
161
  def fake_available_osdb_implementations(name, *, real_available_implementations):
@@ -158,6 +163,6 @@ def fake_available_osdb_implementations(name, *, real_available_implementations)
158
163
 
159
164
  # Dynamically generate a class that inherits from the first implementation
160
165
  # but that also has the MockOSDBMixin
161
- MockParameterDB = type(name, (MockOSDBMixin, implementations[0]), {})
166
+ mock_parameter_db = type(name, (MockOSDBMixin, implementations[0]), {})
162
167
 
163
- return [MockParameterDB] + implementations
168
+ return [mock_parameter_db] + implementations