@@ -299,3 +299,95 @@ def successful_func():
299299
300300 # Circuit breaker should be closed again (or at least not open)
301301 assert breaker .current_state in ["closed" , "half-open" ]
302+
303+ def test_circuit_breaker_state_listener_half_open (self ):
304+ """Test circuit breaker state listener logs half-open state."""
305+ from databricks .sql .telemetry .circuit_breaker_manager import CircuitBreakerStateListener , CIRCUIT_BREAKER_STATE_HALF_OPEN
306+ from unittest .mock import patch
307+
308+ listener = CircuitBreakerStateListener ()
309+
310+ # Mock circuit breaker with half-open state
311+ mock_cb = Mock ()
312+ mock_cb .name = "test-breaker"
313+
314+ # Mock old and new states
315+ mock_old_state = Mock ()
316+ mock_old_state .name = "open"
317+
318+ mock_new_state = Mock ()
319+ mock_new_state .name = CIRCUIT_BREAKER_STATE_HALF_OPEN
320+
321+ with patch ('databricks.sql.telemetry.circuit_breaker_manager.logger' ) as mock_logger :
322+ listener .state_change (mock_cb , mock_old_state , mock_new_state )
323+
324+ # Check that half-open state was logged
325+ mock_logger .info .assert_called ()
326+ calls = mock_logger .info .call_args_list
327+ half_open_logged = any ("half-open" in str (call ) for call in calls )
328+ assert half_open_logged
329+
330+ def test_circuit_breaker_state_listener_all_states (self ):
331+ """Test circuit breaker state listener logs all possible state transitions."""
332+ from databricks .sql .telemetry .circuit_breaker_manager import CircuitBreakerStateListener , CIRCUIT_BREAKER_STATE_HALF_OPEN , CIRCUIT_BREAKER_STATE_OPEN , CIRCUIT_BREAKER_STATE_CLOSED
333+ from unittest .mock import patch
334+
335+ listener = CircuitBreakerStateListener ()
336+ mock_cb = Mock ()
337+ mock_cb .name = "test-breaker"
338+
339+ # Test all state transitions with exact constants
340+ state_transitions = [
341+ (CIRCUIT_BREAKER_STATE_CLOSED , CIRCUIT_BREAKER_STATE_OPEN ),
342+ (CIRCUIT_BREAKER_STATE_OPEN , CIRCUIT_BREAKER_STATE_HALF_OPEN ),
343+ (CIRCUIT_BREAKER_STATE_HALF_OPEN , CIRCUIT_BREAKER_STATE_CLOSED ),
344+ (CIRCUIT_BREAKER_STATE_CLOSED , CIRCUIT_BREAKER_STATE_HALF_OPEN ),
345+ ]
346+
347+ with patch ('databricks.sql.telemetry.circuit_breaker_manager.logger' ) as mock_logger :
348+ for old_state_name , new_state_name in state_transitions :
349+ mock_old_state = Mock ()
350+ mock_old_state .name = old_state_name
351+
352+ mock_new_state = Mock ()
353+ mock_new_state .name = new_state_name
354+
355+ listener .state_change (mock_cb , mock_old_state , mock_new_state )
356+
357+ # Verify that logging was called for each transition
358+ assert mock_logger .info .call_count >= len (state_transitions )
359+
360+ def test_create_circuit_breaker_not_initialized (self ):
361+ """Test that _create_circuit_breaker raises RuntimeError when not initialized."""
362+ # Clear any existing config
363+ CircuitBreakerManager ._config = None
364+
365+ with pytest .raises (RuntimeError , match = "CircuitBreakerManager not initialized" ):
366+ CircuitBreakerManager ._create_circuit_breaker ("test-host" )
367+
368+ def test_get_circuit_breaker_state_not_initialized (self ):
369+ """Test get_circuit_breaker_state when host is not in instances."""
370+ config = CircuitBreakerConfig ()
371+ CircuitBreakerManager .initialize (config )
372+
373+ # Test with a host that doesn't exist in instances
374+ state = CircuitBreakerManager .get_circuit_breaker_state ("nonexistent-host" )
375+ assert state == "not_initialized"
376+
377+ def test_reset_circuit_breaker_nonexistent_host (self ):
378+ """Test reset_circuit_breaker when host doesn't exist in instances."""
379+ config = CircuitBreakerConfig ()
380+ CircuitBreakerManager .initialize (config )
381+
382+ # Reset a host that doesn't exist - should not raise an error
383+ CircuitBreakerManager .reset_circuit_breaker ("nonexistent-host" )
384+ # No assertion needed - just ensuring no exception is raised
385+
386+ def test_clear_circuit_breaker_nonexistent_host (self ):
387+ """Test clear_circuit_breaker when host doesn't exist in instances."""
388+ config = CircuitBreakerConfig ()
389+ CircuitBreakerManager .initialize (config )
390+
391+ # Clear a host that doesn't exist - should not raise an error
392+ CircuitBreakerManager .clear_circuit_breaker ("nonexistent-host" )
393+ # No assertion needed - just ensuring no exception is raised
0 commit comments