@@ -374,3 +374,225 @@ def test_desired_node_number_extraction(self):
374
374
vlan_id = 100 ,
375
375
)
376
376
assert config_n2 .desired_node_number == 2
377
+
378
+
379
+ class TestNetAppManagerRouteIntegration :
380
+ """Test NetAppManager route integration functionality."""
381
+
382
+ @pytest .fixture
383
+ def mock_config_file (self ):
384
+ """Create a temporary config file for testing."""
385
+ config_content = """[netapp_nvme]
386
+ netapp_server_hostname = test-hostname
387
+ netapp_login = test-user
388
+ netapp_password = test-password
389
+ """
390
+ with tempfile .NamedTemporaryFile (mode = "w" , suffix = ".conf" , delete = False ) as f :
391
+ f .write (config_content )
392
+ f .flush ()
393
+ yield f .name
394
+ os .unlink (f .name )
395
+
396
+ @pytest .fixture
397
+ def sample_interface_configs (self ):
398
+ """Create sample interface configurations for testing."""
399
+ return [
400
+ NetappIPInterfaceConfig (
401
+ name = "N1-lif-A" ,
402
+ address = ipaddress .IPv4Address ("100.127.0.21" ),
403
+ network = ipaddress .IPv4Network ("100.127.0.16/29" ),
404
+ vlan_id = 100 ,
405
+ ),
406
+ NetappIPInterfaceConfig (
407
+ name = "N1-lif-B" ,
408
+ address = ipaddress .IPv4Address ("100.127.128.21" ),
409
+ network = ipaddress .IPv4Network ("100.127.128.16/29" ),
410
+ vlan_id = 200 ,
411
+ ),
412
+ NetappIPInterfaceConfig (
413
+ name = "N2-lif-A" ,
414
+ address = ipaddress .IPv4Address ("100.127.0.22" ),
415
+ network = ipaddress .IPv4Network ("100.127.0.16/29" ),
416
+ vlan_id = 100 ,
417
+ ),
418
+ ]
419
+
420
+ @patch ("understack_workflows.netapp.manager.config" )
421
+ @patch ("understack_workflows.netapp.manager.HostConnection" )
422
+ def test_route_service_initialization (
423
+ self , mock_host_connection , mock_config , mock_config_file
424
+ ):
425
+ """Test that RouteService is properly initialized in NetAppManager."""
426
+ manager = NetAppManager (mock_config_file )
427
+
428
+ # Verify route service is initialized
429
+ assert hasattr (manager , "_route_service" )
430
+ assert manager ._route_service is not None
431
+
432
+ @patch ("understack_workflows.netapp.manager.config" )
433
+ @patch ("understack_workflows.netapp.manager.HostConnection" )
434
+ def test_create_routes_for_project_delegates_to_service (
435
+ self ,
436
+ mock_host_connection ,
437
+ mock_config ,
438
+ mock_config_file ,
439
+ sample_interface_configs ,
440
+ ):
441
+ """Test create_routes_for_project delegates to RouteService."""
442
+ from understack_workflows .netapp .value_objects import RouteResult
443
+
444
+ manager = NetAppManager (mock_config_file )
445
+
446
+ # Mock route service
447
+ expected_results = [
448
+ RouteResult (
449
+ uuid = "route-uuid-1" ,
450
+ gateway = "100.127.0.17" ,
451
+ destination = "100.126.0.0/17" ,
452
+ svm_name = "os-test-project" ,
453
+ ),
454
+ RouteResult (
455
+ uuid = "route-uuid-2" ,
456
+ gateway = "100.127.128.17" ,
457
+ destination = "100.126.128.0/17" ,
458
+ svm_name = "os-test-project" ,
459
+ ),
460
+ ]
461
+ manager ._route_service .create_routes_from_interfaces = MagicMock (
462
+ return_value = expected_results
463
+ )
464
+
465
+ result = manager .create_routes_for_project (
466
+ "test-project" , sample_interface_configs
467
+ )
468
+
469
+ # Verify delegation with correct parameters
470
+ manager ._route_service .create_routes_from_interfaces .assert_called_once_with (
471
+ "test-project" , sample_interface_configs
472
+ )
473
+ assert result == expected_results
474
+
475
+ @patch ("understack_workflows.netapp.manager.config" )
476
+ @patch ("understack_workflows.netapp.manager.HostConnection" )
477
+ def test_create_routes_for_project_error_handling (
478
+ self ,
479
+ mock_host_connection ,
480
+ mock_config ,
481
+ mock_config_file ,
482
+ sample_interface_configs ,
483
+ ):
484
+ """Test create_routes_for_project error handling and propagation."""
485
+ from understack_workflows .netapp .exceptions import NetworkOperationError
486
+
487
+ manager = NetAppManager (mock_config_file )
488
+
489
+ # Mock route service to raise an error
490
+ manager ._route_service .create_routes_from_interfaces = MagicMock (
491
+ side_effect = NetworkOperationError ("Route creation failed" )
492
+ )
493
+
494
+ # Verify error is propagated
495
+ with pytest .raises (NetworkOperationError , match = "Route creation failed" ):
496
+ manager .create_routes_for_project ("test-project" , sample_interface_configs )
497
+
498
+ # Verify service was called
499
+ manager ._route_service .create_routes_from_interfaces .assert_called_once_with (
500
+ "test-project" , sample_interface_configs
501
+ )
502
+
503
+ @patch ("understack_workflows.netapp.manager.config" )
504
+ @patch ("understack_workflows.netapp.manager.HostConnection" )
505
+ def test_create_routes_for_project_logging (
506
+ self ,
507
+ mock_host_connection ,
508
+ mock_config ,
509
+ mock_config_file ,
510
+ sample_interface_configs ,
511
+ ):
512
+ """Test create_routes_for_project logging behavior."""
513
+ from understack_workflows .netapp .value_objects import RouteResult
514
+
515
+ manager = NetAppManager (mock_config_file )
516
+
517
+ # Mock route service
518
+ expected_results = [
519
+ RouteResult (
520
+ uuid = "route-uuid-1" ,
521
+ gateway = "100.127.0.17" ,
522
+ destination = "100.126.0.0/17" ,
523
+ svm_name = "os-test-project" ,
524
+ ),
525
+ ]
526
+ manager ._route_service .create_routes_from_interfaces = MagicMock (
527
+ return_value = expected_results
528
+ )
529
+
530
+ with patch ("understack_workflows.netapp.manager.logger" ) as mock_logger :
531
+ result = manager .create_routes_for_project (
532
+ "test-project" , sample_interface_configs
533
+ )
534
+
535
+ # Verify logging calls
536
+ mock_logger .info .assert_any_call (
537
+ "Creating routes for project %(project_id)s with %(count)d interfaces" ,
538
+ {"project_id" : "test-project" , "count" : 3 },
539
+ )
540
+ mock_logger .info .assert_any_call (
541
+ "Successfully created %(count)d routes for project %(project_id)s" ,
542
+ {"count" : 1 , "project_id" : "test-project" },
543
+ )
544
+
545
+ assert result == expected_results
546
+
547
+ @patch ("understack_workflows.netapp.manager.config" )
548
+ @patch ("understack_workflows.netapp.manager.HostConnection" )
549
+ def test_create_routes_for_project_empty_interfaces (
550
+ self , mock_host_connection , mock_config , mock_config_file
551
+ ):
552
+ """Test create_routes_for_project with empty interface list."""
553
+ manager = NetAppManager (mock_config_file )
554
+
555
+ # Mock route service
556
+ manager ._route_service .create_routes_from_interfaces = MagicMock (
557
+ return_value = []
558
+ )
559
+
560
+ result = manager .create_routes_for_project ("test-project" , [])
561
+
562
+ # Verify delegation with empty list
563
+ manager ._route_service .create_routes_from_interfaces .assert_called_once_with (
564
+ "test-project" , []
565
+ )
566
+ assert result == []
567
+
568
+ @patch ("understack_workflows.netapp.manager.config" )
569
+ @patch ("understack_workflows.netapp.manager.HostConnection" )
570
+ def test_route_service_dependency_injection (
571
+ self , mock_host_connection , mock_config , mock_config_file
572
+ ):
573
+ """Test NetAppManager with injected RouteService dependency."""
574
+ from understack_workflows .netapp .route_service import RouteService
575
+
576
+ # Create mock dependencies
577
+ mock_client = MagicMock ()
578
+ mock_error_handler = MagicMock ()
579
+ mock_route_service = MagicMock (spec = RouteService )
580
+
581
+ manager = NetAppManager (
582
+ config_path = mock_config_file ,
583
+ netapp_client = mock_client ,
584
+ route_service = mock_route_service ,
585
+ error_handler = mock_error_handler ,
586
+ )
587
+
588
+ # Verify injected route service is used
589
+ assert manager ._route_service is mock_route_service
590
+
591
+ # Test delegation works with injected service
592
+ mock_route_service .create_routes_from_interfaces .return_value = []
593
+ result = manager .create_routes_for_project ("test-project" , [])
594
+
595
+ mock_route_service .create_routes_from_interfaces .assert_called_once_with (
596
+ "test-project" , []
597
+ )
598
+ assert result == []
0 commit comments