parent
c1164e8b8c
commit
13ccce5238
@ -0,0 +1,24 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
source scripts/gates/common.sh
|
||||
|
||||
# P17 Degraded Mode Gate
|
||||
# Verifies degraded mode blocking.
|
||||
|
||||
echo "=========================================================="
|
||||
echo "GATE: P17 Degraded Mode"
|
||||
echo "=========================================================="
|
||||
|
||||
echo "1. Verify Forced Degraded Mode (Integration)"
|
||||
# Uses tests/exchange/test_icicibreeze_integration_degraded.py
|
||||
# Matches "degraded_block"
|
||||
pytest -v tests/exchange/test_icicibreeze_integration_degraded.py
|
||||
echo " [+] Integration Verified"
|
||||
|
||||
echo "2. Verify Logic (Unit Tests)"
|
||||
pytest -v tests/test_degraded_mode_force_block.py tests/test_degraded_mode_auto_trigger.py
|
||||
echo " [+] Logic Verified"
|
||||
|
||||
echo "----------------------------------------------------------"
|
||||
echo "GATE P17-DegradedMode PASSED"
|
||||
echo "----------------------------------------------------------"
|
||||
@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
source scripts/gates/common.sh
|
||||
|
||||
# P17 Invalid Symbol Resilience Gate
|
||||
# Verifies system handles bad data gracefully.
|
||||
|
||||
echo "=========================================================="
|
||||
echo "GATE: P17 Invalid Symbol"
|
||||
echo "=========================================================="
|
||||
|
||||
echo "1. Verify Invalid Symbol Handling (Pytest)"
|
||||
pytest -v tests/exchange/test_icicibreeze_invalid_symbol.py
|
||||
echo " [+] Resilience Verified"
|
||||
|
||||
echo "----------------------------------------------------------"
|
||||
echo "GATE P17-InvalidSymbol PASSED"
|
||||
echo "----------------------------------------------------------"
|
||||
@ -0,0 +1,27 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
source scripts/gates/common.sh
|
||||
|
||||
# P17 Rate Limit Gate
|
||||
# Verifies that shim enforces rate limits in both sleep (default) and block modes.
|
||||
|
||||
echo "=========================================================="
|
||||
echo "GATE: P17 Rate Limiter"
|
||||
echo "=========================================================="
|
||||
|
||||
echo "1. Verify Block Mode (Pytest Integration w/ Env)"
|
||||
# Uses tests/exchange/test_icicibreeze_rate_limit_applied.py
|
||||
# Env vars set in the test fixture, but we can double check logic here if needed?
|
||||
# Actually the test file is self-contained. Is that enough?
|
||||
# Plan says: "Run pytest tests with specific failure expectations"
|
||||
# Our integration test file forces block mode.
|
||||
pytest -v tests/exchange/test_icicibreeze_rate_limit_applied.py
|
||||
echo " [+] Block Mode Verified"
|
||||
|
||||
echo "2. Verify Sleep Mode (Unit Test)"
|
||||
pytest -v tests/test_rate_limiter_sleep_mode.py
|
||||
echo " [+] Sleep Mode Verified"
|
||||
|
||||
echo "----------------------------------------------------------"
|
||||
echo "GATE P17-RateLimit PASSED"
|
||||
echo "----------------------------------------------------------"
|
||||
@ -0,0 +1,50 @@
|
||||
import pytest
|
||||
import os
|
||||
from unittest import mock
|
||||
from freqtrade.exceptions import OperationalException
|
||||
from adapters.ccxt_shim.breeze_ccxt import BreezeCCXT
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def exchange_for_resilience():
|
||||
exchange = BreezeCCXT()
|
||||
exchange.breeze = mock.Mock() # Mock session
|
||||
return exchange
|
||||
|
||||
|
||||
def test_fetch_ohlcv_invalid_symbol_raises_cleanly(exchange_for_resilience):
|
||||
# Mock _load_security_master to return empty master, so any symbol is not found
|
||||
with mock.patch.object(
|
||||
exchange_for_resilience,
|
||||
"_load_security_master",
|
||||
return_value={"nfo": {}, "nse": {"by_symbol": {}}},
|
||||
):
|
||||
# "INVALID/INR" -> Underlying=INVALID, Quote=INR -> CASH
|
||||
# Lookup INVALID in nse master -> None -> Raise "Cash symbol not found"
|
||||
with pytest.raises(OperationalException, match="Cash symbol not found"):
|
||||
exchange_for_resilience.fetch_ohlcv("INVALID/INR", "5m")
|
||||
|
||||
|
||||
def test_fetch_ohlcv_api_error_returns_empty(exchange_for_resilience):
|
||||
# Case 2: Breeze SDK returns Generic Exception
|
||||
symbol = "RELIANCE/INR"
|
||||
|
||||
# Mock master to find symbol
|
||||
mock_master = {"nse": {"by_symbol": {"RELIANCE": {"token": "123"}}}, "nfo": {}}
|
||||
|
||||
with mock.patch.object(
|
||||
exchange_for_resilience, "_load_security_master", return_value=mock_master
|
||||
):
|
||||
with mock.patch.object(
|
||||
exchange_for_resilience,
|
||||
"_parse_symbol",
|
||||
return_value={"stock_code": "REL", "exchange_code": "NSE", "product_type": "cash"},
|
||||
):
|
||||
# Mock Breeze SDK to raise Exception
|
||||
exchange_for_resilience.breeze.get_historical_data_v2.side_effect = Exception(
|
||||
"API Error"
|
||||
)
|
||||
|
||||
# Should NOT raise, but return empty list (resilience)
|
||||
res = exchange_for_resilience.fetch_ohlcv(symbol, "5m")
|
||||
assert res == []
|
||||
Loading…
Reference in new issue