pytest-databases 0.5.0__tar.gz → 0.6.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 (69) hide show
  1. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/.pre-commit-config.yaml +1 -1
  2. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/Makefile +6 -0
  3. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/PKG-INFO +5 -2
  4. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/README.md +1 -0
  5. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/pyproject.toml +15 -18
  6. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/src/pytest_databases/docker/__init__.py +11 -2
  7. pytest_databases-0.6.0/src/pytest_databases/docker/azure_blob.py +187 -0
  8. pytest_databases-0.6.0/src/pytest_databases/docker/docker-compose.azurite.yml +9 -0
  9. pytest_databases-0.6.0/tests/docker/test_azure_blob.py +35 -0
  10. pytest_databases-0.5.0/requirements/requirements-dev.txt +0 -497
  11. pytest_databases-0.5.0/requirements/requirements-docs.txt +0 -405
  12. pytest_databases-0.5.0/requirements/requirements.txt +0 -13
  13. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/.gitignore +0 -0
  14. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/.sourcery.yaml +0 -0
  15. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/.vscode/launch.json +0 -0
  16. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/.vscode/settings.json +0 -0
  17. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/CODEOWNERS +0 -0
  18. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/CONTRIBUTING.rst +0 -0
  19. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/LICENSE +0 -0
  20. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/scripts/__init__.py +0 -0
  21. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/scripts/build_docs.py +0 -0
  22. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/scripts/convert_docs.sh +0 -0
  23. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/sonar-project.properties +0 -0
  24. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/src/pytest_databases/__init__.py +0 -0
  25. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/src/pytest_databases/__metadata__.py +0 -0
  26. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/src/pytest_databases/docker/alloydb_omni.py +0 -0
  27. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/src/pytest_databases/docker/bigquery.py +0 -0
  28. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/src/pytest_databases/docker/cockroachdb.py +0 -0
  29. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/src/pytest_databases/docker/docker-compose.alloydb-omni.yml +0 -0
  30. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/src/pytest_databases/docker/docker-compose.bigquery.yml +0 -0
  31. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/src/pytest_databases/docker/docker-compose.cockroachdb.yml +0 -0
  32. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/src/pytest_databases/docker/docker-compose.dragonfly.yml +0 -0
  33. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/src/pytest_databases/docker/docker-compose.elasticsearch.yml +0 -0
  34. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/src/pytest_databases/docker/docker-compose.keydb.yml +0 -0
  35. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/src/pytest_databases/docker/docker-compose.mariadb.yml +0 -0
  36. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/src/pytest_databases/docker/docker-compose.mssql.yml +0 -0
  37. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/src/pytest_databases/docker/docker-compose.mysql.yml +0 -0
  38. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/src/pytest_databases/docker/docker-compose.oracle.yml +0 -0
  39. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/src/pytest_databases/docker/docker-compose.postgres.yml +0 -0
  40. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/src/pytest_databases/docker/docker-compose.redis.yml +0 -0
  41. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/src/pytest_databases/docker/docker-compose.spanner.yml +0 -0
  42. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/src/pytest_databases/docker/dragonfly.py +0 -0
  43. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/src/pytest_databases/docker/elastic_search.py +0 -0
  44. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/src/pytest_databases/docker/keydb.py +0 -0
  45. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/src/pytest_databases/docker/mariadb.py +0 -0
  46. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/src/pytest_databases/docker/mssql.py +0 -0
  47. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/src/pytest_databases/docker/mysql.py +0 -0
  48. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/src/pytest_databases/docker/oracle.py +0 -0
  49. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/src/pytest_databases/docker/postgres.py +0 -0
  50. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/src/pytest_databases/docker/redis.py +0 -0
  51. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/src/pytest_databases/docker/spanner.py +0 -0
  52. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/src/pytest_databases/helpers.py +0 -0
  53. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/src/pytest_databases/py.typed +0 -0
  54. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/tests/__init__.py +0 -0
  55. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/tests/conftest.py +0 -0
  56. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/tests/docker/__init__.py +0 -0
  57. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/tests/docker/test_alloydb_omni.py +0 -0
  58. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/tests/docker/test_bigquery.py +0 -0
  59. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/tests/docker/test_cockroachdb.py +0 -0
  60. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/tests/docker/test_dragonfly.py +0 -0
  61. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/tests/docker/test_elasticsearch.py +0 -0
  62. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/tests/docker/test_keydb.py +0 -0
  63. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/tests/docker/test_mariadb.py +0 -0
  64. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/tests/docker/test_mssql.py +0 -0
  65. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/tests/docker/test_mysql.py +0 -0
  66. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/tests/docker/test_oracle.py +0 -0
  67. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/tests/docker/test_postgres.py +0 -0
  68. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/tests/docker/test_redis.py +0 -0
  69. {pytest_databases-0.5.0 → pytest_databases-0.6.0}/tests/docker/test_spanner.py +0 -0
@@ -19,7 +19,7 @@ repos:
19
19
 
20
20
  # Ruff replaces black, flake8, autoflake and isort
21
21
  - repo: https://github.com/charliermarsh/ruff-pre-commit
22
- rev: "v0.4.0" # make sure this is always consistent with hatch configs
22
+ rev: "v0.4.5" # make sure this is always consistent with hatch configs
23
23
  hooks:
24
24
  - id: ruff
25
25
  args: [--config, ./pyproject.toml]
@@ -111,6 +111,12 @@ lint: ## Runs pre-commit hooks; includes ruff linting, codespell, bl
111
111
 
112
112
  .PHONY: test
113
113
  test: ## Run the tests
114
+ @echo "=> Running test cases"
115
+ @hatch run +py=3.12 test:cov
116
+ @echo "=> Tests complete"
117
+
118
+ .PHONY: test-all
119
+ test-all: ## Run the tests for all python versions
114
120
  @echo "=> Running test cases"
115
121
  @hatch run test:cov
116
122
  @echo "=> Tests complete"
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.3
2
2
  Name: pytest-databases
3
- Version: 0.5.0
3
+ Version: 0.6.0
4
4
  Summary: Reusable database fixtures for any and all databases.
5
5
  Project-URL: Documentation, https://github.com/litestar-org/pytest-databases#readme
6
6
  Project-URL: Issues, https://github.com/litestar-org/pytest-databases/issues
@@ -20,6 +20,8 @@ Classifier: Programming Language :: Python :: Implementation :: CPython
20
20
  Classifier: Programming Language :: Python :: Implementation :: PyPy
21
21
  Requires-Python: >=3.8
22
22
  Requires-Dist: pytest
23
+ Provides-Extra: azure-storage
24
+ Requires-Dist: azure-storage-blob; extra == 'azure-storage'
23
25
  Provides-Extra: bigquery
24
26
  Requires-Dist: google-cloud-bigquery; extra == 'bigquery'
25
27
  Provides-Extra: cockroachdb
@@ -94,6 +96,7 @@ It is designed to offer pre-configured testing setups for many different types a
94
96
  - **Dragonfly**: Latest server
95
97
  - **KeyDB**: Latest server
96
98
  - **Elasticsearch**: Version 7 and 8 are available
99
+ - **Azure blob storage**: Via azurite
97
100
 
98
101
  ## Contributing
99
102
 
@@ -44,6 +44,7 @@ It is designed to offer pre-configured testing setups for many different types a
44
44
  - **Dragonfly**: Latest server
45
45
  - **KeyDB**: Latest server
46
46
  - **Elasticsearch**: Version 7 and 8 are available
47
+ - **Azure blob storage**: Via azurite
47
48
 
48
49
  ## Contributing
49
50
 
@@ -1,6 +1,6 @@
1
1
  [build-system]
2
2
  build-backend = "hatchling.build"
3
- requires = ["hatchling", "hatch-pip-compile"]
3
+ requires = ["hatchling"]
4
4
 
5
5
  ####################
6
6
  # Project Metadata #
@@ -12,7 +12,7 @@ license = "MIT"
12
12
  name = "pytest-databases"
13
13
  readme = "README.md"
14
14
  requires-python = ">=3.8"
15
- version = "0.5.0"
15
+ version = "0.6.0"
16
16
  #
17
17
  authors = [{ name = "Cody Fincher", email = "cody.fincher@gmail.com" }]
18
18
  keywords = [
@@ -52,6 +52,7 @@ Issues = "https://github.com/litestar-org/pytest-databases/issues"
52
52
  Source = "https://github.com/litestar-org/pytest-databases"
53
53
 
54
54
  [project.optional-dependencies]
55
+ azure-storage = ["azure-storage-blob"]
55
56
  bigquery = ["google-cloud-bigquery"]
56
57
  cockroachdb = ["psycopg"]
57
58
  dragonfly = ["redis"]
@@ -80,14 +81,8 @@ exclude = ["/.github", "/docs"]
80
81
 
81
82
  # Default environment with production dependencies
82
83
  [tool.hatch.envs.default]
83
- lock-filename = "requirements/requirements.txt"
84
- pip-compile-constraint = "default"
85
- pip-compile-hashes = false
86
- pip-compile-installer = "uv"
87
- pip-compile-resolver = "uv"
88
- python = "3.11"
89
- requires = ["hatch-pip-compile"]
90
- type = "pip-compile"
84
+ installer = "uv"
85
+ python = "3.12"
91
86
 
92
87
  [tool.hatch.envs.default.scripts]
93
88
  upgrade-all = "PIP_COMPILE_UPGRADE=1 hatch env run --env {env_name} -- python --version"
@@ -119,6 +114,7 @@ features = [
119
114
  "elasticsearch7",
120
115
  "elasticsearch8",
121
116
  "bigquery",
117
+ "azure-storage",
122
118
  ]
123
119
  template = "default"
124
120
  type = "virtual"
@@ -178,11 +174,9 @@ features = [
178
174
  "elasticsearch8",
179
175
  "bigquery",
180
176
  ]
181
- lock-filename = "requirements/requirements-docs.txt"
182
- pip-compile-constraint = "default"
183
177
  python = "3.11"
184
- template = "test"
185
- type = "pip-compile"
178
+ template = "default"
179
+ type = "virtual"
186
180
 
187
181
  [tool.hatch.envs.docs.env-vars]
188
182
  PYTHONPATH = "."
@@ -250,12 +244,10 @@ features = [
250
244
  "elasticsearch8",
251
245
  "bigquery",
252
246
  ]
253
- lock-filename = "requirements/requirements-dev.txt"
254
247
  path = ".venv/"
255
- pip-compile-constraint = "docs"
256
248
  python = "3.11"
257
249
  template = "docs"
258
- type = "pip-compile"
250
+ type = "virtual"
259
251
 
260
252
 
261
253
  # Lint environment
@@ -291,6 +283,7 @@ features = [
291
283
  ]
292
284
  python = "3.11"
293
285
  template = "docs"
286
+ type = "virtual"
294
287
 
295
288
  [tool.hatch.envs.lint.scripts]
296
289
  check = ["style", "typing"]
@@ -596,7 +589,11 @@ line-length = 120
596
589
 
597
590
  [tool.pytest.ini_options]
598
591
  addopts = "--dist loadfile -n 2 -ra -q --doctest-glob='*.md'"
599
- filterwarnings = ["ignore::DeprecationWarning:pkg_resources", "ignore::DeprecationWarning:xdist.*"]
592
+ filterwarnings = [
593
+ "ignore::DeprecationWarning:pkg_resources",
594
+ "ignore::DeprecationWarning:xdist.*",
595
+ "ignore::DeprecationWarning:importlib._bootstrap",
596
+ ]
600
597
  markers = [
601
598
  "mysql: MySQL Tests",
602
599
  "postgres: Postgres Tests",
@@ -29,7 +29,7 @@ import re
29
29
  import subprocess # noqa: S404
30
30
  import sys
31
31
  import timeit
32
- from typing import TYPE_CHECKING, Any, Callable
32
+ from typing import TYPE_CHECKING, Any, Callable, Iterable
33
33
 
34
34
  import pytest
35
35
 
@@ -72,7 +72,12 @@ COMPOSE_PROJECT_NAME: str = f"pytest-databases-{simple_string_hash(__file__)}"
72
72
 
73
73
 
74
74
  class DockerServiceRegistry:
75
- def __init__(self, worker_id: str, compose_project_name: str = COMPOSE_PROJECT_NAME) -> None:
75
+ def __init__(
76
+ self,
77
+ worker_id: str,
78
+ compose_project_name: str = COMPOSE_PROJECT_NAME,
79
+ before_start: Iterable[Callable[[], Any]] | None = None,
80
+ ) -> None:
76
81
  self._running_services: set[str] = set()
77
82
  self.docker_ip = self._get_docker_ip()
78
83
  self._base_command = ["docker-compose"] if USE_LEGACY_DOCKER_COMPOSE else ["docker", "compose"]
@@ -82,6 +87,7 @@ class DockerServiceRegistry:
82
87
  f"--project-name={compose_project_name}-{worker_id}",
83
88
  ],
84
89
  )
90
+ self._before_start = list(before_start) if before_start else []
85
91
 
86
92
  @staticmethod
87
93
  def _get_docker_ip() -> str:
@@ -109,6 +115,9 @@ class DockerServiceRegistry:
109
115
  pause: float = 0.1,
110
116
  **kwargs: Any,
111
117
  ) -> None:
118
+ for before_start in self._before_start:
119
+ before_start()
120
+
112
121
  if SKIP_DOCKER_COMPOSE:
113
122
  self._running_services.add(name)
114
123
  if name not in self._running_services:
@@ -0,0 +1,187 @@
1
+ # MIT License
2
+
3
+ # Copyright (c) 2024 Litestar
4
+
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+
12
+ # The above copyright notice and this permission notice shall be included in all
13
+ # copies or substantial portions of the Software.
14
+
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ # SOFTWARE.
22
+ from __future__ import annotations
23
+
24
+ import json
25
+ import os
26
+ import secrets
27
+ import subprocess # noqa: S404
28
+ from pathlib import Path
29
+ from typing import AsyncGenerator, Generator
30
+
31
+ import pytest
32
+ from azure.storage.blob import ContainerClient
33
+ from azure.storage.blob.aio import ContainerClient as AsyncContainerClient
34
+
35
+ from pytest_databases.docker import DockerServiceRegistry
36
+ from pytest_databases.helpers import simple_string_hash
37
+
38
+ COMPOSE_PROJECT_NAME: str = f"pytest-databases-azure-blob-{simple_string_hash(__file__)}"
39
+
40
+
41
+ def _get_container_ids(compose_file_name: str) -> list[str]:
42
+ proc = subprocess.run(
43
+ [ # noqa: S607
44
+ "docker",
45
+ "container",
46
+ "ls",
47
+ f"--filter=label=com.docker.compose.project.config_files={compose_file_name}",
48
+ "--format=json",
49
+ ],
50
+ capture_output=True,
51
+ text=True,
52
+ check=True,
53
+ )
54
+ return [json.loads(line)["ID"] for line in proc.stdout.splitlines()]
55
+
56
+
57
+ def _get_container_logs(compose_file_name: str) -> str:
58
+ logs = ""
59
+ for container_id in _get_container_ids(compose_file_name):
60
+ stdout = subprocess.run(
61
+ ["docker", "logs", container_id], # noqa: S607
62
+ capture_output=True,
63
+ text=True,
64
+ check=True,
65
+ ).stdout
66
+ logs += stdout
67
+ return logs
68
+
69
+
70
+ @pytest.fixture(scope="session")
71
+ def azure_blob_compose_project_name() -> str:
72
+ return os.environ.get("COMPOSE_PROJECT_NAME", COMPOSE_PROJECT_NAME)
73
+
74
+
75
+ @pytest.fixture(scope="session")
76
+ def azure_blob_service_startup_delay() -> int:
77
+ return 1
78
+
79
+
80
+ @pytest.fixture(scope="session")
81
+ def azure_blob_docker_services(
82
+ azure_blob_compose_project_name: str,
83
+ azure_blob_service_startup_delay: int,
84
+ worker_id: str = "main",
85
+ ) -> Generator[DockerServiceRegistry, None, None]:
86
+ registry = DockerServiceRegistry(
87
+ worker_id,
88
+ compose_project_name=azure_blob_compose_project_name,
89
+ )
90
+ try:
91
+ yield registry
92
+ finally:
93
+ registry.down()
94
+
95
+
96
+ @pytest.fixture(scope="session")
97
+ def azure_blob_connection_string() -> str:
98
+ return "DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://127.0.0.1:10000/devstoreaccount1;"
99
+
100
+
101
+ @pytest.fixture(scope="session")
102
+ def azure_blob_account_name() -> str:
103
+ return "devstoreaccount1"
104
+
105
+
106
+ @pytest.fixture(scope="session")
107
+ def azure_blob_account_key() -> str:
108
+ return "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw=="
109
+
110
+
111
+ @pytest.fixture(scope="session")
112
+ def azure_blob_account_url() -> str:
113
+ return "http://127.0.0.1:10000/devstoreaccount1"
114
+
115
+
116
+ @pytest.fixture(scope="session")
117
+ def azure_blob_port() -> int:
118
+ return 10000
119
+
120
+
121
+ @pytest.fixture(scope="session")
122
+ def azure_blob_docker_compose_files() -> list[Path]:
123
+ return [Path(Path(__file__).parent / "docker-compose.azurite.yml")]
124
+
125
+
126
+ @pytest.fixture(scope="session")
127
+ def default_azure_blob_redis_service_name() -> str:
128
+ return "azurite"
129
+
130
+
131
+ @pytest.fixture(scope="session")
132
+ def azure_blob_docker_ip(azure_blob_docker_services: DockerServiceRegistry) -> str:
133
+ return azure_blob_docker_services.docker_ip
134
+
135
+
136
+ @pytest.fixture(scope="session")
137
+ def azure_blob_default_container_name() -> str:
138
+ return secrets.token_hex(4)
139
+
140
+
141
+ @pytest.fixture(scope="session")
142
+ def azure_blob_container_client(
143
+ azure_blob_connection_string: str,
144
+ azure_blob_default_container_name: str,
145
+ azure_blob_service: None,
146
+ ) -> Generator[ContainerClient, None, None]:
147
+ with ContainerClient.from_connection_string(
148
+ azure_blob_connection_string, container_name=azure_blob_default_container_name
149
+ ) as container_client:
150
+ yield container_client
151
+
152
+
153
+ @pytest.fixture(scope="session")
154
+ async def azure_blob_async_container_client(
155
+ azure_blob_connection_string: str, azure_blob_default_container_name: str
156
+ ) -> AsyncGenerator[AsyncContainerClient, None]:
157
+ async with AsyncContainerClient.from_connection_string(
158
+ azure_blob_connection_string, container_name=azure_blob_default_container_name
159
+ ) as container_client:
160
+ yield container_client
161
+
162
+
163
+ @pytest.fixture(autouse=False, scope="session")
164
+ async def azure_blob_service(
165
+ azure_blob_docker_services: DockerServiceRegistry,
166
+ default_azure_blob_redis_service_name: str,
167
+ azure_blob_docker_compose_files: list[Path],
168
+ azure_blob_connection_string: str,
169
+ azure_blob_port: int,
170
+ azure_blob_default_container_name: str,
171
+ ) -> AsyncGenerator[None, None]:
172
+ os.environ["AZURE_BLOB_PORT"] = str(azure_blob_port)
173
+
174
+ def azurite_responsive(host: str, port: int) -> bool:
175
+ # because azurite has a bug where it will hang for a long time if you make a
176
+ # request against it before it has completed startup we can't ping it, so we're
177
+ # inspecting the container logs instead
178
+ logs = _get_container_logs(str(azure_blob_docker_compose_files[0].absolute()))
179
+ return "Azurite Blob service successfully listens on" in logs
180
+
181
+ await azure_blob_docker_services.start(
182
+ name=default_azure_blob_redis_service_name,
183
+ docker_compose_files=azure_blob_docker_compose_files,
184
+ check=azurite_responsive,
185
+ port=azure_blob_port,
186
+ )
187
+ yield
@@ -0,0 +1,9 @@
1
+ version: "3.9"
2
+ services:
3
+ azurite:
4
+ image: mcr.microsoft.com/azure-storage/azurite
5
+ hostname: azurite
6
+ restart: always
7
+ command: "azurite-blob --blobHost 0.0.0.0 --blobPort 10000"
8
+ ports:
9
+ - "10000:10000"
@@ -0,0 +1,35 @@
1
+ # MIT License
2
+
3
+ # Copyright (c) 2024 Litestar
4
+
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+
12
+ # The above copyright notice and this permission notice shall be included in all
13
+ # copies or substantial portions of the Software.
14
+
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ # SOFTWARE.
22
+
23
+ import pytest
24
+ from azure.storage.blob import ContainerClient
25
+
26
+ pytestmark = pytest.mark.anyio
27
+
28
+
29
+ pytest_plugins = [
30
+ "pytest_databases.docker.azure_blob",
31
+ ]
32
+
33
+
34
+ async def test_azure_blob_service(azure_blob_container_client: ContainerClient) -> None:
35
+ assert not azure_blob_container_client.exists()