Skip to content

Commit f33964a

Browse files
committed
netapp routes: test unhappy path
1 parent 1f5c89f commit f33964a

File tree

3 files changed

+623
-0
lines changed

3 files changed

+623
-0
lines changed

python/understack-workflows/tests/test_netapp_client.py

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
from understack_workflows.netapp.value_objects import NodeResult
2222
from understack_workflows.netapp.value_objects import PortResult
2323
from understack_workflows.netapp.value_objects import PortSpec
24+
from understack_workflows.netapp.value_objects import RouteSpec
2425
from understack_workflows.netapp.value_objects import SvmResult
2526
from understack_workflows.netapp.value_objects import SvmSpec
2627
from understack_workflows.netapp.value_objects import VolumeResult
@@ -521,6 +522,180 @@ def test_get_namespaces_failure(
521522
with pytest.raises(NetAppManagerError):
522523
netapp_client.get_namespaces(namespace_spec)
523524

525+
@patch("understack_workflows.netapp.client.NetworkRoute")
526+
def test_create_route_success(self, mock_route_class, netapp_client):
527+
"""Test successful route creation."""
528+
mock_route_instance = MagicMock()
529+
mock_route_instance.uuid = "route-uuid-123"
530+
mock_route_class.return_value = mock_route_instance
531+
532+
route_spec = RouteSpec(
533+
svm_name="os-test-project",
534+
gateway="100.127.0.17",
535+
destination="100.126.0.0/17",
536+
)
537+
538+
result = netapp_client.create_route(route_spec)
539+
540+
# Verify route configuration
541+
assert mock_route_instance.svm == {"name": "os-test-project"}
542+
assert mock_route_instance.gateway == "100.127.0.17"
543+
assert mock_route_instance.destination == "100.126.0.0/17"
544+
mock_route_instance.post.assert_called_once_with(hydrate=True)
545+
546+
# Verify result
547+
assert result.uuid == "route-uuid-123"
548+
assert result.gateway == "100.127.0.17"
549+
assert result.destination == "100.126.0.0/17"
550+
assert result.svm_name == "os-test-project"
551+
552+
@patch("understack_workflows.netapp.client.NetworkRoute")
553+
def test_create_route_netapp_rest_error(self, mock_route_class, netapp_client):
554+
"""Test route creation with NetAppRestError."""
555+
mock_route_instance = MagicMock()
556+
mock_route_instance.post.side_effect = NetAppRestError("SVM not found")
557+
mock_route_class.return_value = mock_route_instance
558+
559+
# Configure error handler to raise NetworkOperationError
560+
netapp_client._error_handler.handle_netapp_error.side_effect = (
561+
NetworkOperationError(
562+
"Route creation failed: SVM not found",
563+
interface_name="test-route",
564+
context={"svm_name": "os-nonexistent-project"},
565+
)
566+
)
567+
568+
route_spec = RouteSpec(
569+
svm_name="os-nonexistent-project",
570+
gateway="100.127.0.17",
571+
destination="100.126.0.0/17",
572+
)
573+
574+
with pytest.raises(NetworkOperationError):
575+
netapp_client.create_route(route_spec)
576+
577+
# Verify error handler was called with correct context
578+
netapp_client._error_handler.handle_netapp_error.assert_called_once()
579+
call_args = netapp_client._error_handler.handle_netapp_error.call_args
580+
assert isinstance(call_args[0][0], NetAppRestError)
581+
assert call_args[0][1] == "Route creation"
582+
assert call_args[0][2]["svm_name"] == "os-nonexistent-project"
583+
assert call_args[0][2]["gateway"] == "100.127.0.17"
584+
assert call_args[0][2]["destination"] == "100.126.0.0/17"
585+
586+
@patch("understack_workflows.netapp.client.NetworkRoute")
587+
def test_create_route_invalid_svm_error(self, mock_route_class, netapp_client):
588+
"""Test route creation with invalid SVM name."""
589+
mock_route_instance = MagicMock()
590+
mock_route_instance.post.side_effect = NetAppRestError(
591+
"SVM 'os-invalid-svm' does not exist"
592+
)
593+
mock_route_class.return_value = mock_route_instance
594+
595+
# Configure error handler to raise NetworkOperationError
596+
netapp_client._error_handler.handle_netapp_error.side_effect = (
597+
NetworkOperationError(
598+
"Route creation failed: SVM does not exist",
599+
interface_name="test-route",
600+
context={"svm_name": "os-invalid-svm"},
601+
)
602+
)
603+
604+
route_spec = RouteSpec(
605+
svm_name="os-invalid-svm",
606+
gateway="100.127.0.17",
607+
destination="100.126.0.0/17",
608+
)
609+
610+
with pytest.raises(NetworkOperationError):
611+
netapp_client.create_route(route_spec)
612+
613+
# Verify error context includes SVM information
614+
call_args = netapp_client._error_handler.handle_netapp_error.call_args
615+
assert call_args[0][2]["svm_name"] == "os-invalid-svm"
616+
617+
@patch("understack_workflows.netapp.client.NetworkRoute")
618+
def test_create_route_gateway_unreachable_error(
619+
self, mock_route_class, netapp_client
620+
):
621+
"""Test route creation with unreachable gateway."""
622+
mock_route_instance = MagicMock()
623+
mock_route_instance.post.side_effect = NetAppRestError(
624+
"Gateway 192.168.1.1 is not reachable from SVM network"
625+
)
626+
mock_route_class.return_value = mock_route_instance
627+
628+
# Configure error handler to raise NetworkOperationError
629+
netapp_client._error_handler.handle_netapp_error.side_effect = (
630+
NetworkOperationError(
631+
"Route creation failed: Gateway unreachable",
632+
interface_name="test-route",
633+
context={"gateway": "192.168.1.1"},
634+
)
635+
)
636+
637+
route_spec = RouteSpec(
638+
svm_name="os-test-project",
639+
gateway="192.168.1.1", # Invalid gateway for this network
640+
destination="100.126.0.0/17",
641+
)
642+
643+
with pytest.raises(NetworkOperationError):
644+
netapp_client.create_route(route_spec)
645+
646+
# Verify error context includes gateway information
647+
call_args = netapp_client._error_handler.handle_netapp_error.call_args
648+
assert call_args[0][2]["gateway"] == "192.168.1.1"
649+
assert call_args[0][2]["destination"] == "100.126.0.0/17"
650+
651+
@patch("understack_workflows.netapp.client.NetworkRoute")
652+
def test_create_route_logging_behavior(self, mock_route_class, netapp_client):
653+
"""Test route creation logging behavior."""
654+
mock_route_instance = MagicMock()
655+
mock_route_instance.uuid = "route-uuid-456"
656+
mock_route_class.return_value = mock_route_instance
657+
658+
route_spec = RouteSpec(
659+
svm_name="os-logging-test",
660+
gateway="100.127.128.17",
661+
destination="100.126.128.0/17",
662+
)
663+
664+
netapp_client.create_route(route_spec)
665+
666+
# Verify logging calls
667+
error_handler = netapp_client._error_handler
668+
log_info_calls = error_handler.log_info.call_args_list
669+
log_debug_calls = error_handler.log_debug.call_args_list
670+
671+
# Should have info logs for start and completion
672+
assert len(log_info_calls) >= 2
673+
674+
# Should have debug log for route creation
675+
assert len(log_debug_calls) >= 1
676+
677+
# Find the route-specific log messages
678+
route_start_logs = [
679+
call for call in log_info_calls if "Creating route:" in call[0][0]
680+
]
681+
route_completion_logs = [
682+
call
683+
for call in log_info_calls
684+
if "Route created successfully:" in call[0][0]
685+
]
686+
687+
# Verify route start log
688+
assert len(route_start_logs) == 1
689+
start_log = route_start_logs[0]
690+
assert start_log[0][1]["destination"] == "100.126.128.0/17"
691+
assert start_log[0][1]["gateway"] == "100.127.128.17"
692+
assert start_log[0][1]["svm_name"] == "os-logging-test"
693+
694+
# Verify route completion log
695+
assert len(route_completion_logs) == 1
696+
completion_log = route_completion_logs[0]
697+
assert completion_log[0][1]["uuid"] == "route-uuid-456"
698+
524699

525700
class TestNetAppClientInterface:
526701
"""Test cases for NetAppClientInterface abstract class."""

0 commit comments

Comments
 (0)