diracx-testing 0.0.1a24__py3-none-any.whl → 0.0.1a26__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.
@@ -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):
diracx/testing/utils.py CHANGED
@@ -18,8 +18,8 @@ from typing import TYPE_CHECKING, Generator
18
18
  from urllib.parse import parse_qs, urljoin, urlparse
19
19
  from uuid import uuid4
20
20
 
21
+ import httpx
21
22
  import pytest
22
- import requests
23
23
 
24
24
  if TYPE_CHECKING:
25
25
  from diracx.core.settings import DevelopmentSettings
@@ -252,6 +252,7 @@ class ClientFactory:
252
252
  assert (
253
253
  self.app.dependency_overrides == {} and self.app.lifetime_functions == []
254
254
  ), "configure cannot be nested"
255
+
255
256
  for k, v in self.all_dependency_overrides.items():
256
257
 
257
258
  class_name = k.__self__.__name__
@@ -284,17 +285,26 @@ class ClientFactory:
284
285
  import sqlalchemy
285
286
  from sqlalchemy.util.concurrency import greenlet_spawn
286
287
 
288
+ from diracx.db.os.utils import BaseOSDB
287
289
  from diracx.db.sql.utils import BaseSQLDB
290
+ from diracx.testing.mock_osdb import MockOSDBMixin
288
291
 
289
292
  for k, v in self.app.dependency_overrides.items():
290
- # Ignore dependency overrides which aren't BaseSQLDB.transaction
291
- if (
292
- isinstance(v, UnavailableDependency)
293
- or k.__func__ != BaseSQLDB.transaction.__func__
293
+ # Ignore dependency overrides which aren't BaseSQLDB.transaction or BaseOSDB.session
294
+ if isinstance(v, UnavailableDependency) or k.__func__ not in (
295
+ BaseSQLDB.transaction.__func__,
296
+ BaseOSDB.session.__func__,
294
297
  ):
298
+
295
299
  continue
300
+
296
301
  # The first argument of the overridden BaseSQLDB.transaction is the DB object
297
302
  db = v.args[0]
303
+ # We expect the OS DB to be mocked with sqlite, so use the
304
+ # internal DB
305
+ if isinstance(db, MockOSDBMixin):
306
+ db = db._sql_db
307
+
298
308
  assert isinstance(db, BaseSQLDB), (k, db)
299
309
 
300
310
  # set PRAGMA foreign_keys=ON if sqlite
@@ -606,7 +616,7 @@ async def test_login(monkeypatch, capfd, cli_env):
606
616
 
607
617
  poll_attempts = 0
608
618
 
609
- def fake_sleep(*args, **kwargs):
619
+ async def fake_sleep(*args, **kwargs):
610
620
  nonlocal poll_attempts
611
621
 
612
622
  # Keep track of the number of times this is called
@@ -619,13 +629,13 @@ async def test_login(monkeypatch, capfd, cli_env):
619
629
  match = re.search(rf"{cli_env['DIRACX_URL']}[^\n]+", captured.out)
620
630
  assert match, captured
621
631
 
622
- do_device_flow_with_dex(match.group(), cli_env["DIRACX_CA_PATH"])
632
+ await do_device_flow_with_dex(match.group(), cli_env["DIRACX_CA_PATH"])
623
633
 
624
634
  # Ensure we don't poll forever
625
635
  assert poll_attempts <= 100
626
636
 
627
637
  # Reduce the sleep duration to zero to speed up the test
628
- return unpatched_sleep(0)
638
+ await unpatched_sleep(0.0)
629
639
 
630
640
  # We monkeypatch asyncio.sleep to provide a hook to run the actions that
631
641
  # would normally be done by a user. This includes capturing the login URL
@@ -640,7 +650,7 @@ async def test_login(monkeypatch, capfd, cli_env):
640
650
 
641
651
  # Run the login command
642
652
  with monkeypatch.context() as m:
643
- m.setattr("asyncio.sleep", fake_sleep)
653
+ m.setattr("diracx.cli.auth.sleep", fake_sleep)
644
654
  await cli.auth.login(vo="diracAdmin", group=None, property=None)
645
655
  captured = capfd.readouterr()
646
656
  assert "Login successful!" in captured.out
@@ -654,7 +664,7 @@ async def test_login(monkeypatch, capfd, cli_env):
654
664
  return expected_credentials_path.read_text()
655
665
 
656
666
 
657
- def do_device_flow_with_dex(url: str, ca_path: str) -> None:
667
+ async def do_device_flow_with_dex(url: str, ca_path: str) -> None:
658
668
  """Do the device flow with dex."""
659
669
 
660
670
  class DexLoginFormParser(HTMLParser):
@@ -662,10 +672,14 @@ def do_device_flow_with_dex(url: str, ca_path: str) -> None:
662
672
  nonlocal action_url
663
673
  if "form" in str(tag):
664
674
  assert action_url is None
665
- action_url = urljoin(login_page_url, dict(attrs)["action"])
675
+ action_url = urljoin(str(login_page_url), dict(attrs)["action"])
666
676
 
677
+ ssl_context = ssl.create_default_context(cafile=ca_path)
678
+ client_kwargs = dict(verify=ssl_context, follow_redirects=True)
667
679
  # Get the login page
668
- r = requests.get(url, verify=ca_path)
680
+ async with httpx.AsyncClient(**client_kwargs) as client:
681
+ r = await client.get(url)
682
+
669
683
  r.raise_for_status()
670
684
  login_page_url = r.url # This is not the same as URL as we redirect to dex
671
685
  login_page_body = r.text
@@ -676,19 +690,24 @@ def do_device_flow_with_dex(url: str, ca_path: str) -> None:
676
690
  assert action_url is not None, login_page_body
677
691
 
678
692
  # Do the actual login
679
- r = requests.post(
680
- action_url,
681
- data={"login": "admin@example.com", "password": "password"},
682
- verify=ca_path,
683
- )
693
+ async with httpx.AsyncClient(**client_kwargs) as client:
694
+ r = await client.post(
695
+ action_url,
696
+ data={"login": "admin@example.com", "password": "password"},
697
+ )
698
+
684
699
  r.raise_for_status()
685
700
  approval_url = r.url # This is not the same as URL as we redirect to dex
686
701
  # Do the actual approval
687
- r = requests.post(
688
- approval_url,
689
- {"approval": "approve", "req": parse_qs(urlparse(r.url).query)["req"][0]},
690
- verify=ca_path,
691
- )
702
+
703
+ async with httpx.AsyncClient(**client_kwargs) as client:
704
+ r = await client.post(
705
+ approval_url,
706
+ data={
707
+ "approval": "approve",
708
+ "req": parse_qs(urlparse(str(r.url)).query)["req"][0],
709
+ },
710
+ )
692
711
 
693
712
  # This should have redirected to the DiracX page that shows the login is complete
694
713
  assert "Please close the window" in r.text
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: diracx-testing
3
- Version: 0.0.1a24
3
+ Version: 0.0.1a26
4
4
  Summary: TODO
5
5
  License: GPL-3.0-only
6
6
  Classifier: Intended Audience :: Science/Research
@@ -14,5 +14,6 @@ Requires-Dist: pytest
14
14
  Requires-Dist: pytest-asyncio
15
15
  Requires-Dist: pytest-cov
16
16
  Requires-Dist: pytest-xdist
17
+ Requires-Dist: httpx
17
18
  Provides-Extra: testing
18
19
  Requires-Dist: diracx-testing; extra == "testing"
@@ -1,11 +1,11 @@
1
1
  diracx/testing/__init__.py,sha256=nGbnGP8m53N9rqHR-hyqDa5vetcsmnQp806HadV6_dE,984
2
2
  diracx/testing/dummy_osdb.py,sha256=bNk3LF8KgMuQx3RVFNYuw4hMmpG2A80sZ58rEZqHo7M,907
3
3
  diracx/testing/entrypoints.py,sha256=MbH0VLUQz96XPdHzb7XWFwYtWEitAqPrrGM1H1FzDLo,2231
4
- diracx/testing/mock_osdb.py,sha256=SCpiC0HnsBL2UZMrmybG060A2jvlhDXNcLQ4KgdCSQ4,5873
4
+ diracx/testing/mock_osdb.py,sha256=hHuvmQZ3212SaSGX11dQv4ki3ZWsmqJZFYwdn6kg2MA,6029
5
5
  diracx/testing/osdb.py,sha256=m6mUBLnGOoQLTCIBie9P2GhmLMybrgzIrlIYfhF1_Ss,3230
6
6
  diracx/testing/routers.py,sha256=UW-TnikMQgcNxF5sUZD5DWoucGiCpP6s8mYmuahDiSc,979
7
- diracx/testing/utils.py,sha256=5NRQhWre34dIhhTccBI1IICz2lPdxvEpbpq4jb_wKZw,23694
8
- diracx_testing-0.0.1a24.dist-info/METADATA,sha256=MYbR38ttL5UcXNqhmh0Q-8fWlnhqWDVXH1k9ImIfpTI,613
9
- diracx_testing-0.0.1a24.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
10
- diracx_testing-0.0.1a24.dist-info/top_level.txt,sha256=vJx10tdRlBX3rF2Psgk5jlwVGZNcL3m_7iQWwgPXt-U,7
11
- diracx_testing-0.0.1a24.dist-info/RECORD,,
7
+ diracx/testing/utils.py,sha256=uPI7UssaOkDvaG3Lq1-A-IJCYvhQ1F_HcQsI6N6O-Bw,24417
8
+ diracx_testing-0.0.1a26.dist-info/METADATA,sha256=Cye4WM98UB1L1irFN3KHkgq4Iqd74Gxi-Ej8U-kc9fw,634
9
+ diracx_testing-0.0.1a26.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
10
+ diracx_testing-0.0.1a26.dist-info/top_level.txt,sha256=vJx10tdRlBX3rF2Psgk5jlwVGZNcL3m_7iQWwgPXt-U,7
11
+ diracx_testing-0.0.1a26.dist-info/RECORD,,