1from netaddr import IPNetwork, IPSet 2from django.core.exceptions import ValidationError 3from django.test import TestCase, override_settings 4 5from ipam.choices import IPAddressRoleChoices, PrefixStatusChoices 6from ipam.models import Aggregate, IPAddress, IPRange, Prefix, RIR, VLAN, VLANGroup, VRF 7 8 9class TestAggregate(TestCase): 10 11 def test_get_utilization(self): 12 rir = RIR.objects.create(name='RIR 1', slug='rir-1') 13 aggregate = Aggregate(prefix=IPNetwork('10.0.0.0/8'), rir=rir) 14 aggregate.save() 15 16 # 25% utilization 17 Prefix.objects.bulk_create(( 18 Prefix(prefix=IPNetwork('10.0.0.0/12')), 19 Prefix(prefix=IPNetwork('10.16.0.0/12')), 20 Prefix(prefix=IPNetwork('10.32.0.0/12')), 21 Prefix(prefix=IPNetwork('10.48.0.0/12')), 22 )) 23 self.assertEqual(aggregate.get_utilization(), 25) 24 25 # 50% utilization 26 Prefix.objects.bulk_create(( 27 Prefix(prefix=IPNetwork('10.64.0.0/10')), 28 )) 29 self.assertEqual(aggregate.get_utilization(), 50) 30 31 # 100% utilization 32 Prefix.objects.bulk_create(( 33 Prefix(prefix=IPNetwork('10.128.0.0/9')), 34 )) 35 self.assertEqual(aggregate.get_utilization(), 100) 36 37 38class TestPrefix(TestCase): 39 40 def test_get_duplicates(self): 41 prefixes = Prefix.objects.bulk_create(( 42 Prefix(prefix=IPNetwork('192.0.2.0/24')), 43 Prefix(prefix=IPNetwork('192.0.2.0/24')), 44 Prefix(prefix=IPNetwork('192.0.2.0/24')), 45 )) 46 duplicate_prefix_pks = [p.pk for p in prefixes[0].get_duplicates()] 47 48 self.assertSetEqual(set(duplicate_prefix_pks), {prefixes[1].pk, prefixes[2].pk}) 49 50 def test_get_child_prefixes(self): 51 vrfs = VRF.objects.bulk_create(( 52 VRF(name='VRF 1'), 53 VRF(name='VRF 2'), 54 VRF(name='VRF 3'), 55 )) 56 prefixes = Prefix.objects.bulk_create(( 57 Prefix(prefix=IPNetwork('10.0.0.0/16'), status=PrefixStatusChoices.STATUS_CONTAINER), 58 Prefix(prefix=IPNetwork('10.0.0.0/24'), vrf=None), 59 Prefix(prefix=IPNetwork('10.0.1.0/24'), vrf=vrfs[0]), 60 Prefix(prefix=IPNetwork('10.0.2.0/24'), vrf=vrfs[1]), 61 Prefix(prefix=IPNetwork('10.0.3.0/24'), vrf=vrfs[2]), 62 )) 63 child_prefix_pks = {p.pk for p in prefixes[0].get_child_prefixes()} 64 65 # Global container should return all children 66 self.assertSetEqual(child_prefix_pks, {prefixes[1].pk, prefixes[2].pk, prefixes[3].pk, prefixes[4].pk}) 67 68 prefixes[0].vrf = vrfs[0] 69 prefixes[0].save() 70 child_prefix_pks = {p.pk for p in prefixes[0].get_child_prefixes()} 71 72 # VRF container is limited to its own VRF 73 self.assertSetEqual(child_prefix_pks, {prefixes[2].pk}) 74 75 def test_get_child_ranges(self): 76 prefix = Prefix(prefix='192.168.0.16/28') 77 prefix.save() 78 ranges = IPRange.objects.bulk_create(( 79 IPRange(start_address=IPNetwork('192.168.0.1/24'), end_address=IPNetwork('192.168.0.10/24'), size=10), # No overlap 80 IPRange(start_address=IPNetwork('192.168.0.11/24'), end_address=IPNetwork('192.168.0.17/24'), size=7), # Partial overlap 81 IPRange(start_address=IPNetwork('192.168.0.18/24'), end_address=IPNetwork('192.168.0.23/24'), size=6), # Full overlap 82 IPRange(start_address=IPNetwork('192.168.0.24/24'), end_address=IPNetwork('192.168.0.30/24'), size=7), # Full overlap 83 IPRange(start_address=IPNetwork('192.168.0.31/24'), end_address=IPNetwork('192.168.0.40/24'), size=10), # Partial overlap 84 )) 85 86 child_ranges = prefix.get_child_ranges() 87 88 self.assertEqual(len(child_ranges), 2) 89 self.assertEqual(child_ranges[0], ranges[2]) 90 self.assertEqual(child_ranges[1], ranges[3]) 91 92 def test_get_child_ips(self): 93 vrfs = VRF.objects.bulk_create(( 94 VRF(name='VRF 1'), 95 VRF(name='VRF 2'), 96 VRF(name='VRF 3'), 97 )) 98 parent_prefix = Prefix.objects.create( 99 prefix=IPNetwork('10.0.0.0/16'), status=PrefixStatusChoices.STATUS_CONTAINER 100 ) 101 ips = IPAddress.objects.bulk_create(( 102 IPAddress(address=IPNetwork('10.0.0.1/24'), vrf=None), 103 IPAddress(address=IPNetwork('10.0.1.1/24'), vrf=vrfs[0]), 104 IPAddress(address=IPNetwork('10.0.2.1/24'), vrf=vrfs[1]), 105 IPAddress(address=IPNetwork('10.0.3.1/24'), vrf=vrfs[2]), 106 )) 107 child_ip_pks = {p.pk for p in parent_prefix.get_child_ips()} 108 109 # Global container should return all children 110 self.assertSetEqual(child_ip_pks, {ips[0].pk, ips[1].pk, ips[2].pk, ips[3].pk}) 111 112 parent_prefix.vrf = vrfs[0] 113 parent_prefix.save() 114 child_ip_pks = {p.pk for p in parent_prefix.get_child_ips()} 115 116 # VRF container is limited to its own VRF 117 self.assertSetEqual(child_ip_pks, {ips[1].pk}) 118 119 def test_get_available_prefixes(self): 120 121 prefixes = Prefix.objects.bulk_create(( 122 Prefix(prefix=IPNetwork('10.0.0.0/16')), # Parent prefix 123 Prefix(prefix=IPNetwork('10.0.0.0/20')), 124 Prefix(prefix=IPNetwork('10.0.32.0/20')), 125 Prefix(prefix=IPNetwork('10.0.128.0/18')), 126 )) 127 missing_prefixes = IPSet([ 128 IPNetwork('10.0.16.0/20'), 129 IPNetwork('10.0.48.0/20'), 130 IPNetwork('10.0.64.0/18'), 131 IPNetwork('10.0.192.0/18'), 132 ]) 133 available_prefixes = prefixes[0].get_available_prefixes() 134 135 self.assertEqual(available_prefixes, missing_prefixes) 136 137 def test_get_available_ips(self): 138 139 parent_prefix = Prefix.objects.create(prefix=IPNetwork('10.0.0.0/28')) 140 IPAddress.objects.bulk_create(( 141 IPAddress(address=IPNetwork('10.0.0.1/26')), 142 IPAddress(address=IPNetwork('10.0.0.3/26')), 143 IPAddress(address=IPNetwork('10.0.0.5/26')), 144 IPAddress(address=IPNetwork('10.0.0.7/26')), 145 )) 146 IPRange.objects.create( 147 start_address=IPNetwork('10.0.0.9/26'), 148 end_address=IPNetwork('10.0.0.12/26') 149 ) 150 missing_ips = IPSet([ 151 '10.0.0.2/32', 152 '10.0.0.4/32', 153 '10.0.0.6/32', 154 '10.0.0.8/32', 155 '10.0.0.13/32', 156 '10.0.0.14/32', 157 ]) 158 available_ips = parent_prefix.get_available_ips() 159 160 self.assertEqual(available_ips, missing_ips) 161 162 def test_get_first_available_prefix(self): 163 164 prefixes = Prefix.objects.bulk_create(( 165 Prefix(prefix=IPNetwork('10.0.0.0/16')), # Parent prefix 166 Prefix(prefix=IPNetwork('10.0.0.0/24')), 167 Prefix(prefix=IPNetwork('10.0.1.0/24')), 168 Prefix(prefix=IPNetwork('10.0.2.0/24')), 169 )) 170 self.assertEqual(prefixes[0].get_first_available_prefix(), IPNetwork('10.0.3.0/24')) 171 172 Prefix.objects.create(prefix=IPNetwork('10.0.3.0/24')) 173 self.assertEqual(prefixes[0].get_first_available_prefix(), IPNetwork('10.0.4.0/22')) 174 175 def test_get_first_available_ip(self): 176 177 parent_prefix = Prefix.objects.create(prefix=IPNetwork('10.0.0.0/24')) 178 IPAddress.objects.bulk_create(( 179 IPAddress(address=IPNetwork('10.0.0.1/24')), 180 IPAddress(address=IPNetwork('10.0.0.2/24')), 181 IPAddress(address=IPNetwork('10.0.0.3/24')), 182 )) 183 self.assertEqual(parent_prefix.get_first_available_ip(), '10.0.0.4/24') 184 185 IPAddress.objects.create(address=IPNetwork('10.0.0.4/24')) 186 self.assertEqual(parent_prefix.get_first_available_ip(), '10.0.0.5/24') 187 188 def test_get_utilization_container(self): 189 prefixes = ( 190 Prefix(prefix=IPNetwork('10.0.0.0/24'), status=PrefixStatusChoices.STATUS_CONTAINER), 191 Prefix(prefix=IPNetwork('10.0.0.0/26')), 192 Prefix(prefix=IPNetwork('10.0.0.128/26')), 193 ) 194 Prefix.objects.bulk_create(prefixes) 195 self.assertEqual(prefixes[0].get_utilization(), 50) # 50% utilization 196 197 def test_get_utilization_noncontainer(self): 198 prefix = Prefix.objects.create( 199 prefix=IPNetwork('10.0.0.0/24'), 200 status=PrefixStatusChoices.STATUS_ACTIVE 201 ) 202 203 # Create 32 child IPs 204 IPAddress.objects.bulk_create([ 205 IPAddress(address=IPNetwork(f'10.0.0.{i}/24')) for i in range(1, 33) 206 ]) 207 self.assertEqual(prefix.get_utilization(), 12) # 12.5% utilization 208 209 # Create a child range with 32 additional IPs 210 IPRange.objects.create(start_address=IPNetwork('10.0.0.33/24'), end_address=IPNetwork('10.0.0.64/24')) 211 self.assertEqual(prefix.get_utilization(), 25) # 25% utilization 212 213 # 214 # Uniqueness enforcement tests 215 # 216 217 @override_settings(ENFORCE_GLOBAL_UNIQUE=False) 218 def test_duplicate_global(self): 219 Prefix.objects.create(prefix=IPNetwork('192.0.2.0/24')) 220 duplicate_prefix = Prefix(prefix=IPNetwork('192.0.2.0/24')) 221 self.assertIsNone(duplicate_prefix.clean()) 222 223 @override_settings(ENFORCE_GLOBAL_UNIQUE=True) 224 def test_duplicate_global_unique(self): 225 Prefix.objects.create(prefix=IPNetwork('192.0.2.0/24')) 226 duplicate_prefix = Prefix(prefix=IPNetwork('192.0.2.0/24')) 227 self.assertRaises(ValidationError, duplicate_prefix.clean) 228 229 def test_duplicate_vrf(self): 230 vrf = VRF.objects.create(name='Test', rd='1:1', enforce_unique=False) 231 Prefix.objects.create(vrf=vrf, prefix=IPNetwork('192.0.2.0/24')) 232 duplicate_prefix = Prefix(vrf=vrf, prefix=IPNetwork('192.0.2.0/24')) 233 self.assertIsNone(duplicate_prefix.clean()) 234 235 def test_duplicate_vrf_unique(self): 236 vrf = VRF.objects.create(name='Test', rd='1:1', enforce_unique=True) 237 Prefix.objects.create(vrf=vrf, prefix=IPNetwork('192.0.2.0/24')) 238 duplicate_prefix = Prefix(vrf=vrf, prefix=IPNetwork('192.0.2.0/24')) 239 self.assertRaises(ValidationError, duplicate_prefix.clean) 240 241 242class TestPrefixHierarchy(TestCase): 243 """ 244 Test the automatic updating of depth and child count in response to changes made within 245 the prefix hierarchy. 246 """ 247 @classmethod 248 def setUpTestData(cls): 249 250 prefixes = ( 251 252 # IPv4 253 Prefix(prefix='10.0.0.0/8', _depth=0, _children=2), 254 Prefix(prefix='10.0.0.0/16', _depth=1, _children=1), 255 Prefix(prefix='10.0.0.0/24', _depth=2, _children=0), 256 257 # IPv6 258 Prefix(prefix='2001:db8::/32', _depth=0, _children=2), 259 Prefix(prefix='2001:db8::/40', _depth=1, _children=1), 260 Prefix(prefix='2001:db8::/48', _depth=2, _children=0), 261 262 ) 263 Prefix.objects.bulk_create(prefixes) 264 265 def test_create_prefix4(self): 266 # Create 10.0.0.0/12 267 Prefix(prefix='10.0.0.0/12').save() 268 269 prefixes = Prefix.objects.filter(prefix__family=4) 270 self.assertEqual(prefixes[0].prefix, IPNetwork('10.0.0.0/8')) 271 self.assertEqual(prefixes[0]._depth, 0) 272 self.assertEqual(prefixes[0]._children, 3) 273 self.assertEqual(prefixes[1].prefix, IPNetwork('10.0.0.0/12')) 274 self.assertEqual(prefixes[1]._depth, 1) 275 self.assertEqual(prefixes[1]._children, 2) 276 self.assertEqual(prefixes[2].prefix, IPNetwork('10.0.0.0/16')) 277 self.assertEqual(prefixes[2]._depth, 2) 278 self.assertEqual(prefixes[2]._children, 1) 279 self.assertEqual(prefixes[3].prefix, IPNetwork('10.0.0.0/24')) 280 self.assertEqual(prefixes[3]._depth, 3) 281 self.assertEqual(prefixes[3]._children, 0) 282 283 def test_create_prefix6(self): 284 # Create 2001:db8::/36 285 Prefix(prefix='2001:db8::/36').save() 286 287 prefixes = Prefix.objects.filter(prefix__family=6) 288 self.assertEqual(prefixes[0].prefix, IPNetwork('2001:db8::/32')) 289 self.assertEqual(prefixes[0]._depth, 0) 290 self.assertEqual(prefixes[0]._children, 3) 291 self.assertEqual(prefixes[1].prefix, IPNetwork('2001:db8::/36')) 292 self.assertEqual(prefixes[1]._depth, 1) 293 self.assertEqual(prefixes[1]._children, 2) 294 self.assertEqual(prefixes[2].prefix, IPNetwork('2001:db8::/40')) 295 self.assertEqual(prefixes[2]._depth, 2) 296 self.assertEqual(prefixes[2]._children, 1) 297 self.assertEqual(prefixes[3].prefix, IPNetwork('2001:db8::/48')) 298 self.assertEqual(prefixes[3]._depth, 3) 299 self.assertEqual(prefixes[3]._children, 0) 300 301 def test_update_prefix4(self): 302 # Change 10.0.0.0/24 to 10.0.0.0/12 303 p = Prefix.objects.get(prefix='10.0.0.0/24') 304 p.prefix = '10.0.0.0/12' 305 p.save() 306 307 prefixes = Prefix.objects.filter(prefix__family=4) 308 self.assertEqual(prefixes[0].prefix, IPNetwork('10.0.0.0/8')) 309 self.assertEqual(prefixes[0]._depth, 0) 310 self.assertEqual(prefixes[0]._children, 2) 311 self.assertEqual(prefixes[1].prefix, IPNetwork('10.0.0.0/12')) 312 self.assertEqual(prefixes[1]._depth, 1) 313 self.assertEqual(prefixes[1]._children, 1) 314 self.assertEqual(prefixes[2].prefix, IPNetwork('10.0.0.0/16')) 315 self.assertEqual(prefixes[2]._depth, 2) 316 self.assertEqual(prefixes[2]._children, 0) 317 318 def test_update_prefix6(self): 319 # Change 2001:db8::/48 to 2001:db8::/36 320 p = Prefix.objects.get(prefix='2001:db8::/48') 321 p.prefix = '2001:db8::/36' 322 p.save() 323 324 prefixes = Prefix.objects.filter(prefix__family=6) 325 self.assertEqual(prefixes[0].prefix, IPNetwork('2001:db8::/32')) 326 self.assertEqual(prefixes[0]._depth, 0) 327 self.assertEqual(prefixes[0]._children, 2) 328 self.assertEqual(prefixes[1].prefix, IPNetwork('2001:db8::/36')) 329 self.assertEqual(prefixes[1]._depth, 1) 330 self.assertEqual(prefixes[1]._children, 1) 331 self.assertEqual(prefixes[2].prefix, IPNetwork('2001:db8::/40')) 332 self.assertEqual(prefixes[2]._depth, 2) 333 self.assertEqual(prefixes[2]._children, 0) 334 335 def test_update_prefix_vrf4(self): 336 vrf = VRF(name='VRF A') 337 vrf.save() 338 339 # Move 10.0.0.0/16 to a VRF 340 p = Prefix.objects.get(prefix='10.0.0.0/16') 341 p.vrf = vrf 342 p.save() 343 344 prefixes = Prefix.objects.filter(vrf__isnull=True, prefix__family=4) 345 self.assertEqual(prefixes[0].prefix, IPNetwork('10.0.0.0/8')) 346 self.assertEqual(prefixes[0]._depth, 0) 347 self.assertEqual(prefixes[0]._children, 1) 348 self.assertEqual(prefixes[1].prefix, IPNetwork('10.0.0.0/24')) 349 self.assertEqual(prefixes[1]._depth, 1) 350 self.assertEqual(prefixes[1]._children, 0) 351 352 prefixes = Prefix.objects.filter(vrf=vrf) 353 self.assertEqual(prefixes[0].prefix, IPNetwork('10.0.0.0/16')) 354 self.assertEqual(prefixes[0]._depth, 0) 355 self.assertEqual(prefixes[0]._children, 0) 356 357 def test_update_prefix_vrf6(self): 358 vrf = VRF(name='VRF A') 359 vrf.save() 360 361 # Move 2001:db8::/40 to a VRF 362 p = Prefix.objects.get(prefix='2001:db8::/40') 363 p.vrf = vrf 364 p.save() 365 366 prefixes = Prefix.objects.filter(vrf__isnull=True, prefix__family=6) 367 self.assertEqual(prefixes[0].prefix, IPNetwork('2001:db8::/32')) 368 self.assertEqual(prefixes[0]._depth, 0) 369 self.assertEqual(prefixes[0]._children, 1) 370 self.assertEqual(prefixes[1].prefix, IPNetwork('2001:db8::/48')) 371 self.assertEqual(prefixes[1]._depth, 1) 372 self.assertEqual(prefixes[1]._children, 0) 373 374 prefixes = Prefix.objects.filter(vrf=vrf) 375 self.assertEqual(prefixes[0].prefix, IPNetwork('2001:db8::/40')) 376 self.assertEqual(prefixes[0]._depth, 0) 377 self.assertEqual(prefixes[0]._children, 0) 378 379 def test_delete_prefix4(self): 380 # Delete 10.0.0.0/16 381 Prefix.objects.filter(prefix='10.0.0.0/16').delete() 382 383 prefixes = Prefix.objects.filter(prefix__family=4) 384 self.assertEqual(prefixes[0].prefix, IPNetwork('10.0.0.0/8')) 385 self.assertEqual(prefixes[0]._depth, 0) 386 self.assertEqual(prefixes[0]._children, 1) 387 self.assertEqual(prefixes[1].prefix, IPNetwork('10.0.0.0/24')) 388 self.assertEqual(prefixes[1]._depth, 1) 389 self.assertEqual(prefixes[1]._children, 0) 390 391 def test_delete_prefix6(self): 392 # Delete 2001:db8::/40 393 Prefix.objects.filter(prefix='2001:db8::/40').delete() 394 395 prefixes = Prefix.objects.filter(prefix__family=6) 396 self.assertEqual(prefixes[0].prefix, IPNetwork('2001:db8::/32')) 397 self.assertEqual(prefixes[0]._depth, 0) 398 self.assertEqual(prefixes[0]._children, 1) 399 self.assertEqual(prefixes[1].prefix, IPNetwork('2001:db8::/48')) 400 self.assertEqual(prefixes[1]._depth, 1) 401 self.assertEqual(prefixes[1]._children, 0) 402 403 def test_duplicate_prefix4(self): 404 # Duplicate 10.0.0.0/16 405 Prefix(prefix='10.0.0.0/16').save() 406 407 prefixes = Prefix.objects.filter(prefix__family=4) 408 self.assertEqual(prefixes[0].prefix, IPNetwork('10.0.0.0/8')) 409 self.assertEqual(prefixes[0]._depth, 0) 410 self.assertEqual(prefixes[0]._children, 3) 411 self.assertEqual(prefixes[1].prefix, IPNetwork('10.0.0.0/16')) 412 self.assertEqual(prefixes[1]._depth, 1) 413 self.assertEqual(prefixes[1]._children, 1) 414 self.assertEqual(prefixes[2].prefix, IPNetwork('10.0.0.0/16')) 415 self.assertEqual(prefixes[2]._depth, 1) 416 self.assertEqual(prefixes[2]._children, 1) 417 self.assertEqual(prefixes[3].prefix, IPNetwork('10.0.0.0/24')) 418 self.assertEqual(prefixes[3]._depth, 2) 419 self.assertEqual(prefixes[3]._children, 0) 420 421 def test_duplicate_prefix6(self): 422 # Duplicate 2001:db8::/40 423 Prefix(prefix='2001:db8::/40').save() 424 425 prefixes = Prefix.objects.filter(prefix__family=6) 426 self.assertEqual(prefixes[0].prefix, IPNetwork('2001:db8::/32')) 427 self.assertEqual(prefixes[0]._depth, 0) 428 self.assertEqual(prefixes[0]._children, 3) 429 self.assertEqual(prefixes[1].prefix, IPNetwork('2001:db8::/40')) 430 self.assertEqual(prefixes[1]._depth, 1) 431 self.assertEqual(prefixes[1]._children, 1) 432 self.assertEqual(prefixes[2].prefix, IPNetwork('2001:db8::/40')) 433 self.assertEqual(prefixes[2]._depth, 1) 434 self.assertEqual(prefixes[2]._children, 1) 435 self.assertEqual(prefixes[3].prefix, IPNetwork('2001:db8::/48')) 436 self.assertEqual(prefixes[3]._depth, 2) 437 self.assertEqual(prefixes[3]._children, 0) 438 439 440class TestIPAddress(TestCase): 441 442 def test_get_duplicates(self): 443 ips = IPAddress.objects.bulk_create(( 444 IPAddress(address=IPNetwork('192.0.2.1/24')), 445 IPAddress(address=IPNetwork('192.0.2.1/24')), 446 IPAddress(address=IPNetwork('192.0.2.1/24')), 447 )) 448 duplicate_ip_pks = [p.pk for p in ips[0].get_duplicates()] 449 450 self.assertSetEqual(set(duplicate_ip_pks), {ips[1].pk, ips[2].pk}) 451 452 # 453 # Uniqueness enforcement tests 454 # 455 456 @override_settings(ENFORCE_GLOBAL_UNIQUE=False) 457 def test_duplicate_global(self): 458 IPAddress.objects.create(address=IPNetwork('192.0.2.1/24')) 459 duplicate_ip = IPAddress(address=IPNetwork('192.0.2.1/24')) 460 self.assertIsNone(duplicate_ip.clean()) 461 462 @override_settings(ENFORCE_GLOBAL_UNIQUE=True) 463 def test_duplicate_global_unique(self): 464 IPAddress.objects.create(address=IPNetwork('192.0.2.1/24')) 465 duplicate_ip = IPAddress(address=IPNetwork('192.0.2.1/24')) 466 self.assertRaises(ValidationError, duplicate_ip.clean) 467 468 def test_duplicate_vrf(self): 469 vrf = VRF.objects.create(name='Test', rd='1:1', enforce_unique=False) 470 IPAddress.objects.create(vrf=vrf, address=IPNetwork('192.0.2.1/24')) 471 duplicate_ip = IPAddress(vrf=vrf, address=IPNetwork('192.0.2.1/24')) 472 self.assertIsNone(duplicate_ip.clean()) 473 474 def test_duplicate_vrf_unique(self): 475 vrf = VRF.objects.create(name='Test', rd='1:1', enforce_unique=True) 476 IPAddress.objects.create(vrf=vrf, address=IPNetwork('192.0.2.1/24')) 477 duplicate_ip = IPAddress(vrf=vrf, address=IPNetwork('192.0.2.1/24')) 478 self.assertRaises(ValidationError, duplicate_ip.clean) 479 480 @override_settings(ENFORCE_GLOBAL_UNIQUE=True) 481 def test_duplicate_nonunique_nonrole_role(self): 482 IPAddress.objects.create(address=IPNetwork('192.0.2.1/24')) 483 duplicate_ip = IPAddress(address=IPNetwork('192.0.2.1/24'), role=IPAddressRoleChoices.ROLE_VIP) 484 self.assertRaises(ValidationError, duplicate_ip.clean) 485 486 @override_settings(ENFORCE_GLOBAL_UNIQUE=True) 487 def test_duplicate_nonunique_role_nonrole(self): 488 IPAddress.objects.create(address=IPNetwork('192.0.2.1/24'), role=IPAddressRoleChoices.ROLE_VIP) 489 duplicate_ip = IPAddress(address=IPNetwork('192.0.2.1/24')) 490 self.assertRaises(ValidationError, duplicate_ip.clean) 491 492 @override_settings(ENFORCE_GLOBAL_UNIQUE=True) 493 def test_duplicate_nonunique_role(self): 494 IPAddress.objects.create(address=IPNetwork('192.0.2.1/24'), role=IPAddressRoleChoices.ROLE_VIP) 495 IPAddress.objects.create(address=IPNetwork('192.0.2.1/24'), role=IPAddressRoleChoices.ROLE_VIP) 496 497 498class TestVLANGroup(TestCase): 499 500 def test_get_next_available_vid(self): 501 502 vlangroup = VLANGroup.objects.create(name='VLAN Group 1', slug='vlan-group-1') 503 VLAN.objects.bulk_create(( 504 VLAN(name='VLAN 1', vid=1, group=vlangroup), 505 VLAN(name='VLAN 2', vid=2, group=vlangroup), 506 VLAN(name='VLAN 3', vid=3, group=vlangroup), 507 VLAN(name='VLAN 5', vid=5, group=vlangroup), 508 )) 509 self.assertEqual(vlangroup.get_next_available_vid(), 4) 510 511 VLAN.objects.bulk_create(( 512 VLAN(name='VLAN 4', vid=4, group=vlangroup), 513 )) 514 self.assertEqual(vlangroup.get_next_available_vid(), 6) 515