|
6 | 6 | from unittest.mock import patch
|
7 | 7 |
|
8 | 8 | import pytest
|
| 9 | +from pydantic import ValidationError |
9 | 10 |
|
10 | 11 | from understack_workflows.main.netapp_configure_net import VIRTUAL_MACHINES_QUERY
|
11 |
| -from understack_workflows.main.netapp_configure_net import InterfaceInfo |
12 |
| -from understack_workflows.main.netapp_configure_net import VirtualMachineNetworkInfo |
13 | 12 | from understack_workflows.main.netapp_configure_net import argument_parser
|
14 | 13 | from understack_workflows.main.netapp_configure_net import construct_device_name
|
15 | 14 | from understack_workflows.main.netapp_configure_net import execute_graphql_query
|
|
19 | 18 | from understack_workflows.main.netapp_configure_net import (
|
20 | 19 | validate_and_transform_response,
|
21 | 20 | )
|
| 21 | +from understack_workflows.netapp.value_objects import InterfaceInfo |
| 22 | +from understack_workflows.netapp.value_objects import VirtualMachineNetworkInfo |
22 | 23 |
|
23 | 24 |
|
24 | 25 | def load_json_sample(filename: str) -> dict:
|
@@ -657,6 +658,52 @@ def test_error_messages_contain_interface_details(self):
|
657 | 658 | assert "200" in error_message
|
658 | 659 | assert "300" in error_message
|
659 | 660 |
|
| 661 | + def test_vlan_validation_valid_range(self): |
| 662 | + """Test VLAN validation with valid VLAN IDs (1-4094).""" |
| 663 | + valid_vlans = [1, 100, 2002, 4094] |
| 664 | + |
| 665 | + for vlan in valid_vlans: |
| 666 | + interface = InterfaceInfo( |
| 667 | + name="test-interface", address="192.168.1.10/24", vlan=vlan |
| 668 | + ) |
| 669 | + assert interface.vlan == vlan |
| 670 | + |
| 671 | + def test_vlan_validation_invalid_range(self): |
| 672 | + """Test VLAN validation with invalid VLAN IDs (outside 1-4094 range).""" |
| 673 | + from pydantic import ValidationError |
| 674 | + |
| 675 | + invalid_vlans = [0, -1, 4095, 5000, 65536] |
| 676 | + |
| 677 | + for vlan in invalid_vlans: |
| 678 | + with pytest.raises( |
| 679 | + ValidationError, match="VLAN ID must be between 1 and 4094" |
| 680 | + ): |
| 681 | + InterfaceInfo( |
| 682 | + name="test-interface", address="192.168.1.10/24", vlan=vlan |
| 683 | + ) |
| 684 | + |
| 685 | + def test_vlan_validation_in_from_graphql_interface(self): |
| 686 | + """Test VLAN validation works in from_graphql_interface method.""" |
| 687 | + # Test valid VLAN |
| 688 | + interface_data = { |
| 689 | + "name": "test-interface", |
| 690 | + "ip_addresses": [{"address": "192.168.1.10/24"}], |
| 691 | + "tagged_vlans": [{"vid": 2002}], |
| 692 | + } |
| 693 | + |
| 694 | + interface = InterfaceInfo.from_graphql_interface(interface_data) |
| 695 | + assert interface.vlan == 2002 |
| 696 | + |
| 697 | + # Test invalid VLAN |
| 698 | + interface_data_invalid = { |
| 699 | + "name": "test-interface", |
| 700 | + "ip_addresses": [{"address": "192.168.1.10/24"}], |
| 701 | + "tagged_vlans": [{"vid": 4095}], # Invalid VLAN |
| 702 | + } |
| 703 | + |
| 704 | + with pytest.raises(ValidationError, match="VLAN ID must be between 1 and 4094"): |
| 705 | + InterfaceInfo.from_graphql_interface(interface_data_invalid) |
| 706 | + |
660 | 707 |
|
661 | 708 | class TestVirtualMachineNetworkInfo:
|
662 | 709 | """Test cases for VirtualMachineNetworkInfo data class and validation."""
|
@@ -1142,7 +1189,7 @@ def test_handling_of_empty_query_results(self, mock_logger):
|
1142 | 1189 |
|
1143 | 1190 | assert result["data"]["virtual_machines"] == []
|
1144 | 1191 | mock_logger.info.assert_called_with(
|
1145 |
| - "GraphQL query successful. Found %s virtual machine(s) " "for device: %s", |
| 1192 | + "GraphQL query successful. Found %s virtual machine(s) for device: %s", |
1146 | 1193 | 0,
|
1147 | 1194 | "os-empty-project",
|
1148 | 1195 | )
|
@@ -1175,7 +1222,7 @@ def test_handling_of_empty_query_results(self, mock_logger):
|
1175 | 1222 | assert len(result["data"]["virtual_machines"]) == 1
|
1176 | 1223 | assert result["data"]["virtual_machines"][0]["interfaces"] == []
|
1177 | 1224 | mock_logger.info.assert_called_with(
|
1178 |
| - "GraphQL query successful. Found %s virtual machine(s) " "for device: %s", |
| 1225 | + "GraphQL query successful. Found %s virtual machine(s) for device: %s", |
1179 | 1226 | 1,
|
1180 | 1227 | "os-empty-interfaces-project",
|
1181 | 1228 | )
|
@@ -1204,7 +1251,7 @@ def test_graphql_query_logging_behavior(self, mock_logger):
|
1204 | 1251 |
|
1205 | 1252 | # Verify info logging
|
1206 | 1253 | mock_logger.info.assert_called_with(
|
1207 |
| - "GraphQL query successful. Found %s virtual machine(s) " "for device: %s", |
| 1254 | + "GraphQL query successful. Found %s virtual machine(s) for device: %s", |
1208 | 1255 | 1,
|
1209 | 1256 | "os-logging-test-project",
|
1210 | 1257 | )
|
@@ -1733,6 +1780,10 @@ def test_main_function_initializes_netapp_manager_with_default_path(
|
1733 | 1780 | # Mock NetAppManager
|
1734 | 1781 | mock_netapp_manager_instance = Mock()
|
1735 | 1782 | mock_netapp_manager_instance.create_routes_for_project.return_value = []
|
| 1783 | + # Properly mock the config property with netapp_nic_slot_prefix |
| 1784 | + mock_config = Mock() |
| 1785 | + mock_config.netapp_nic_slot_prefix = "e4" |
| 1786 | + mock_netapp_manager_instance.config = mock_config |
1736 | 1787 | mock_netapp_manager_class.return_value = mock_netapp_manager_instance
|
1737 | 1788 |
|
1738 | 1789 | # Mock sys.argv with default netapp config path
|
@@ -1789,6 +1840,10 @@ def test_main_function_initializes_netapp_manager_with_custom_path(
|
1789 | 1840 |
|
1790 | 1841 | # Mock NetAppManager
|
1791 | 1842 | mock_netapp_manager_instance = Mock()
|
| 1843 | + # Mock the config property to return a proper config object |
| 1844 | + mock_config = Mock() |
| 1845 | + mock_config.netapp_nic_slot_prefix = "e4" |
| 1846 | + mock_netapp_manager_instance.config = mock_config |
1792 | 1847 | mock_netapp_manager_instance.create_routes_for_project.return_value = []
|
1793 | 1848 | mock_netapp_manager_class.return_value = mock_netapp_manager_instance
|
1794 | 1849 |
|
|
0 commit comments