Skip to content

Commit feb9b29

Browse files
authored
Fix for finalize stress test failing with timeout on AWS (#2097)
#### Reference Issues/PRs <!--Example: Fixes #1234. See also #3456.--> #### What does this implement or fix? The AWS storage operations are long consuming many times slower than LMDB. The goal is to have hundreds instead of thousands chunks for AWS. That will reduce both time and will still provide knowledge how finalizing behaves in slow environments https://github.com/man-group/ArcticDB/actions/runs/12548177307/job/34987768673 ------------------ generated xml file: /__w/_temp/pytest..xml ------------------ =========================== short test summary info ============================ FAILED tests/stress/arcticdb/version_store/test_stress_finalize_staged_data.py::test_finalize_monotonic_unique_chunks[real_s3-EncodingVersion.V1] - Failed: Timeout >3600.0s FAILED tests/stress/arcticdb/version_store/test_stress_finalize_staged_data.py::test_finalize_monotonic_unique_chunks[real_s3-EncodingVersion.V2] - Failed: Timeout >3600.0s ==== 2 failed, 75 passed, 1 skipped, 40006 warnings in 11455.91s (3:10:55) ===== #### Any other comments? #### Checklist <details> <summary> Checklist for code changes... </summary> - [ ] Have you updated the relevant docstrings, documentation and copyright notice? - [ ] Is this contribution tested against [all ArcticDB's features](../docs/mkdocs/docs/technical/contributing.md)? - [ ] Do all exceptions introduced raise appropriate [error messages](https://docs.arcticdb.io/error_messages/)? - [ ] Are API changes highlighted in the PR description? - [ ] Is the PR labelled as enhancement or bug so it appears in autogenerated release notes? </details> <!-- Thanks for contributing a Pull Request to ArcticDB! Please ensure you have taken a look at: - ArcticDB's Code of Conduct: https://github.com/man-group/ArcticDB/blob/master/CODE_OF_CONDUCT.md - ArcticDB's Contribution Licensing: https://github.com/man-group/ArcticDB/blob/master/docs/mkdocs/docs/technical/contributing.md#contribution-licensing --> --------- Co-authored-by: Georgi Rusev <Georgi Rusev>
1 parent 0d62ab1 commit feb9b29

File tree

2 files changed

+58
-37
lines changed

2 files changed

+58
-37
lines changed

python/tests/conftest.py

+36-30
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,10 @@
2424

2525
from arcticdb import LibraryOptions
2626
from arcticdb.storage_fixtures.api import StorageFixture
27-
from arcticdb.storage_fixtures.azure import AzuriteStorageFixtureFactory
27+
from arcticdb.storage_fixtures.azure import AzureContainer, AzuriteStorageFixtureFactory
2828
from arcticdb.storage_fixtures.lmdb import LmdbStorageFixture
2929
from arcticdb.storage_fixtures.s3 import (
30+
BaseS3StorageFixtureFactory,
3031
MotoS3StorageFixtureFactory,
3132
MotoNfsBackedS3StorageFixtureFactory,
3233
NfsS3Bucket,
@@ -75,7 +76,7 @@ def sym(request: pytest.FixtureRequest):
7576

7677

7778
@pytest.fixture()
78-
def lib_name(request: pytest.FixtureRequest):
79+
def lib_name(request: pytest.FixtureRequest) -> str:
7980
name = re.sub(r"[^\w]", "_", request.node.name)[:30]
8081
return f"{name}.{random.randint(0, 999)}_{datetime.utcnow().strftime('%Y-%m-%dT%H_%M_%S_%f')}"
8182

@@ -112,7 +113,7 @@ def pytest_generate_tests(metafunc):
112113
# endregion
113114
# region ======================================= Storage Fixtures =======================================
114115
@pytest.fixture
115-
def lmdb_storage(tmp_path) -> Iterator[LmdbStorageFixture]:
116+
def lmdb_storage(tmp_path) -> Generator[LmdbStorageFixture, None, None]:
116117
with LmdbStorageFixture(tmp_path) as f:
117118
yield f
118119

@@ -137,64 +138,64 @@ def lmdb_library_static_dynamic(request):
137138

138139
# ssl is enabled by default to maximize test coverage as ssl is enabled most of the times in real world
139140
@pytest.fixture(scope="session")
140-
def s3_storage_factory() -> Iterator[MotoS3StorageFixtureFactory]:
141+
def s3_storage_factory() -> Generator[MotoS3StorageFixtureFactory, None, None]:
141142
with MotoS3StorageFixtureFactory(
142143
use_ssl=SSL_TEST_SUPPORTED, ssl_test_support=SSL_TEST_SUPPORTED, bucket_versioning=False
143144
) as f:
144145
yield f
145146

146147

147148
@pytest.fixture(scope="session")
148-
def s3_no_ssl_storage_factory() -> Iterator[MotoS3StorageFixtureFactory]:
149+
def s3_no_ssl_storage_factory() -> Generator[MotoS3StorageFixtureFactory, None, None]:
149150
with MotoS3StorageFixtureFactory(use_ssl=False, ssl_test_support=SSL_TEST_SUPPORTED, bucket_versioning=False) as f:
150151
yield f
151152

152153

153154
@pytest.fixture(scope="session")
154-
def s3_ssl_disabled_storage_factory() -> Iterator[MotoS3StorageFixtureFactory]:
155+
def s3_ssl_disabled_storage_factory() -> Generator[MotoS3StorageFixtureFactory, None, None]:
155156
with MotoS3StorageFixtureFactory(use_ssl=False, ssl_test_support=False, bucket_versioning=False) as f:
156157
yield f
157158

158159

159160
@pytest.fixture(scope="session")
160-
def s3_bucket_versioning_storage_factory() -> Iterator[MotoS3StorageFixtureFactory]:
161+
def s3_bucket_versioning_storage_factory() -> Generator[MotoS3StorageFixtureFactory, None, None]:
161162
with MotoS3StorageFixtureFactory(use_ssl=False, ssl_test_support=False, bucket_versioning=True) as f:
162163
yield f
163164

164165

165166
@pytest.fixture(scope="session")
166-
def nfs_backed_s3_storage_factory() -> Iterator[MotoNfsBackedS3StorageFixtureFactory]:
167+
def nfs_backed_s3_storage_factory() -> Generator[MotoNfsBackedS3StorageFixtureFactory, None, None]:
167168
with MotoNfsBackedS3StorageFixtureFactory(use_ssl=False, ssl_test_support=False, bucket_versioning=False) as f:
168169
yield f
169170

170171

171172
@pytest.fixture
172-
def s3_storage(s3_storage_factory) -> Iterator[S3Bucket]:
173+
def s3_storage(s3_storage_factory) -> Generator[S3Bucket, None, None]:
173174
with s3_storage_factory.create_fixture() as f:
174175
yield f
175176

176177

177178
@pytest.fixture
178-
def nfs_backed_s3_storage(nfs_backed_s3_storage_factory) -> Iterator[NfsS3Bucket]:
179+
def nfs_backed_s3_storage(nfs_backed_s3_storage_factory) -> Generator[NfsS3Bucket, None, None]:
179180
with nfs_backed_s3_storage_factory.create_fixture() as f:
180181
yield f
181182

182183

183184
@pytest.fixture
184-
def s3_no_ssl_storage(s3_no_ssl_storage_factory) -> Iterator[S3Bucket]:
185+
def s3_no_ssl_storage(s3_no_ssl_storage_factory) -> Generator[S3Bucket, None, None]:
185186
with s3_no_ssl_storage_factory.create_fixture() as f:
186187
yield f
187188

188189

189190
@pytest.fixture
190-
def s3_ssl_disabled_storage(s3_ssl_disabled_storage_factory) -> Iterator[S3Bucket]:
191+
def s3_ssl_disabled_storage(s3_ssl_disabled_storage_factory) -> Generator[S3Bucket, None, None]:
191192
with s3_ssl_disabled_storage_factory.create_fixture() as f:
192193
yield f
193194

194195

195196
# s3 storage is picked just for its versioning capabilities for verifying arcticdb atomicity
196197
@pytest.fixture
197-
def s3_bucket_versioning_storage(s3_bucket_versioning_storage_factory) -> Iterator[S3Bucket]:
198+
def s3_bucket_versioning_storage(s3_bucket_versioning_storage_factory) -> Generator[S3Bucket, None, None]:
198199
with s3_bucket_versioning_storage_factory.create_fixture() as f:
199200
s3_admin = f.factory._s3_admin
200201
bucket = f.bucket
@@ -214,26 +215,31 @@ def mock_s3_storage_with_error_simulation(mock_s3_storage_with_error_simulation_
214215

215216

216217
@pytest.fixture(scope="session")
217-
def real_s3_storage_factory():
218+
def real_s3_storage_factory() -> BaseS3StorageFixtureFactory:
218219
return real_s3_from_environment_variables(shared_path=False, additional_suffix=f"{random.randint(0, 999)}_{datetime.utcnow().strftime('%Y-%m-%dT%H_%M_%S_%f')}")
219220

220221

221222
@pytest.fixture(scope="session")
222-
def real_s3_shared_path_storage_factory():
223+
def real_s3_shared_path_storage_factory() -> BaseS3StorageFixtureFactory:
223224
return real_s3_from_environment_variables(shared_path=True, additional_suffix=f"{random.randint(0, 999)}_{datetime.utcnow().strftime('%Y-%m-%dT%H_%M_%S_%f')}")
224225

225226

226227
@pytest.fixture(scope="session")
227-
def real_s3_storage_without_clean_up(real_s3_shared_path_storage_factory):
228+
def real_s3_storage_without_clean_up(real_s3_shared_path_storage_factory) -> S3Bucket:
228229
return real_s3_shared_path_storage_factory.create_fixture()
229230

230231

231232
@pytest.fixture
232-
def real_s3_storage(real_s3_storage_factory):
233+
def real_s3_storage(real_s3_storage_factory) -> Generator[S3Bucket, None, None]:
233234
with real_s3_storage_factory.create_fixture() as f:
234235
yield f
235236

236237

238+
@pytest.fixture
239+
def real_s3_library(real_s3_storage, lib_name) -> Library:
240+
return real_s3_storage.create_arctic().create_library(lib_name)
241+
242+
237243
@pytest.fixture(scope="session") # Config loaded at the first ArcticDB binary import, so we need to set it up before any tests
238244
def real_s3_sts_storage_factory():
239245
sts_test_credentials_prefix = os.getenv("ARCTICDB_REAL_S3_STS_TEST_CREDENTIALS_POSTFIX", f"{random.randint(0, 999)}_{datetime.utcnow().strftime('%Y-%m-%dT%H_%M_%S_%f')}")
@@ -258,32 +264,32 @@ def real_s3_sts_storage_factory():
258264

259265

260266
@pytest.fixture
261-
def real_s3_sts_storage(real_s3_sts_storage_factory):
267+
def real_s3_sts_storage(real_s3_sts_storage_factory) -> Generator[BaseS3StorageFixtureFactory, None, None]:
262268
with real_s3_sts_storage_factory.create_fixture() as f:
263269
yield f
264270

265271

266272
# ssl cannot be ON by default due to azurite performance constraints https://github.com/man-group/ArcticDB/issues/1539
267273
@pytest.fixture(scope="session")
268-
def azurite_storage_factory():
274+
def azurite_storage_factory() -> Generator[AzuriteStorageFixtureFactory, None, None]:
269275
with AzuriteStorageFixtureFactory(use_ssl=False, ssl_test_support=SSL_TEST_SUPPORTED) as f:
270276
yield f
271277

272278

273279
@pytest.fixture
274-
def azurite_storage(azurite_storage_factory: AzuriteStorageFixtureFactory):
280+
def azurite_storage(azurite_storage_factory: AzuriteStorageFixtureFactory) -> Generator[AzureContainer, None, None]:
275281
with azurite_storage_factory.create_fixture() as f:
276282
yield f
277283

278284

279285
@pytest.fixture(scope="session")
280-
def azurite_ssl_storage_factory():
286+
def azurite_ssl_storage_factory() -> Generator[AzuriteStorageFixtureFactory, None, None]:
281287
with AzuriteStorageFixtureFactory(use_ssl=True, ssl_test_support=SSL_TEST_SUPPORTED) as f:
282288
yield f
283289

284290

285291
@pytest.fixture
286-
def azurite_ssl_storage(azurite_ssl_storage_factory: AzuriteStorageFixtureFactory):
292+
def azurite_ssl_storage(azurite_ssl_storage_factory: AzuriteStorageFixtureFactory) -> Generator[AzureContainer, None, None]:
287293
with azurite_ssl_storage_factory.create_fixture() as f:
288294
yield f
289295

@@ -301,7 +307,7 @@ def mongo_storage(mongo_server):
301307

302308

303309
@pytest.fixture
304-
def mem_storage() -> Iterator[InMemoryStorageFixture]:
310+
def mem_storage() -> Generator[InMemoryStorageFixture, None, None]:
305311
with InMemoryStorageFixture() as f:
306312
yield f
307313

@@ -357,12 +363,12 @@ def arctic_client_lmdb(request, encoding_version) -> Arctic:
357363

358364

359365
@pytest.fixture
360-
def arctic_library(arctic_client, lib_name) -> Arctic:
366+
def arctic_library(arctic_client, lib_name) -> Library:
361367
return arctic_client.create_library(lib_name)
362368

363369

364370
@pytest.fixture
365-
def arctic_library_lmdb(arctic_client_lmdb, lib_name):
371+
def arctic_library_lmdb(arctic_client_lmdb, lib_name) -> Library:
366372
return arctic_client_lmdb.create_library(lib_name)
367373

368374

@@ -418,17 +424,17 @@ def s3_store_factory_mock_storage_exception(lib_name, s3_storage):
418424

419425

420426
@pytest.fixture
421-
def s3_store_factory(lib_name, s3_storage):
427+
def s3_store_factory(lib_name, s3_storage) -> NativeVersionStore:
422428
return s3_storage.create_version_store_factory(lib_name)
423429

424430

425431
@pytest.fixture
426-
def s3_no_ssl_store_factory(lib_name, s3_no_ssl_storage):
432+
def s3_no_ssl_store_factory(lib_name, s3_no_ssl_storage) -> NativeVersionStore:
427433
return s3_no_ssl_storage.create_version_store_factory(lib_name)
428434

429435

430436
@pytest.fixture
431-
def mock_s3_store_with_error_simulation_factory(lib_name, mock_s3_storage_with_error_simulation):
437+
def mock_s3_store_with_error_simulation_factory(lib_name, mock_s3_storage_with_error_simulation) -> NativeVersionStore:
432438
return mock_s3_storage_with_error_simulation.create_version_store_factory(lib_name)
433439

434440

@@ -438,12 +444,12 @@ def real_s3_store_factory(lib_name, real_s3_storage) -> Callable[..., NativeVers
438444

439445

440446
@pytest.fixture
441-
def real_s3_sts_store_factory(lib_name, real_s3_sts_storage):
447+
def real_s3_sts_store_factory(lib_name, real_s3_sts_storage) -> NativeVersionStore:
442448
return real_s3_sts_storage.create_version_store_factory(lib_name)
443449

444450

445451
@pytest.fixture
446-
def azure_store_factory(lib_name, azurite_storage):
452+
def azure_store_factory(lib_name, azurite_storage) -> NativeVersionStore:
447453
return azurite_storage.create_version_store_factory(lib_name)
448454

449455

python/tests/stress/arcticdb/version_store/test_stress_finalize_staged_data.py

+22-7
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
from arcticdb.util.utils import CachedDFGenerator, TimestampNumber, stage_chunks
2121

2222

23-
from tests.util.mark import SKIP_CONDA_MARK, SLOW_TESTS_MARK
23+
from tests.util.mark import REAL_S3_TESTS_MARK, SKIP_CONDA_MARK, SLOW_TESTS_MARK
2424

2525
# Uncomment for logging
2626
# set_log_level(default_level="DEBUG", console_output=False, file_output_path="/tmp/arcticdb.log")
@@ -40,10 +40,10 @@ def __init__(self):
4040
def __str__(self):
4141
return f"Options: {self.options}\nIteration: {self.iteration}\n# staged chunks: {self.number_staged_chunks}\ntotal rows finalized: {self.total_rows_finalized}\ntime for finalization (s): {self.finalization_time}"
4242

43-
@SLOW_TESTS_MARK
44-
@SKIP_CONDA_MARK # Conda CI runner doesn't have enough storage to perform these stress tests
45-
@pytest.mark.skipif(sys.platform == "win32", reason="Not enough storage on Windows runners")
46-
def test_finalize_monotonic_unique_chunks(basic_arctic_library):
43+
44+
45+
46+
def finalize_monotonic_unique_chunks(ac_library, iterations):
4747
"""
4848
The test is designed to staged thousands of chunks with variable chunk size.
4949
To experiment on local computer you can move up to 20k number of chunks approx 10k each
@@ -65,7 +65,7 @@ def test_finalize_monotonic_unique_chunks(basic_arctic_library):
6565
# Will hold the results after each iteration (instance of Results class)
6666
results = []
6767

68-
lib : Library = basic_arctic_library
68+
lib : Library = ac_library
6969

7070
total_start_time = time.time()
7171

@@ -86,7 +86,7 @@ def test_finalize_monotonic_unique_chunks(basic_arctic_library):
8686
df = cachedDF.generate_dataframe_timestamp_indexed(num_rows_initially, total_number_rows, cachedDF.TIME_UNIT)
8787

8888
cnt = 0
89-
for iter in [500, 1000, 1500, 2000] :
89+
for iter in iterations :
9090
res = Results()
9191

9292
total_number_rows = INITIAL_TIMESTAMP + num_rows_initially
@@ -138,3 +138,18 @@ def test_finalize_monotonic_unique_chunks(basic_arctic_library):
138138
print("TOTAL TIME: ", total_time)
139139

140140

141+
@SLOW_TESTS_MARK
142+
@SKIP_CONDA_MARK # Conda CI runner doesn't have enough storage to perform these stress tests
143+
@pytest.mark.skipif(sys.platform == "win32", reason="Not enough storage on Windows runners")
144+
def test_finalize_monotonic_unique_chunks_lmdb(lmdb_library):
145+
finalize_monotonic_unique_chunks(lmdb_library, [500, 1000, 1500, 2000])
146+
147+
148+
@SLOW_TESTS_MARK
149+
@SKIP_CONDA_MARK # Conda CI runner doesn't have enough storage to perform these stress tests
150+
@pytest.mark.skipif(sys.platform == "win32", reason="Not enough storage on Windows runners")
151+
@REAL_S3_TESTS_MARK
152+
def test_finalize_monotonic_unique_chunks_realS3(real_s3_library):
153+
finalize_monotonic_unique_chunks(real_s3_library, [50, 100, 150, 200])
154+
155+

0 commit comments

Comments
 (0)