| """Integration tests for DataBus provider chains. |
| |
| Tests cache layers, circuit breakers, provider fallbacks. |
| Uses mocked external APIs to avoid real API calls. |
| """ |
|
|
| import pytest |
|
|
|
|
| class TestDataBusCache: |
| """Test L1 (memory) and L2 (Redis) cache layers.""" |
|
|
| @pytest.mark.integration |
| async def test_l1_cache_hit_returns_data(self): |
| """L1 memory cache should return cached data on second fetch.""" |
| pass |
|
|
| @pytest.mark.integration |
| async def test_l2_redis_fallback_on_l1_miss(self): |
| """L2 Redis should serve when L1 misses.""" |
| pass |
|
|
| @pytest.mark.integration |
| async def test_stale_while_revalidate_returns_stale(self): |
| """SWR should return stale data while refreshing in background.""" |
| pass |
|
|
|
|
| class TestCircuitBreakers: |
| """Test provider circuit breakers β 3 failures β open β half-open β closed.""" |
|
|
| @pytest.mark.integration |
| async def test_circuit_opens_after_three_failures(self): |
| """Circuit should open after 3 consecutive provider failures.""" |
| pass |
|
|
| @pytest.mark.integration |
| async def test_half_open_allows_one_probe(self): |
| """After timeout, half-open state should allow one probe request.""" |
| pass |
|
|
| @pytest.mark.integration |
| async def test_closed_after_successful_probe(self): |
| """Successful probe in half-open should close the circuit.""" |
| pass |
|
|
|
|
| class TestProviderFallback: |
| """Test provider chain fallback β first fails, second succeeds.""" |
|
|
| @pytest.mark.integration |
| async def test_fallback_to_secondary_provider(self): |
| """When primary fails, secondary provider should be tried.""" |
| pass |
|
|
| @pytest.mark.integration |
| async def test_all_providers_fail_returns_none(self): |
| """When all providers fail, databus should return None.""" |
| pass |
|
|
|
|
| class TestDataBusSmoke: |
| """Smoke tests for all 78 DataBus provider chains.""" |
|
|
| CHAINS = [ |
| "token_price", |
| "market_overview", |
| "trending", |
| "fear_greed", |
| "wallet_labels", |
| "entity_intel", |
| "scanner", |
| "rag_search", |
| "wallet_tokens", |
| "token_metadata", |
| "token_security", |
| ] |
|
|
| @pytest.mark.integration |
| @pytest.mark.parametrize("chain", CHAINS) |
| async def test_chain_exists_in_providers(self, chain): |
| """Every chain should exist in build_provider_chains().""" |
| from app.databus.providers import build_provider_chains |
|
|
| chains = build_provider_chains() |
| assert chain in chains, f"Chain '{chain}' missing from provider chains" |
|
|