@@ -514,6 +514,93 @@ def test__validate_gw_info_delete_gateway_no_route(self):
514
514
self .assertIsNone (
515
515
self .db ._validate_gw_info (mock .ANY , info , [], router ))
516
516
517
+ def test__raise_on_subnets_overlap_does_not_raise (self ):
518
+ subnets = [
519
+ {'id' : uuidutils .generate_uuid (),
520
+ 'cidr' : '10.1.0.0/24' },
521
+ {'id' : uuidutils .generate_uuid (),
522
+ 'cidr' : '10.2.0.0/24' }]
523
+ self .db ._raise_on_subnets_overlap (subnets [0 ], subnets [1 ])
524
+
525
+ def test__raise_on_subnets_overlap_raises (self ):
526
+ subnets = [
527
+ {'id' : uuidutils .generate_uuid (),
528
+ 'cidr' : '10.1.0.0/20' },
529
+ {'id' : uuidutils .generate_uuid (),
530
+ 'cidr' : '10.1.10.0/24' }]
531
+ self .assertRaises (
532
+ n_exc .BadRequest , self .db ._raise_on_subnets_overlap , subnets [0 ],
533
+ subnets [1 ])
534
+
535
+ def test__validate_one_router_ipv6_port_per_network (self ):
536
+ port = models_v2 .Port (
537
+ id = uuidutils .generate_uuid (),
538
+ network_id = 'foo_network' ,
539
+ fixed_ips = [models_v2 .IPAllocation (
540
+ ip_address = str (netaddr .IPNetwork (
541
+ '2001:db8::/32' ).ip + 1 ),
542
+ subnet_id = 'foo_subnet' )])
543
+ rports = [l3_models .RouterPort (router_id = 'foo_router' , port = port )]
544
+ router = l3_models .Router (
545
+ id = 'foo_router' , attached_ports = rports , route_list = [],
546
+ gw_port_id = None )
547
+ new_port = models_v2 .Port (
548
+ id = uuidutils .generate_uuid (),
549
+ network_id = 'foo_network2' ,
550
+ fixed_ips = [models_v2 .IPAllocation (
551
+ ip_address = str (netaddr .IPNetwork (
552
+ '2001:db8::/32' ).ip + 2 ),
553
+ subnet_id = 'foo_subnet' )])
554
+ self .db ._validate_one_router_ipv6_port_per_network (
555
+ router , new_port )
556
+
557
+ def test__validate_one_router_ipv6_port_per_network_mix_ipv4_ipv6 (self ):
558
+ port = models_v2 .Port (
559
+ id = uuidutils .generate_uuid (),
560
+ network_id = 'foo_network' ,
561
+ fixed_ips = [models_v2 .IPAllocation (
562
+ ip_address = str (netaddr .IPNetwork (
563
+ '10.1.10.0/24' ).ip + 1 ),
564
+ subnet_id = 'foo_subnet' )])
565
+ rports = [l3_models .RouterPort (router_id = 'foo_router' , port = port )]
566
+ router = l3_models .Router (
567
+ id = 'foo_router' , attached_ports = rports , route_list = [],
568
+ gw_port_id = None )
569
+ new_port = models_v2 .Port (
570
+ id = uuidutils .generate_uuid (),
571
+ network_id = 'foo_network' ,
572
+ fixed_ips = [models_v2 .IPAllocation (
573
+ ip_address = str (netaddr .IPNetwork (
574
+ '2001:db8::/32' ).ip + 2 ),
575
+ subnet_id = 'foo_subnet' )])
576
+ self .db ._validate_one_router_ipv6_port_per_network (
577
+ router , new_port )
578
+
579
+ def test__validate_one_router_ipv6_port_per_network_failed (self ):
580
+ port = models_v2 .Port (
581
+ id = uuidutils .generate_uuid (),
582
+ network_id = 'foo_network' ,
583
+ fixed_ips = [models_v2 .IPAllocation (
584
+ ip_address = str (netaddr .IPNetwork (
585
+ '2001:db8::/32' ).ip + 1 ),
586
+ subnet_id = 'foo_subnet' )])
587
+ rports = [l3_models .RouterPort (router_id = 'foo_router' , port = port )]
588
+ router = l3_models .Router (
589
+ id = 'foo_router' , attached_ports = rports , route_list = [],
590
+ gw_port_id = None )
591
+ new_port = models_v2 .Port (
592
+ id = uuidutils .generate_uuid (),
593
+ network_id = 'foo_network' ,
594
+ fixed_ips = [models_v2 .IPAllocation (
595
+ ip_address = str (netaddr .IPNetwork (
596
+ '2001:db8::/32' ).ip + 2 ),
597
+ subnet_id = 'foo_subnet' )])
598
+ self .assertRaises (
599
+ n_exc .BadRequest ,
600
+ self .db ._validate_one_router_ipv6_port_per_network ,
601
+ router ,
602
+ new_port )
603
+
517
604
518
605
class L3_NAT_db_mixin (base .BaseTestCase ):
519
606
def setUp (self ):
@@ -697,6 +784,56 @@ def test_remove_router_interface_by_subnet(self, mock_log):
697
784
mock_log .warning .not_called_once ()
698
785
self ._check_routerports ((True , False ))
699
786
787
+ @mock .patch .object (l3_db .L3_NAT_dbonly_mixin ,
788
+ '_check_for_dup_router_subnets' )
789
+ @mock .patch .object (l3_db .L3_NAT_dbonly_mixin ,
790
+ '_raise_on_subnets_overlap' )
791
+ def test_add_router_interface_by_port_overlap_detected (
792
+ self , mock_raise_on_subnets_overlap , mock_check_dup ):
793
+ # NOTE(froyo): On a normal behaviour this overlapping would be detected
794
+ # by _check_for_dup_router_subnets, in order to evalue the code
795
+ # implemented to cover the race condition when two ports are added
796
+ # simultaneously using colliding cidrs we need to "fake" this method
797
+ # to overpass it and check we achieve the code part that cover the case
798
+ mock_check_dup .return_value = True
799
+ network2 = self .create_network ('network2' )
800
+ subnet = self .create_subnet (network2 , '1.1.1.1' , '1.1.1.0/24' )
801
+ ipa = str (netaddr .IPNetwork (subnet ['subnet' ]['cidr' ]).ip + 10 )
802
+ fixed_ips = [{'subnet_id' : subnet ['subnet' ]['id' ], 'ip_address' : ipa }]
803
+ port = self .create_port (
804
+ network2 ['network' ]['id' ], {'fixed_ips' : fixed_ips })
805
+ self .mixin .add_router_interface (
806
+ self .ctx , self .router ['id' ],
807
+ interface_info = {'port_id' : port ['port' ]['id' ]})
808
+ mock_raise_on_subnets_overlap .assert_not_called ()
809
+ self .mixin .add_router_interface (
810
+ self .ctx , self .router ['id' ],
811
+ interface_info = {'port_id' : self .ports [0 ]['port' ]['id' ]})
812
+ mock_raise_on_subnets_overlap .assert_called_once ()
813
+
814
+ @mock .patch .object (l3_db .L3_NAT_dbonly_mixin ,
815
+ '_check_for_dup_router_subnets' )
816
+ @mock .patch .object (l3_db .L3_NAT_dbonly_mixin ,
817
+ '_raise_on_subnets_overlap' )
818
+ def test_add_router_interface_by_subnet_overlap_detected (
819
+ self , mock_raise_on_subnets_overlap , mock_check_dup ):
820
+ # NOTE(froyo): On a normal behaviour this overlapping would be detected
821
+ # by _check_for_dup_router_subnets, in order to evalue the code
822
+ # implemented to cover the race condition when two ports are added
823
+ # simultaneously using colliding cidrs we need to "fake" this method
824
+ # to overpass it and check we achieve the code part that cover the case
825
+ mock_check_dup .return_value = True
826
+ network2 = self .create_network ('network2' )
827
+ subnet = self .create_subnet (network2 , '1.1.1.1' , '1.1.1.0/24' )
828
+ self .mixin .add_router_interface (
829
+ self .ctx , self .router ['id' ],
830
+ interface_info = {'subnet_id' : subnet ['subnet' ]['id' ]})
831
+ mock_raise_on_subnets_overlap .assert_not_called ()
832
+ self .mixin .add_router_interface (
833
+ self .ctx , self .router ['id' ],
834
+ interface_info = {'subnet_id' : self .subnets [0 ]['subnet' ]['id' ]})
835
+ mock_raise_on_subnets_overlap .assert_called_once ()
836
+
700
837
@mock .patch .object (port_obj , 'LOG' )
701
838
def test_remove_router_interface_by_subnet_removed_rport (self , mock_log ):
702
839
self ._add_router_interfaces ()
0 commit comments