77These tests download real data from HuggingFace and GitHub, are slow, and are
88subject to transient network failures. They are intended to run daily in e2e CI,
99not on every PR.
10+
11+ Resiliency: each fetch is retried up to 3 times with exponential backoff to
12+ handle transient HuggingFace / GitHub rate-limiting and network errors.
1013"""
1114
1215import logging
1316
1417import pytest
18+ from tenacity import retry , retry_if_exception_type , stop_after_attempt , wait_exponential
1519
1620from pyrit .datasets import SeedDatasetProvider
1721from pyrit .datasets .seed_datasets .remote import _VLSUMultimodalDataset
1822from pyrit .models import SeedDataset
1923
2024logger = logging .getLogger (__name__ )
2125
26+ # Per-test timeout in seconds (5 minutes per dataset)
27+ _TEST_TIMEOUT = 300
28+
29+ # Transient error types that warrant a retry
30+ _RETRYABLE_ERRORS = (OSError , ConnectionError , TimeoutError )
31+
2232
2333def get_dataset_providers ():
2434 """Helper to get all registered providers for parameterization."""
2535 providers = SeedDatasetProvider .get_all_providers ()
2636 return [(name , cls ) for name , cls in providers .items ()]
2737
2838
39+ @retry (
40+ stop = stop_after_attempt (3 ),
41+ wait = wait_exponential (multiplier = 5 , min = 5 , max = 60 ),
42+ retry = retry_if_exception_type (_RETRYABLE_ERRORS ),
43+ reraise = True ,
44+ )
45+ async def _fetch_with_retry (provider ) -> SeedDataset :
46+ """Fetch a dataset with retry on transient network errors."""
47+ return await provider .fetch_dataset (cache = False )
48+
49+
2950class TestAllDatasets :
3051 """Exhaustive test that every registered dataset provider can be fetched."""
3152
3253 @pytest .mark .asyncio
54+ @pytest .mark .timeout (_TEST_TIMEOUT )
3355 @pytest .mark .parametrize ("name,provider_cls" , get_dataset_providers ())
3456 async def test_fetch_dataset (self , name , provider_cls ):
3557 """
@@ -40,13 +62,15 @@ async def test_fetch_dataset(self, name, provider_cls):
4062 1. The dataset can be downloaded/loaded without error
4163 2. The result is a SeedDataset
4264 3. The dataset is not empty (has seeds)
65+
66+ Retries up to 3 times on transient network errors.
4367 """
4468 logger .info (f"Testing provider: { name } " )
4569
4670 try :
4771 # Use max_examples for slow providers that fetch many remote images
4872 provider = provider_cls (max_examples = 6 ) if provider_cls == _VLSUMultimodalDataset else provider_cls ()
49- dataset = await provider . fetch_dataset ( cache = False )
73+ dataset = await _fetch_with_retry ( provider )
5074
5175 assert isinstance (dataset , SeedDataset ), f"{ name } did not return a SeedDataset"
5276 assert len (dataset .seeds ) > 0 , f"{ name } returned an empty dataset"
0 commit comments