@@ -68,71 +68,54 @@ def test_request_enabled_success(self):
6868 self .mock_delegate .request .assert_called_once ()
6969
7070 def test_request_enabled_circuit_breaker_error (self ):
71- """Test request when circuit breaker is open - should return mock response ."""
71+ """Test request when circuit breaker is open - should raise CircuitBreakerError ."""
7272 # Mock circuit breaker to raise CircuitBreakerError
7373 with patch .object (
7474 self .client ._circuit_breaker ,
7575 "call" ,
7676 side_effect = CircuitBreakerError ("Circuit is open" ),
7777 ):
78- # Circuit breaker open should return mock response, not raise
79- response = self .client .request (HttpMethod .POST , "https://test.com" , {})
80- # Should get a mock success response
81- assert response is not None
82- assert response .status == 200
83- assert b"numProtoSuccess" in response .data
78+ # Circuit breaker open should raise (caller handles it)
79+ with pytest .raises (CircuitBreakerError ):
80+ self .client .request (HttpMethod .POST , "https://test.com" , {})
8481
8582 def test_request_enabled_other_error (self ):
86- """Test request when other error occurs - should return mock response ."""
83+ """Test request when other error occurs - should raise original exception ."""
8784 # Mock delegate to raise a different error (not rate limiting)
8885 self .mock_delegate .request .side_effect = ValueError ("Network error" )
8986
90- # Non-rate-limit errors return mock success response
91- response = self .client .request (HttpMethod .POST , "https://test.com" , {})
92- assert response is not None
93- assert response .status == 200
94- assert b"numProtoSuccess" in response .data
87+ # Non-rate-limit errors are unwrapped and raised
88+ with pytest .raises (ValueError , match = "Network error" ):
89+ self .client .request (HttpMethod .POST , "https://test.com" , {})
9590
9691 def test_is_circuit_breaker_enabled (self ):
9792 """Test checking if circuit breaker is enabled."""
9893 assert self .client ._circuit_breaker is not None
9994
10095 def test_circuit_breaker_state_logging (self ):
101- """Test that circuit breaker state changes are logged."""
102- with patch (
103- "databricks.sql.telemetry.telemetry_push_client.logger"
104- ) as mock_logger :
105- with patch .object (
106- self .client ._circuit_breaker ,
107- "call" ,
108- side_effect = CircuitBreakerError ("Circuit is open" ),
109- ):
110- # Should return mock response, not raise
111- response = self .client .request (HttpMethod .POST , "https://test.com" , {})
112- assert response is not None
113-
114- # Check that debug was logged (not warning - telemetry silently drops)
115- mock_logger .debug .assert_called ()
116- debug_call = mock_logger .debug .call_args [0 ]
117- assert "Circuit breaker is open" in debug_call [0 ]
118- assert self .host in debug_call [1 ]
96+ """Test that circuit breaker errors are raised (no longer silent)."""
97+ with patch .object (
98+ self .client ._circuit_breaker ,
99+ "call" ,
100+ side_effect = CircuitBreakerError ("Circuit is open" ),
101+ ):
102+ # Should raise CircuitBreakerError (caller handles it)
103+ with pytest .raises (CircuitBreakerError ):
104+ self .client .request (HttpMethod .POST , "https://test.com" , {})
119105
120106 def test_other_error_logging (self ):
121- """Test that other errors are logged appropriately ."""
107+ """Test that other errors are wrapped, logged, then unwrapped and raised ."""
122108 with patch (
123109 "databricks.sql.telemetry.telemetry_push_client.logger"
124110 ) as mock_logger :
125111 self .mock_delegate .request .side_effect = ValueError ("Network error" )
126112
127- # Should return mock response, not raise
128- response = self . client . request ( HttpMethod . POST , "https://test.com" , {})
129- assert response is not None
113+ # Should raise the original ValueError
114+ with pytest . raises ( ValueError , match = "Network error" ):
115+ self . client . request ( HttpMethod . POST , "https://test.com" , {})
130116
131- # Check that debug was logged
132- mock_logger .debug .assert_called ()
133- debug_call = mock_logger .debug .call_args [0 ]
134- assert "failing silently" in debug_call [0 ]
135- assert self .host in debug_call [1 ]
117+ # Check that debug was logged (for wrapping and/or unwrapping)
118+ assert mock_logger .debug .call_count >= 1
136119
137120
138121class TestCircuitBreakerTelemetryPushClientIntegration :
@@ -161,16 +144,22 @@ def test_circuit_breaker_opens_after_failures(self):
161144 mock_response .status = 429
162145 self .mock_delegate .request .return_value = mock_response
163146
164- # All calls should return mock success (circuit breaker handles it internally)
165- mock_response_count = 0
147+ # All calls should raise TelemetryRateLimitError
148+ # After MINIMUM_CALLS failures, circuit breaker opens
149+ rate_limit_error_count = 0
150+ circuit_breaker_error_count = 0
151+
166152 for i in range (MINIMUM_CALLS + 5 ):
167- response = client .request (HttpMethod .POST , "https://test.com" , {})
168- # Always get mock response (circuit breaker prevents re-raising)
169- assert response .status == 200
170- mock_response_count += 1
153+ try :
154+ client .request (HttpMethod .POST , "https://test.com" , {})
155+ except TelemetryRateLimitError :
156+ rate_limit_error_count += 1
157+ except CircuitBreakerError :
158+ circuit_breaker_error_count += 1
171159
172- # All should return mock responses (telemetry fails silently)
173- assert mock_response_count == MINIMUM_CALLS + 5
160+ # Should have some rate limit errors before circuit opens, then circuit breaker errors
161+ assert rate_limit_error_count >= MINIMUM_CALLS - 1
162+ assert circuit_breaker_error_count > 0
174163
175164 def test_circuit_breaker_recovers_after_success (self ):
176165 """Test that circuit breaker recovers after successful calls."""
@@ -187,21 +176,23 @@ def test_circuit_breaker_recovers_after_success(self):
187176 client = CircuitBreakerTelemetryPushClient (self .mock_delegate , self .host )
188177
189178 # Simulate rate limit failures first (429)
179+ from databricks .sql .exc import TelemetryRateLimitError
180+ from pybreaker import CircuitBreakerError
181+
190182 mock_rate_limit_response = Mock ()
191183 mock_rate_limit_response .status = 429
192184 self .mock_delegate .request .return_value = mock_rate_limit_response
193185
194186 # Trigger enough rate limit failures to open circuit
195187 for i in range (MINIMUM_CALLS + 5 ):
196- response = client .request (HttpMethod .POST , "https://test.com" , {})
197- assert response .status == 200 # Returns mock success
198- assert b"numProtoSuccess" in response .data
199-
200- # Circuit should be open now - still returns mock response
201- response = client .request (HttpMethod .POST , "https://test.com" , {})
202- assert response is not None
203- assert response .status == 200 # Mock success response
204- assert b"numProtoSuccess" in response .data
188+ try :
189+ client .request (HttpMethod .POST , "https://test.com" , {})
190+ except (TelemetryRateLimitError , CircuitBreakerError ):
191+ pass # Expected - circuit breaker opens after MINIMUM_CALLS failures
192+
193+ # Circuit should be open now - raises CircuitBreakerError
194+ with pytest .raises (CircuitBreakerError ):
195+ client .request (HttpMethod .POST , "https://test.com" , {})
205196
206197 # Wait for reset timeout
207198 time .sleep (RESET_TIMEOUT + 1.0 )
0 commit comments