blob: beb268555e3050700b795ceaafa8c2c926dac6b2 [file] [log] [blame]
Nick Coghlandc9b2552012-05-20 21:01:57 +10001# Copyright 2007 Google Inc.
2# Licensed to PSF under a Contributor Agreement.
Nick Coghlandc9b2552012-05-20 21:01:57 +10003
Nick Coghlanaff73f92012-05-27 00:57:25 +10004"""Unittest for ipaddress module."""
Nick Coghlandc9b2552012-05-20 21:01:57 +10005
6
7import unittest
Nick Coghlan36f8dcd2012-07-07 19:23:53 +10008import re
9import contextlib
Nick Coghlandc9b2552012-05-20 21:01:57 +100010import ipaddress
11
Nick Coghlan36f8dcd2012-07-07 19:23:53 +100012class ErrorReporting(unittest.TestCase):
13 # One big change in ipaddress over the original ipaddr module is
14 # error reporting that tries to assume users *don't know the rules*
15 # for what constitutes an RFC compliant IP address
16
17 # Note that if the constructors are refactored so that addresses with
18 # multiple problems get classified differently, that's OK - just
19 # move the affected examples to the newly appropriate test case.
20
21 # The error reporting tests also cover a few corner cases that
22 # specifically *aren't* errors (such as leading zeroes in v6
23 # address parts) that don't have an obvious home in the main test
24 # suite
25
Nick Coghlan297b1432012-07-08 17:11:04 +100026 @property
27 def factory(self):
28 raise NotImplementedError
29
Nick Coghlan36f8dcd2012-07-07 19:23:53 +100030 @contextlib.contextmanager
31 def assertCleanError(self, exc_type, details, *args):
32 """
33 Ensure exception does not display a context by default
34
35 Wraps unittest.TestCase.assertRaisesRegex
36 """
37 if args:
38 details = details % args
39 cm = self.assertRaisesRegex(exc_type, details)
40 with cm as exc:
41 yield exc
42 # Ensure we produce clean tracebacks on failure
43 if exc.exception.__context__ is not None:
44 self.assertTrue(exc.exception.__suppress_context__)
45
46 def assertAddressError(self, details, *args):
47 """Ensure a clean AddressValueError"""
48 return self.assertCleanError(ipaddress.AddressValueError,
49 details, *args)
50
51 def assertNetmaskError(self, details, *args):
52 """Ensure a clean NetmaskValueError"""
53 return self.assertCleanError(ipaddress.NetmaskValueError,
54 details, *args)
55
Nick Coghlan297b1432012-07-08 17:11:04 +100056class CommonErrorsMixin:
Nick Coghlan36f8dcd2012-07-07 19:23:53 +100057
58 def test_empty_address(self):
59 with self.assertAddressError("Address cannot be empty"):
Nick Coghlan297b1432012-07-08 17:11:04 +100060 self.factory("")
61
62 def test_floats_rejected(self):
63 with self.assertAddressError(re.escape(repr("1.0"))):
64 self.factory(1.0)
65
66class CommonErrorsMixin_v4(CommonErrorsMixin):
67
68 def test_negative_ints_rejected(self):
69 msg = "-1 (< 0) is not permitted as an IPv4 address"
70 with self.assertAddressError(re.escape(msg)):
71 self.factory(-1)
72
73 def test_large_ints_rejected(self):
74 msg = "%d (>= 2**32) is not permitted as an IPv4 address"
75 with self.assertAddressError(re.escape(msg % 2**32)):
76 self.factory(2**32)
77
78 def test_bad_packed_length(self):
79 def assertBadLength(length):
80 addr = b'\x00' * length
81 msg = "%r (len %d != 4) is not permitted as an IPv4 address"
82 with self.assertAddressError(re.escape(msg % (addr, length))):
83 self.factory(addr)
84
85 assertBadLength(3)
86 assertBadLength(5)
87
88class CommonErrorsMixin_v6(CommonErrorsMixin):
89
90 def test_negative_ints_rejected(self):
91 msg = "-1 (< 0) is not permitted as an IPv6 address"
92 with self.assertAddressError(re.escape(msg)):
93 self.factory(-1)
94
95 def test_large_ints_rejected(self):
96 msg = "%d (>= 2**128) is not permitted as an IPv6 address"
97 with self.assertAddressError(re.escape(msg % 2**128)):
98 self.factory(2**128)
99
100 def test_bad_packed_length(self):
101 def assertBadLength(length):
102 addr = b'\x00' * length
103 msg = "%r (len %d != 16) is not permitted as an IPv6 address"
104 with self.assertAddressError(re.escape(msg % (addr, length))):
105 self.factory(addr)
106 self.factory(addr)
107
108 assertBadLength(15)
109 assertBadLength(17)
110
111
112class AddressErrors_v4(ErrorReporting, CommonErrorsMixin_v4):
113 factory = ipaddress.IPv4Address
Nick Coghlan36f8dcd2012-07-07 19:23:53 +1000114
115 def test_network_passed_as_address(self):
116 addr = "127.0.0.1/24"
117 with self.assertAddressError("Unexpected '/' in %r", addr):
118 ipaddress.IPv4Address(addr)
119
120 def test_bad_address_split(self):
121 def assertBadSplit(addr):
122 with self.assertAddressError("Expected 4 octets in %r", addr):
123 ipaddress.IPv4Address(addr)
124
125 assertBadSplit("127.0.1")
126 assertBadSplit("42.42.42.42.42")
127 assertBadSplit("42.42.42")
128 assertBadSplit("42.42")
129 assertBadSplit("42")
130 assertBadSplit("42..42.42.42")
131 assertBadSplit("42.42.42.42.")
132 assertBadSplit("42.42.42.42...")
133 assertBadSplit(".42.42.42.42")
134 assertBadSplit("...42.42.42.42")
135 assertBadSplit("016.016.016")
136 assertBadSplit("016.016")
137 assertBadSplit("016")
138 assertBadSplit("000")
139 assertBadSplit("0x0a.0x0a.0x0a")
140 assertBadSplit("0x0a.0x0a")
141 assertBadSplit("0x0a")
142 assertBadSplit(".")
143 assertBadSplit("bogus")
144 assertBadSplit("bogus.com")
145 assertBadSplit("1000")
146 assertBadSplit("1000000000000000")
147 assertBadSplit("192.168.0.1.com")
148
149 def test_empty_octet(self):
150 def assertBadOctet(addr):
151 with self.assertAddressError("Empty octet not permitted in %r",
152 addr):
153 ipaddress.IPv4Address(addr)
154
155 assertBadOctet("42..42.42")
156 assertBadOctet("...")
157
158 def test_invalid_characters(self):
159 def assertBadOctet(addr, octet):
160 msg = "Only decimal digits permitted in %r in %r" % (octet, addr)
161 with self.assertAddressError(re.escape(msg)):
162 ipaddress.IPv4Address(addr)
163
164 assertBadOctet("0x0a.0x0a.0x0a.0x0a", "0x0a")
165 assertBadOctet("42.42.42.-0", "-0")
166 assertBadOctet("42.42.42.+0", "+0")
167 assertBadOctet("42.42.42.-42", "-42")
168 assertBadOctet("+1.+2.+3.4", "+1")
169 assertBadOctet("1.2.3.4e0", "4e0")
170 assertBadOctet("1.2.3.4::", "4::")
171 assertBadOctet("1.a.2.3", "a")
172
173 def test_leading_zeros(self):
174 def assertBadOctet(addr, octet):
175 msg = "Ambiguous leading zero in %r not permitted in %r"
176 with self.assertAddressError(msg, octet, addr):
177 ipaddress.IPv4Address(addr)
178
179 assertBadOctet("016.016.016.016", "016")
180 assertBadOctet("001.000.008.016", "008")
181 self.assertEqual(ipaddress.IPv4Address("192.168.000.001"),
182 ipaddress.IPv4Address("192.168.0.1"))
183
184 def test_octet_limit(self):
185 def assertBadOctet(addr, octet):
Nick Coghlanb582ecc2012-07-07 22:15:22 +1000186 msg = "Octet %d (> 255) not permitted in %r" % (octet, addr)
187 with self.assertAddressError(re.escape(msg)):
Nick Coghlan36f8dcd2012-07-07 19:23:53 +1000188 ipaddress.IPv4Address(addr)
189
190 assertBadOctet("12345.67899.-54321.-98765", 12345)
191 assertBadOctet("257.0.0.0", 257)
192
Nick Coghlan36f8dcd2012-07-07 19:23:53 +1000193
Nick Coghlan297b1432012-07-08 17:11:04 +1000194class AddressErrors_v6(ErrorReporting, CommonErrorsMixin_v6):
195 factory = ipaddress.IPv6Address
Nick Coghlan36f8dcd2012-07-07 19:23:53 +1000196
197 def test_network_passed_as_address(self):
198 addr = "::1/24"
199 with self.assertAddressError("Unexpected '/' in %r", addr):
200 ipaddress.IPv6Address(addr)
201
202 def test_bad_address_split_v6_not_enough_parts(self):
203 def assertBadSplit(addr):
204 msg = "At least 3 parts expected in %r"
205 with self.assertAddressError(msg, addr):
206 ipaddress.IPv6Address(addr)
207
208 assertBadSplit(":")
209 assertBadSplit(":1")
210 assertBadSplit("FEDC:9878")
211
212 def test_bad_address_split_v6_too_many_colons(self):
213 def assertBadSplit(addr):
214 msg = "At most 8 colons permitted in %r"
215 with self.assertAddressError(msg, addr):
216 ipaddress.IPv6Address(addr)
217
218 assertBadSplit("9:8:7:6:5:4:3::2:1")
219 assertBadSplit("10:9:8:7:6:5:4:3:2:1")
220 assertBadSplit("::8:7:6:5:4:3:2:1")
221 assertBadSplit("8:7:6:5:4:3:2:1::")
222 # A trailing IPv4 address is two parts
223 assertBadSplit("10:9:8:7:6:5:4:3:42.42.42.42")
224
225 def test_bad_address_split_v6_too_many_parts(self):
226 def assertBadSplit(addr):
227 msg = "Exactly 8 parts expected without '::' in %r"
228 with self.assertAddressError(msg, addr):
229 ipaddress.IPv6Address(addr)
230
231 assertBadSplit("3ffe:0:0:0:0:0:0:0:1")
232 assertBadSplit("9:8:7:6:5:4:3:2:1")
233 assertBadSplit("7:6:5:4:3:2:1")
234 # A trailing IPv4 address is two parts
235 assertBadSplit("9:8:7:6:5:4:3:42.42.42.42")
236 assertBadSplit("7:6:5:4:3:42.42.42.42")
237
238 def test_bad_address_split_v6_too_many_parts_with_double_colon(self):
239 def assertBadSplit(addr):
240 msg = "Expected at most 7 other parts with '::' in %r"
241 with self.assertAddressError(msg, addr):
242 ipaddress.IPv6Address(addr)
243
244 assertBadSplit("1:2:3:4::5:6:7:8")
245
246 def test_bad_address_split_v6_repeated_double_colon(self):
247 def assertBadSplit(addr):
248 msg = "At most one '::' permitted in %r"
249 with self.assertAddressError(msg, addr):
250 ipaddress.IPv6Address(addr)
251
252 assertBadSplit("3ffe::1::1")
253 assertBadSplit("1::2::3::4:5")
254 assertBadSplit("2001::db:::1")
255 assertBadSplit("3ffe::1::")
256 assertBadSplit("::3ffe::1")
257 assertBadSplit(":3ffe::1::1")
258 assertBadSplit("3ffe::1::1:")
259 assertBadSplit(":3ffe::1::1:")
260 assertBadSplit(":::")
261 assertBadSplit('2001:db8:::1')
262
263 def test_bad_address_split_v6_leading_colon(self):
264 def assertBadSplit(addr):
265 msg = "Leading ':' only permitted as part of '::' in %r"
266 with self.assertAddressError(msg, addr):
267 ipaddress.IPv6Address(addr)
268
269 assertBadSplit(":2001:db8::1")
270 assertBadSplit(":1:2:3:4:5:6:7")
271 assertBadSplit(":1:2:3:4:5:6:")
272 assertBadSplit(":6:5:4:3:2:1::")
273
274 def test_bad_address_split_v6_trailing_colon(self):
275 def assertBadSplit(addr):
276 msg = "Trailing ':' only permitted as part of '::' in %r"
277 with self.assertAddressError(msg, addr):
278 ipaddress.IPv6Address(addr)
279
280 assertBadSplit("2001:db8::1:")
281 assertBadSplit("1:2:3:4:5:6:7:")
282 assertBadSplit("::1.2.3.4:")
283 assertBadSplit("::7:6:5:4:3:2:")
284
285 def test_bad_v4_part_in(self):
286 def assertBadAddressPart(addr, v4_error):
287 with self.assertAddressError("%s in %r", v4_error, addr):
288 ipaddress.IPv6Address(addr)
289
290 assertBadAddressPart("3ffe::1.net", "Expected 4 octets in '1.net'")
291 assertBadAddressPart("3ffe::127.0.1",
292 "Expected 4 octets in '127.0.1'")
293 assertBadAddressPart("::1.2.3",
294 "Expected 4 octets in '1.2.3'")
295 assertBadAddressPart("::1.2.3.4.5",
296 "Expected 4 octets in '1.2.3.4.5'")
297 assertBadAddressPart("3ffe::1.1.1.net",
298 "Only decimal digits permitted in 'net' "
299 "in '1.1.1.net'")
300
301 def test_invalid_characters(self):
302 def assertBadPart(addr, part):
303 msg = "Only hex digits permitted in %r in %r" % (part, addr)
304 with self.assertAddressError(re.escape(msg)):
305 ipaddress.IPv6Address(addr)
306
307 assertBadPart("3ffe::goog", "goog")
308 assertBadPart("3ffe::-0", "-0")
309 assertBadPart("3ffe::+0", "+0")
310 assertBadPart("3ffe::-1", "-1")
311 assertBadPart("1.2.3.4::", "1.2.3.4")
312 assertBadPart('1234:axy::b', "axy")
313
314 def test_part_length(self):
315 def assertBadPart(addr, part):
316 msg = "At most 4 characters permitted in %r in %r"
317 with self.assertAddressError(msg, part, addr):
318 ipaddress.IPv6Address(addr)
319
320 assertBadPart("3ffe::10000", "10000")
321 assertBadPart("02001:db8::", "02001")
322 assertBadPart('2001:888888::1', "888888")
323
Nick Coghlan36f8dcd2012-07-07 19:23:53 +1000324
Nick Coghlan297b1432012-07-08 17:11:04 +1000325class NetmaskErrorsMixin_v4(CommonErrorsMixin_v4):
Nick Coghlan36f8dcd2012-07-07 19:23:53 +1000326 """Input validation on interfaces and networks is very similar"""
327
Nick Coghlan36f8dcd2012-07-07 19:23:53 +1000328 def test_split_netmask(self):
329 addr = "1.2.3.4/32/24"
330 with self.assertAddressError("Only one '/' permitted in %r" % addr):
331 self.factory(addr)
332
333 def test_address_errors(self):
334 def assertBadAddress(addr, details):
335 with self.assertAddressError(details):
336 self.factory(addr)
337
Nick Coghlan297b1432012-07-08 17:11:04 +1000338 assertBadAddress("/", "Address cannot be empty")
339 assertBadAddress("/8", "Address cannot be empty")
Nick Coghlan36f8dcd2012-07-07 19:23:53 +1000340 assertBadAddress("bogus", "Expected 4 octets")
341 assertBadAddress("google.com", "Expected 4 octets")
342 assertBadAddress("10/8", "Expected 4 octets")
343 assertBadAddress("::1.2.3.4", "Only decimal digits")
Nick Coghlanb582ecc2012-07-07 22:15:22 +1000344 assertBadAddress("1.2.3.256", re.escape("256 (> 255)"))
Nick Coghlan36f8dcd2012-07-07 19:23:53 +1000345
346 def test_netmask_errors(self):
347 def assertBadNetmask(addr, netmask):
348 msg = "%r is not a valid netmask"
349 with self.assertNetmaskError(msg % netmask):
350 self.factory("%s/%s" % (addr, netmask))
351
352 assertBadNetmask("1.2.3.4", "")
353 assertBadNetmask("1.2.3.4", "33")
354 assertBadNetmask("1.2.3.4", "254.254.255.256")
355 assertBadNetmask("1.1.1.1", "240.255.0.0")
356 assertBadNetmask("1.1.1.1", "1.a.2.3")
357 assertBadNetmask("1.1.1.1", "pudding")
358
Nick Coghlan36f8dcd2012-07-07 19:23:53 +1000359class InterfaceErrors_v4(ErrorReporting, NetmaskErrorsMixin_v4):
360 factory = ipaddress.IPv4Interface
361
362class NetworkErrors_v4(ErrorReporting, NetmaskErrorsMixin_v4):
363 factory = ipaddress.IPv4Network
364
365
Nick Coghlan297b1432012-07-08 17:11:04 +1000366class NetmaskErrorsMixin_v6(CommonErrorsMixin_v6):
Nick Coghlan36f8dcd2012-07-07 19:23:53 +1000367 """Input validation on interfaces and networks is very similar"""
368
Nick Coghlan36f8dcd2012-07-07 19:23:53 +1000369 def test_split_netmask(self):
370 addr = "cafe:cafe::/128/190"
371 with self.assertAddressError("Only one '/' permitted in %r" % addr):
372 self.factory(addr)
373
374 def test_address_errors(self):
375 def assertBadAddress(addr, details):
376 with self.assertAddressError(details):
377 self.factory(addr)
378
Nick Coghlan297b1432012-07-08 17:11:04 +1000379 assertBadAddress("/", "Address cannot be empty")
380 assertBadAddress("/8", "Address cannot be empty")
Nick Coghlan36f8dcd2012-07-07 19:23:53 +1000381 assertBadAddress("google.com", "At least 3 parts")
382 assertBadAddress("1.2.3.4", "At least 3 parts")
383 assertBadAddress("10/8", "At least 3 parts")
384 assertBadAddress("1234:axy::b", "Only hex digits")
385
386 def test_netmask_errors(self):
387 def assertBadNetmask(addr, netmask):
388 msg = "%r is not a valid netmask"
389 with self.assertNetmaskError(msg % netmask):
390 self.factory("%s/%s" % (addr, netmask))
391
392 assertBadNetmask("::1", "")
393 assertBadNetmask("::1", "::1")
394 assertBadNetmask("::1", "1::")
395 assertBadNetmask("::1", "129")
396 assertBadNetmask("::1", "pudding")
397
Nick Coghlan36f8dcd2012-07-07 19:23:53 +1000398class InterfaceErrors_v6(ErrorReporting, NetmaskErrorsMixin_v6):
399 factory = ipaddress.IPv6Interface
400
401class NetworkErrors_v6(ErrorReporting, NetmaskErrorsMixin_v6):
402 factory = ipaddress.IPv6Network
403
404
405class FactoryFunctionErrors(ErrorReporting):
406
407 def assertFactoryError(self, factory, kind):
408 """Ensure a clean ValueError with the expected message"""
409 addr = "camelot"
410 msg = '%r does not appear to be an IPv4 or IPv6 %s'
411 with self.assertCleanError(ValueError, msg, addr, kind):
412 factory(addr)
413
414 def test_ip_address(self):
415 self.assertFactoryError(ipaddress.ip_address, "address")
416
417 def test_ip_interface(self):
418 self.assertFactoryError(ipaddress.ip_interface, "interface")
419
420 def test_ip_network(self):
421 self.assertFactoryError(ipaddress.ip_network, "network")
422
Hynek Schlawack91c5a342012-06-05 11:55:58 +0200423
Nick Coghlan3008ec02012-07-08 00:45:33 +1000424class ComparisonTests(unittest.TestCase):
425
426 v4addr = ipaddress.IPv4Address(1)
427 v4net = ipaddress.IPv4Network(1)
428 v4intf = ipaddress.IPv4Interface(1)
429 v6addr = ipaddress.IPv6Address(1)
430 v6net = ipaddress.IPv6Network(1)
431 v6intf = ipaddress.IPv6Interface(1)
432
433 v4_addresses = [v4addr, v4intf]
434 v4_objects = v4_addresses + [v4net]
435 v6_addresses = [v6addr, v6intf]
436 v6_objects = v6_addresses + [v6net]
437 objects = v4_objects + v6_objects
438
439 def test_foreign_type_equality(self):
440 # __eq__ should never raise TypeError directly
441 other = object()
442 for obj in self.objects:
443 self.assertNotEqual(obj, other)
444 self.assertFalse(obj == other)
445 self.assertEqual(obj.__eq__(other), NotImplemented)
446 self.assertEqual(obj.__ne__(other), NotImplemented)
447
448 def test_mixed_type_equality(self):
449 # Ensure none of the internal objects accidentally
450 # expose the right set of attributes to become "equal"
451 for lhs in self.objects:
452 for rhs in self.objects:
453 if lhs is rhs:
454 continue
455 self.assertNotEqual(lhs, rhs)
456
457 def test_containment(self):
458 for obj in self.v4_addresses:
459 self.assertIn(obj, self.v4net)
460 for obj in self.v6_addresses:
461 self.assertIn(obj, self.v6net)
462 for obj in self.v4_objects + [self.v6net]:
463 self.assertNotIn(obj, self.v6net)
464 for obj in self.v6_objects + [self.v4net]:
465 self.assertNotIn(obj, self.v4net)
466
467 def test_mixed_type_ordering(self):
468 for lhs in self.objects:
469 for rhs in self.objects:
470 if isinstance(lhs, type(rhs)) or isinstance(rhs, type(lhs)):
471 continue
472 self.assertRaises(TypeError, lambda: lhs < rhs)
473 self.assertRaises(TypeError, lambda: lhs > rhs)
474 self.assertRaises(TypeError, lambda: lhs <= rhs)
475 self.assertRaises(TypeError, lambda: lhs >= rhs)
476
477 def test_mixed_type_key(self):
478 # with get_mixed_type_key, you can sort addresses and network.
479 v4_ordered = [self.v4addr, self.v4net, self.v4intf]
480 v6_ordered = [self.v6addr, self.v6net, self.v6intf]
481 self.assertEqual(v4_ordered,
482 sorted(self.v4_objects,
483 key=ipaddress.get_mixed_type_key))
484 self.assertEqual(v6_ordered,
485 sorted(self.v6_objects,
486 key=ipaddress.get_mixed_type_key))
487 self.assertEqual(v4_ordered + v6_ordered,
488 sorted(self.objects,
489 key=ipaddress.get_mixed_type_key))
490 self.assertEqual(NotImplemented, ipaddress.get_mixed_type_key(object))
491
492 def test_incompatible_versions(self):
493 # These should always raise TypeError
494 v4addr = ipaddress.ip_address('1.1.1.1')
495 v4net = ipaddress.ip_network('1.1.1.1')
496 v6addr = ipaddress.ip_address('::1')
497 v6net = ipaddress.ip_address('::1')
498
499 self.assertRaises(TypeError, v4addr.__lt__, v6addr)
500 self.assertRaises(TypeError, v4addr.__gt__, v6addr)
501 self.assertRaises(TypeError, v4net.__lt__, v6net)
502 self.assertRaises(TypeError, v4net.__gt__, v6net)
503
504 self.assertRaises(TypeError, v6addr.__lt__, v4addr)
505 self.assertRaises(TypeError, v6addr.__gt__, v4addr)
506 self.assertRaises(TypeError, v6net.__lt__, v4net)
507 self.assertRaises(TypeError, v6net.__gt__, v4net)
508
509
510
Nick Coghlandc9b2552012-05-20 21:01:57 +1000511class IpaddrUnitTest(unittest.TestCase):
512
513 def setUp(self):
514 self.ipv4_address = ipaddress.IPv4Address('1.2.3.4')
515 self.ipv4_interface = ipaddress.IPv4Interface('1.2.3.4/24')
516 self.ipv4_network = ipaddress.IPv4Network('1.2.3.0/24')
517 #self.ipv4_hostmask = ipaddress.IPv4Interface('10.0.0.1/0.255.255.255')
518 self.ipv6_address = ipaddress.IPv6Interface(
519 '2001:658:22a:cafe:200:0:0:1')
520 self.ipv6_interface = ipaddress.IPv6Interface(
521 '2001:658:22a:cafe:200:0:0:1/64')
522 self.ipv6_network = ipaddress.IPv6Network('2001:658:22a:cafe::/64')
523
524 def testRepr(self):
525 self.assertEqual("IPv4Interface('1.2.3.4/32')",
526 repr(ipaddress.IPv4Interface('1.2.3.4')))
527 self.assertEqual("IPv6Interface('::1/128')",
528 repr(ipaddress.IPv6Interface('::1')))
529
530 # issue57
531 def testAddressIntMath(self):
532 self.assertEqual(ipaddress.IPv4Address('1.1.1.1') + 255,
533 ipaddress.IPv4Address('1.1.2.0'))
534 self.assertEqual(ipaddress.IPv4Address('1.1.1.1') - 256,
535 ipaddress.IPv4Address('1.1.0.1'))
536 self.assertEqual(ipaddress.IPv6Address('::1') + (2**16 - 2),
537 ipaddress.IPv6Address('::ffff'))
538 self.assertEqual(ipaddress.IPv6Address('::ffff') - (2**16 - 2),
539 ipaddress.IPv6Address('::1'))
540
Nick Coghlan3c2570c2012-07-07 01:13:55 +1000541 def testInvalidIntToBytes(self):
542 self.assertRaises(ValueError, ipaddress.v4_int_to_packed, -1)
543 self.assertRaises(ValueError, ipaddress.v4_int_to_packed,
544 2 ** ipaddress.IPV4LENGTH)
545 self.assertRaises(ValueError, ipaddress.v6_int_to_packed, -1)
546 self.assertRaises(ValueError, ipaddress.v6_int_to_packed,
547 2 ** ipaddress.IPV6LENGTH)
548
Hynek Schlawack91c5a342012-06-05 11:55:58 +0200549 def testInternals(self):
550 first, last = ipaddress._find_address_range([
551 ipaddress.IPv4Address('10.10.10.10'),
552 ipaddress.IPv4Address('10.10.10.12')])
553 self.assertEqual(first, last)
Hynek Schlawack91c5a342012-06-05 11:55:58 +0200554 self.assertEqual(128, ipaddress._count_righthand_zero_bits(0, 128))
Hynek Schlawack91c5a342012-06-05 11:55:58 +0200555 self.assertEqual("IPv4Network('1.2.3.0/24')", repr(self.ipv4_network))
556 self.assertEqual('0x1020318', hex(self.ipv4_network))
Nick Coghlandc9b2552012-05-20 21:01:57 +1000557
Nick Coghland9722652012-06-17 16:33:00 +1000558 def testMissingAddressVersion(self):
559 class Broken(ipaddress._BaseAddress):
560 pass
561 broken = Broken('127.0.0.1')
562 with self.assertRaisesRegex(NotImplementedError, "Broken.*version"):
563 broken.version
564
565 def testMissingNetworkVersion(self):
566 class Broken(ipaddress._BaseNetwork):
567 pass
568 broken = Broken('127.0.0.1')
569 with self.assertRaisesRegex(NotImplementedError, "Broken.*version"):
570 broken.version
571
572 def testMissingAddressClass(self):
573 class Broken(ipaddress._BaseNetwork):
574 pass
575 broken = Broken('127.0.0.1')
576 with self.assertRaisesRegex(NotImplementedError, "Broken.*address"):
577 broken._address_class
578
Nick Coghlandc9b2552012-05-20 21:01:57 +1000579 def testGetNetwork(self):
580 self.assertEqual(int(self.ipv4_network.network_address), 16909056)
581 self.assertEqual(str(self.ipv4_network.network_address), '1.2.3.0')
582
583 self.assertEqual(int(self.ipv6_network.network_address),
584 42540616829182469433403647294022090752)
585 self.assertEqual(str(self.ipv6_network.network_address),
586 '2001:658:22a:cafe::')
587 self.assertEqual(str(self.ipv6_network.hostmask),
588 '::ffff:ffff:ffff:ffff')
589
Nick Coghlandc9b2552012-05-20 21:01:57 +1000590 def testIpFromInt(self):
591 self.assertEqual(self.ipv4_interface._ip,
592 ipaddress.IPv4Interface(16909060)._ip)
Nick Coghlandc9b2552012-05-20 21:01:57 +1000593
594 ipv4 = ipaddress.ip_network('1.2.3.4')
595 ipv6 = ipaddress.ip_network('2001:658:22a:cafe:200:0:0:1')
596 self.assertEqual(ipv4, ipaddress.ip_network(int(ipv4)))
597 self.assertEqual(ipv6, ipaddress.ip_network(int(ipv6)))
598
599 v6_int = 42540616829182469433547762482097946625
600 self.assertEqual(self.ipv6_interface._ip,
601 ipaddress.IPv6Interface(v6_int)._ip)
Nick Coghlandc9b2552012-05-20 21:01:57 +1000602
Hynek Schlawack91c5a342012-06-05 11:55:58 +0200603 self.assertEqual(ipaddress.ip_network(self.ipv4_address._ip).version,
604 4)
605 self.assertEqual(ipaddress.ip_network(self.ipv6_address._ip).version,
606 6)
Nick Coghlandc9b2552012-05-20 21:01:57 +1000607
608 def testIpFromPacked(self):
Nick Coghlan5cf896f2012-07-07 01:43:31 +1000609 address = ipaddress.ip_address
Nick Coghlandc9b2552012-05-20 21:01:57 +1000610 self.assertEqual(self.ipv4_interface._ip,
Nick Coghlan5cf896f2012-07-07 01:43:31 +1000611 ipaddress.ip_interface(b'\x01\x02\x03\x04')._ip)
612 self.assertEqual(address('255.254.253.252'),
613 address(b'\xff\xfe\xfd\xfc'))
Nick Coghlandc9b2552012-05-20 21:01:57 +1000614 self.assertEqual(self.ipv6_interface.ip,
615 ipaddress.ip_interface(
Nick Coghlan5cf896f2012-07-07 01:43:31 +1000616 b'\x20\x01\x06\x58\x02\x2a\xca\xfe'
617 b'\x02\x00\x00\x00\x00\x00\x00\x01').ip)
618 self.assertEqual(address('ffff:2:3:4:ffff::'),
619 address(b'\xff\xff\x00\x02\x00\x03\x00\x04' +
620 b'\xff\xff' + b'\x00' * 6))
621 self.assertEqual(address('::'),
622 address(b'\x00' * 16))
623
Nick Coghlandc9b2552012-05-20 21:01:57 +1000624 def testGetIp(self):
625 self.assertEqual(int(self.ipv4_interface.ip), 16909060)
626 self.assertEqual(str(self.ipv4_interface.ip), '1.2.3.4')
627
628 self.assertEqual(int(self.ipv6_interface.ip),
629 42540616829182469433547762482097946625)
630 self.assertEqual(str(self.ipv6_interface.ip),
631 '2001:658:22a:cafe:200::1')
632
633 def testGetNetmask(self):
634 self.assertEqual(int(self.ipv4_network.netmask), 4294967040)
635 self.assertEqual(str(self.ipv4_network.netmask), '255.255.255.0')
636 self.assertEqual(int(self.ipv6_network.netmask),
637 340282366920938463444927863358058659840)
638 self.assertEqual(self.ipv6_network.prefixlen, 64)
639
640 def testZeroNetmask(self):
641 ipv4_zero_netmask = ipaddress.IPv4Interface('1.2.3.4/0')
642 self.assertEqual(int(ipv4_zero_netmask.network.netmask), 0)
643 self.assertTrue(ipv4_zero_netmask.network._is_valid_netmask(
644 str(0)))
Hynek Schlawack91c5a342012-06-05 11:55:58 +0200645 self.assertTrue(ipv4_zero_netmask._is_valid_netmask('0'))
646 self.assertTrue(ipv4_zero_netmask._is_valid_netmask('0.0.0.0'))
647 self.assertFalse(ipv4_zero_netmask._is_valid_netmask('invalid'))
Nick Coghlandc9b2552012-05-20 21:01:57 +1000648
649 ipv6_zero_netmask = ipaddress.IPv6Interface('::1/0')
650 self.assertEqual(int(ipv6_zero_netmask.network.netmask), 0)
651 self.assertTrue(ipv6_zero_netmask.network._is_valid_netmask(
652 str(0)))
653
Hynek Schlawack91c5a342012-06-05 11:55:58 +0200654 def testIPv4NetAndHostmasks(self):
655 net = self.ipv4_network
656 self.assertFalse(net._is_valid_netmask('invalid'))
657 self.assertTrue(net._is_valid_netmask('128.128.128.128'))
658 self.assertFalse(net._is_valid_netmask('128.128.128.127'))
659 self.assertFalse(net._is_valid_netmask('128.128.128.255'))
660 self.assertTrue(net._is_valid_netmask('255.128.128.128'))
661
662 self.assertFalse(net._is_hostmask('invalid'))
663 self.assertTrue(net._is_hostmask('128.255.255.255'))
664 self.assertFalse(net._is_hostmask('255.255.255.255'))
665 self.assertFalse(net._is_hostmask('1.2.3.4'))
666
667 net = ipaddress.IPv4Network('127.0.0.0/0.0.0.255')
668 self.assertEqual(24, net.prefixlen)
669
Nick Coghlandc9b2552012-05-20 21:01:57 +1000670 def testGetBroadcast(self):
671 self.assertEqual(int(self.ipv4_network.broadcast_address), 16909311)
672 self.assertEqual(str(self.ipv4_network.broadcast_address), '1.2.3.255')
673
674 self.assertEqual(int(self.ipv6_network.broadcast_address),
675 42540616829182469451850391367731642367)
676 self.assertEqual(str(self.ipv6_network.broadcast_address),
677 '2001:658:22a:cafe:ffff:ffff:ffff:ffff')
678
679 def testGetPrefixlen(self):
680 self.assertEqual(self.ipv4_interface.prefixlen, 24)
681 self.assertEqual(self.ipv6_interface.prefixlen, 64)
682
683 def testGetSupernet(self):
684 self.assertEqual(self.ipv4_network.supernet().prefixlen, 23)
685 self.assertEqual(str(self.ipv4_network.supernet().network_address),
686 '1.2.2.0')
687 self.assertEqual(
688 ipaddress.IPv4Interface('0.0.0.0/0').network.supernet(),
689 ipaddress.IPv4Network('0.0.0.0/0'))
690
691 self.assertEqual(self.ipv6_network.supernet().prefixlen, 63)
692 self.assertEqual(str(self.ipv6_network.supernet().network_address),
693 '2001:658:22a:cafe::')
694 self.assertEqual(ipaddress.IPv6Interface('::0/0').network.supernet(),
695 ipaddress.IPv6Network('::0/0'))
696
697 def testGetSupernet3(self):
698 self.assertEqual(self.ipv4_network.supernet(3).prefixlen, 21)
699 self.assertEqual(str(self.ipv4_network.supernet(3).network_address),
700 '1.2.0.0')
701
702 self.assertEqual(self.ipv6_network.supernet(3).prefixlen, 61)
703 self.assertEqual(str(self.ipv6_network.supernet(3).network_address),
704 '2001:658:22a:caf8::')
705
706 def testGetSupernet4(self):
707 self.assertRaises(ValueError, self.ipv4_network.supernet,
708 prefixlen_diff=2, new_prefix=1)
Hynek Schlawack91c5a342012-06-05 11:55:58 +0200709 self.assertRaises(ValueError, self.ipv4_network.supernet,
710 new_prefix=25)
Nick Coghlandc9b2552012-05-20 21:01:57 +1000711 self.assertEqual(self.ipv4_network.supernet(prefixlen_diff=2),
712 self.ipv4_network.supernet(new_prefix=22))
713
714 self.assertRaises(ValueError, self.ipv6_network.supernet,
715 prefixlen_diff=2, new_prefix=1)
Hynek Schlawack91c5a342012-06-05 11:55:58 +0200716 self.assertRaises(ValueError, self.ipv6_network.supernet,
717 new_prefix=65)
Nick Coghlandc9b2552012-05-20 21:01:57 +1000718 self.assertEqual(self.ipv6_network.supernet(prefixlen_diff=2),
719 self.ipv6_network.supernet(new_prefix=62))
720
721 def testHosts(self):
Hynek Schlawack91c5a342012-06-05 11:55:58 +0200722 hosts = list(self.ipv4_network.hosts())
723 self.assertEqual(254, len(hosts))
724 self.assertEqual(ipaddress.IPv4Address('1.2.3.1'), hosts[0])
725 self.assertEqual(ipaddress.IPv4Address('1.2.3.254'), hosts[-1])
726
727 # special case where only 1 bit is left for address
Nick Coghlandc9b2552012-05-20 21:01:57 +1000728 self.assertEqual([ipaddress.IPv4Address('2.0.0.0'),
729 ipaddress.IPv4Address('2.0.0.1')],
730 list(ipaddress.ip_network('2.0.0.0/31').hosts()))
731
732 def testFancySubnetting(self):
733 self.assertEqual(sorted(self.ipv4_network.subnets(prefixlen_diff=3)),
734 sorted(self.ipv4_network.subnets(new_prefix=27)))
735 self.assertRaises(ValueError, list,
736 self.ipv4_network.subnets(new_prefix=23))
737 self.assertRaises(ValueError, list,
738 self.ipv4_network.subnets(prefixlen_diff=3,
739 new_prefix=27))
740 self.assertEqual(sorted(self.ipv6_network.subnets(prefixlen_diff=4)),
741 sorted(self.ipv6_network.subnets(new_prefix=68)))
742 self.assertRaises(ValueError, list,
743 self.ipv6_network.subnets(new_prefix=63))
744 self.assertRaises(ValueError, list,
745 self.ipv6_network.subnets(prefixlen_diff=4,
746 new_prefix=68))
747
748 def testGetSubnets(self):
749 self.assertEqual(list(self.ipv4_network.subnets())[0].prefixlen, 25)
750 self.assertEqual(str(list(
751 self.ipv4_network.subnets())[0].network_address),
752 '1.2.3.0')
753 self.assertEqual(str(list(
754 self.ipv4_network.subnets())[1].network_address),
755 '1.2.3.128')
756
757 self.assertEqual(list(self.ipv6_network.subnets())[0].prefixlen, 65)
758
759 def testGetSubnetForSingle32(self):
760 ip = ipaddress.IPv4Network('1.2.3.4/32')
761 subnets1 = [str(x) for x in ip.subnets()]
762 subnets2 = [str(x) for x in ip.subnets(2)]
763 self.assertEqual(subnets1, ['1.2.3.4/32'])
764 self.assertEqual(subnets1, subnets2)
765
766 def testGetSubnetForSingle128(self):
767 ip = ipaddress.IPv6Network('::1/128')
768 subnets1 = [str(x) for x in ip.subnets()]
769 subnets2 = [str(x) for x in ip.subnets(2)]
770 self.assertEqual(subnets1, ['::1/128'])
771 self.assertEqual(subnets1, subnets2)
772
773 def testSubnet2(self):
774 ips = [str(x) for x in self.ipv4_network.subnets(2)]
775 self.assertEqual(
776 ips,
777 ['1.2.3.0/26', '1.2.3.64/26', '1.2.3.128/26', '1.2.3.192/26'])
778
779 ipsv6 = [str(x) for x in self.ipv6_network.subnets(2)]
780 self.assertEqual(
781 ipsv6,
782 ['2001:658:22a:cafe::/66',
783 '2001:658:22a:cafe:4000::/66',
784 '2001:658:22a:cafe:8000::/66',
785 '2001:658:22a:cafe:c000::/66'])
786
787 def testSubnetFailsForLargeCidrDiff(self):
788 self.assertRaises(ValueError, list,
789 self.ipv4_interface.network.subnets(9))
790 self.assertRaises(ValueError, list,
791 self.ipv4_network.subnets(9))
792 self.assertRaises(ValueError, list,
793 self.ipv6_interface.network.subnets(65))
794 self.assertRaises(ValueError, list,
795 self.ipv6_network.subnets(65))
796
797 def testSupernetFailsForLargeCidrDiff(self):
798 self.assertRaises(ValueError,
799 self.ipv4_interface.network.supernet, 25)
800 self.assertRaises(ValueError,
801 self.ipv6_interface.network.supernet, 65)
802
803 def testSubnetFailsForNegativeCidrDiff(self):
804 self.assertRaises(ValueError, list,
805 self.ipv4_interface.network.subnets(-1))
806 self.assertRaises(ValueError, list,
Nick Coghlan2c589102012-05-27 01:03:25 +1000807 self.ipv4_network.subnets(-1))
Nick Coghlandc9b2552012-05-20 21:01:57 +1000808 self.assertRaises(ValueError, list,
809 self.ipv6_interface.network.subnets(-1))
810 self.assertRaises(ValueError, list,
811 self.ipv6_network.subnets(-1))
812
813 def testGetNum_Addresses(self):
814 self.assertEqual(self.ipv4_network.num_addresses, 256)
Hynek Schlawack91c5a342012-06-05 11:55:58 +0200815 self.assertEqual(list(self.ipv4_network.subnets())[0].num_addresses,
816 128)
Nick Coghlandc9b2552012-05-20 21:01:57 +1000817 self.assertEqual(self.ipv4_network.supernet().num_addresses, 512)
818
819 self.assertEqual(self.ipv6_network.num_addresses, 18446744073709551616)
820 self.assertEqual(list(self.ipv6_network.subnets())[0].num_addresses,
821 9223372036854775808)
822 self.assertEqual(self.ipv6_network.supernet().num_addresses,
823 36893488147419103232)
824
825 def testContains(self):
826 self.assertTrue(ipaddress.IPv4Interface('1.2.3.128/25') in
827 self.ipv4_network)
828 self.assertFalse(ipaddress.IPv4Interface('1.2.4.1/24') in
829 self.ipv4_network)
830 # We can test addresses and string as well.
831 addr1 = ipaddress.IPv4Address('1.2.3.37')
832 self.assertTrue(addr1 in self.ipv4_network)
833 # issue 61, bad network comparison on like-ip'd network objects
834 # with identical broadcast addresses.
835 self.assertFalse(ipaddress.IPv4Network('1.1.0.0/16').__contains__(
836 ipaddress.IPv4Network('1.0.0.0/15')))
837
Nick Coghlandc9b2552012-05-20 21:01:57 +1000838 def testNth(self):
839 self.assertEqual(str(self.ipv4_network[5]), '1.2.3.5')
840 self.assertRaises(IndexError, self.ipv4_network.__getitem__, 256)
841
842 self.assertEqual(str(self.ipv6_network[5]),
843 '2001:658:22a:cafe::5')
844
845 def testGetitem(self):
846 # http://code.google.com/p/ipaddr-py/issues/detail?id=15
847 addr = ipaddress.IPv4Network('172.31.255.128/255.255.255.240')
848 self.assertEqual(28, addr.prefixlen)
849 addr_list = list(addr)
850 self.assertEqual('172.31.255.128', str(addr_list[0]))
851 self.assertEqual('172.31.255.128', str(addr[0]))
852 self.assertEqual('172.31.255.143', str(addr_list[-1]))
853 self.assertEqual('172.31.255.143', str(addr[-1]))
854 self.assertEqual(addr_list[-1], addr[-1])
855
856 def testEqual(self):
857 self.assertTrue(self.ipv4_interface ==
858 ipaddress.IPv4Interface('1.2.3.4/24'))
859 self.assertFalse(self.ipv4_interface ==
860 ipaddress.IPv4Interface('1.2.3.4/23'))
861 self.assertFalse(self.ipv4_interface ==
862 ipaddress.IPv6Interface('::1.2.3.4/24'))
863 self.assertFalse(self.ipv4_interface == '')
864 self.assertFalse(self.ipv4_interface == [])
865 self.assertFalse(self.ipv4_interface == 2)
866
867 self.assertTrue(self.ipv6_interface ==
868 ipaddress.IPv6Interface('2001:658:22a:cafe:200::1/64'))
869 self.assertFalse(self.ipv6_interface ==
870 ipaddress.IPv6Interface('2001:658:22a:cafe:200::1/63'))
871 self.assertFalse(self.ipv6_interface ==
872 ipaddress.IPv4Interface('1.2.3.4/23'))
873 self.assertFalse(self.ipv6_interface == '')
874 self.assertFalse(self.ipv6_interface == [])
875 self.assertFalse(self.ipv6_interface == 2)
876
877 def testNotEqual(self):
878 self.assertFalse(self.ipv4_interface !=
879 ipaddress.IPv4Interface('1.2.3.4/24'))
880 self.assertTrue(self.ipv4_interface !=
881 ipaddress.IPv4Interface('1.2.3.4/23'))
882 self.assertTrue(self.ipv4_interface !=
883 ipaddress.IPv6Interface('::1.2.3.4/24'))
884 self.assertTrue(self.ipv4_interface != '')
885 self.assertTrue(self.ipv4_interface != [])
886 self.assertTrue(self.ipv4_interface != 2)
887
888 self.assertTrue(self.ipv4_address !=
889 ipaddress.IPv4Address('1.2.3.5'))
890 self.assertTrue(self.ipv4_address != '')
891 self.assertTrue(self.ipv4_address != [])
892 self.assertTrue(self.ipv4_address != 2)
893
894 self.assertFalse(self.ipv6_interface !=
895 ipaddress.IPv6Interface('2001:658:22a:cafe:200::1/64'))
896 self.assertTrue(self.ipv6_interface !=
897 ipaddress.IPv6Interface('2001:658:22a:cafe:200::1/63'))
898 self.assertTrue(self.ipv6_interface !=
899 ipaddress.IPv4Interface('1.2.3.4/23'))
900 self.assertTrue(self.ipv6_interface != '')
901 self.assertTrue(self.ipv6_interface != [])
902 self.assertTrue(self.ipv6_interface != 2)
903
904 self.assertTrue(self.ipv6_address !=
905 ipaddress.IPv4Address('1.2.3.4'))
906 self.assertTrue(self.ipv6_address != '')
907 self.assertTrue(self.ipv6_address != [])
908 self.assertTrue(self.ipv6_address != 2)
909
910 def testSlash32Constructor(self):
911 self.assertEqual(str(ipaddress.IPv4Interface(
912 '1.2.3.4/255.255.255.255')), '1.2.3.4/32')
913
914 def testSlash128Constructor(self):
915 self.assertEqual(str(ipaddress.IPv6Interface('::1/128')),
916 '::1/128')
917
918 def testSlash0Constructor(self):
919 self.assertEqual(str(ipaddress.IPv4Interface('1.2.3.4/0.0.0.0')),
920 '1.2.3.4/0')
921
922 def testCollapsing(self):
923 # test only IP addresses including some duplicates
924 ip1 = ipaddress.IPv4Address('1.1.1.0')
925 ip2 = ipaddress.IPv4Address('1.1.1.1')
926 ip3 = ipaddress.IPv4Address('1.1.1.2')
927 ip4 = ipaddress.IPv4Address('1.1.1.3')
928 ip5 = ipaddress.IPv4Address('1.1.1.4')
929 ip6 = ipaddress.IPv4Address('1.1.1.0')
930 # check that addreses are subsumed properly.
931 collapsed = ipaddress.collapse_addresses(
932 [ip1, ip2, ip3, ip4, ip5, ip6])
Hynek Schlawack91c5a342012-06-05 11:55:58 +0200933 self.assertEqual(list(collapsed),
934 [ipaddress.IPv4Network('1.1.1.0/30'),
935 ipaddress.IPv4Network('1.1.1.4/32')])
Nick Coghlandc9b2552012-05-20 21:01:57 +1000936
937 # test a mix of IP addresses and networks including some duplicates
938 ip1 = ipaddress.IPv4Address('1.1.1.0')
939 ip2 = ipaddress.IPv4Address('1.1.1.1')
940 ip3 = ipaddress.IPv4Address('1.1.1.2')
941 ip4 = ipaddress.IPv4Address('1.1.1.3')
942 #ip5 = ipaddress.IPv4Interface('1.1.1.4/30')
943 #ip6 = ipaddress.IPv4Interface('1.1.1.4/30')
944 # check that addreses are subsumed properly.
945 collapsed = ipaddress.collapse_addresses([ip1, ip2, ip3, ip4])
Hynek Schlawack91c5a342012-06-05 11:55:58 +0200946 self.assertEqual(list(collapsed),
947 [ipaddress.IPv4Network('1.1.1.0/30')])
Nick Coghlandc9b2552012-05-20 21:01:57 +1000948
949 # test only IP networks
950 ip1 = ipaddress.IPv4Network('1.1.0.0/24')
951 ip2 = ipaddress.IPv4Network('1.1.1.0/24')
952 ip3 = ipaddress.IPv4Network('1.1.2.0/24')
953 ip4 = ipaddress.IPv4Network('1.1.3.0/24')
954 ip5 = ipaddress.IPv4Network('1.1.4.0/24')
Hynek Schlawack91c5a342012-06-05 11:55:58 +0200955 # stored in no particular order b/c we want CollapseAddr to call
956 # [].sort
Nick Coghlandc9b2552012-05-20 21:01:57 +1000957 ip6 = ipaddress.IPv4Network('1.1.0.0/22')
958 # check that addreses are subsumed properly.
959 collapsed = ipaddress.collapse_addresses([ip1, ip2, ip3, ip4, ip5,
960 ip6])
Hynek Schlawack91c5a342012-06-05 11:55:58 +0200961 self.assertEqual(list(collapsed),
962 [ipaddress.IPv4Network('1.1.0.0/22'),
963 ipaddress.IPv4Network('1.1.4.0/24')])
Nick Coghlandc9b2552012-05-20 21:01:57 +1000964
965 # test that two addresses are supernet'ed properly
966 collapsed = ipaddress.collapse_addresses([ip1, ip2])
Hynek Schlawack91c5a342012-06-05 11:55:58 +0200967 self.assertEqual(list(collapsed),
968 [ipaddress.IPv4Network('1.1.0.0/23')])
Nick Coghlandc9b2552012-05-20 21:01:57 +1000969
970 # test same IP networks
971 ip_same1 = ip_same2 = ipaddress.IPv4Network('1.1.1.1/32')
972 self.assertEqual(list(ipaddress.collapse_addresses(
973 [ip_same1, ip_same2])),
974 [ip_same1])
975
976 # test same IP addresses
977 ip_same1 = ip_same2 = ipaddress.IPv4Address('1.1.1.1')
978 self.assertEqual(list(ipaddress.collapse_addresses(
979 [ip_same1, ip_same2])),
980 [ipaddress.ip_network('1.1.1.1/32')])
981 ip1 = ipaddress.IPv6Network('2001::/100')
982 ip2 = ipaddress.IPv6Network('2001::/120')
983 ip3 = ipaddress.IPv6Network('2001::/96')
984 # test that ipv6 addresses are subsumed properly.
985 collapsed = ipaddress.collapse_addresses([ip1, ip2, ip3])
986 self.assertEqual(list(collapsed), [ip3])
987
988 # the toejam test
Hynek Schlawack35db5132012-06-01 20:12:17 +0200989 addr_tuples = [
990 (ipaddress.ip_address('1.1.1.1'),
991 ipaddress.ip_address('::1')),
992 (ipaddress.IPv4Network('1.1.0.0/24'),
993 ipaddress.IPv6Network('2001::/120')),
994 (ipaddress.IPv4Network('1.1.0.0/32'),
995 ipaddress.IPv6Network('2001::/128')),
996 ]
997 for ip1, ip2 in addr_tuples:
998 self.assertRaises(TypeError, ipaddress.collapse_addresses,
999 [ip1, ip2])
Nick Coghlandc9b2552012-05-20 21:01:57 +10001000
1001 def testSummarizing(self):
1002 #ip = ipaddress.ip_address
1003 #ipnet = ipaddress.ip_network
1004 summarize = ipaddress.summarize_address_range
1005 ip1 = ipaddress.ip_address('1.1.1.0')
1006 ip2 = ipaddress.ip_address('1.1.1.255')
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001007
1008 # summarize works only for IPv4 & IPv6
1009 class IPv7Address(ipaddress.IPv6Address):
1010 @property
1011 def version(self):
1012 return 7
1013 ip_invalid1 = IPv7Address('::1')
1014 ip_invalid2 = IPv7Address('::1')
1015 self.assertRaises(ValueError, list,
1016 summarize(ip_invalid1, ip_invalid2))
1017 # test that a summary over ip4 & ip6 fails
1018 self.assertRaises(TypeError, list,
1019 summarize(ip1, ipaddress.IPv6Address('::1')))
1020 # test a /24 is summarized properly
Nick Coghlandc9b2552012-05-20 21:01:57 +10001021 self.assertEqual(list(summarize(ip1, ip2))[0],
1022 ipaddress.ip_network('1.1.1.0/24'))
1023 # test an IPv4 range that isn't on a network byte boundary
1024 ip2 = ipaddress.ip_address('1.1.1.8')
1025 self.assertEqual(list(summarize(ip1, ip2)),
1026 [ipaddress.ip_network('1.1.1.0/29'),
1027 ipaddress.ip_network('1.1.1.8')])
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001028 # all!
1029 ip1 = ipaddress.IPv4Address(0)
1030 ip2 = ipaddress.IPv4Address(ipaddress.IPv4Address._ALL_ONES)
1031 self.assertEqual([ipaddress.IPv4Network('0.0.0.0/0')],
1032 list(summarize(ip1, ip2)))
Nick Coghlandc9b2552012-05-20 21:01:57 +10001033
1034 ip1 = ipaddress.ip_address('1::')
1035 ip2 = ipaddress.ip_address('1:ffff:ffff:ffff:ffff:ffff:ffff:ffff')
1036 # test a IPv6 is sumamrized properly
1037 self.assertEqual(list(summarize(ip1, ip2))[0],
1038 ipaddress.ip_network('1::/16'))
1039 # test an IPv6 range that isn't on a network byte boundary
1040 ip2 = ipaddress.ip_address('2::')
1041 self.assertEqual(list(summarize(ip1, ip2)),
1042 [ipaddress.ip_network('1::/16'),
1043 ipaddress.ip_network('2::/128')])
1044
1045 # test exception raised when first is greater than last
1046 self.assertRaises(ValueError, list,
1047 summarize(ipaddress.ip_address('1.1.1.0'),
1048 ipaddress.ip_address('1.1.0.0')))
1049 # test exception raised when first and last aren't IP addresses
1050 self.assertRaises(TypeError, list,
1051 summarize(ipaddress.ip_network('1.1.1.0'),
1052 ipaddress.ip_network('1.1.0.0')))
1053 self.assertRaises(TypeError, list,
1054 summarize(ipaddress.ip_network('1.1.1.0'),
1055 ipaddress.ip_network('1.1.0.0')))
1056 # test exception raised when first and last are not same version
1057 self.assertRaises(TypeError, list,
1058 summarize(ipaddress.ip_address('::'),
1059 ipaddress.ip_network('1.1.0.0')))
1060
1061 def testAddressComparison(self):
1062 self.assertTrue(ipaddress.ip_address('1.1.1.1') <=
1063 ipaddress.ip_address('1.1.1.1'))
1064 self.assertTrue(ipaddress.ip_address('1.1.1.1') <=
1065 ipaddress.ip_address('1.1.1.2'))
1066 self.assertTrue(ipaddress.ip_address('::1') <=
1067 ipaddress.ip_address('::1'))
1068 self.assertTrue(ipaddress.ip_address('::1') <=
1069 ipaddress.ip_address('::2'))
1070
Nick Coghlan3008ec02012-07-08 00:45:33 +10001071 def testInterfaceComparison(self):
1072 self.assertTrue(ipaddress.ip_interface('1.1.1.1') <=
1073 ipaddress.ip_interface('1.1.1.1'))
1074 self.assertTrue(ipaddress.ip_interface('1.1.1.1') <=
1075 ipaddress.ip_interface('1.1.1.2'))
1076 self.assertTrue(ipaddress.ip_interface('::1') <=
1077 ipaddress.ip_interface('::1'))
1078 self.assertTrue(ipaddress.ip_interface('::1') <=
1079 ipaddress.ip_interface('::2'))
1080
Nick Coghlandc9b2552012-05-20 21:01:57 +10001081 def testNetworkComparison(self):
1082 # ip1 and ip2 have the same network address
1083 ip1 = ipaddress.IPv4Network('1.1.1.0/24')
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001084 ip2 = ipaddress.IPv4Network('1.1.1.0/32')
Nick Coghlandc9b2552012-05-20 21:01:57 +10001085 ip3 = ipaddress.IPv4Network('1.1.2.0/24')
1086
1087 self.assertTrue(ip1 < ip3)
1088 self.assertTrue(ip3 > ip2)
1089
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001090 self.assertEqual(ip1.compare_networks(ip1), 0)
1091
1092 # if addresses are the same, sort by netmask
1093 self.assertEqual(ip1.compare_networks(ip2), -1)
1094 self.assertEqual(ip2.compare_networks(ip1), 1)
1095
Nick Coghlandc9b2552012-05-20 21:01:57 +10001096 self.assertEqual(ip1.compare_networks(ip3), -1)
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001097 self.assertEqual(ip3.compare_networks(ip1), 1)
Nick Coghlandc9b2552012-05-20 21:01:57 +10001098 self.assertTrue(ip1._get_networks_key() < ip3._get_networks_key())
1099
1100 ip1 = ipaddress.IPv6Network('2001:2000::/96')
1101 ip2 = ipaddress.IPv6Network('2001:2001::/96')
1102 ip3 = ipaddress.IPv6Network('2001:ffff:2000::/96')
1103
1104 self.assertTrue(ip1 < ip3)
1105 self.assertTrue(ip3 > ip2)
1106 self.assertEqual(ip1.compare_networks(ip3), -1)
1107 self.assertTrue(ip1._get_networks_key() < ip3._get_networks_key())
1108
1109 # Test comparing different protocols.
1110 # Should always raise a TypeError.
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001111 self.assertRaises(TypeError,
1112 self.ipv4_network.compare_networks,
1113 self.ipv6_network)
Nick Coghlandc9b2552012-05-20 21:01:57 +10001114 ipv6 = ipaddress.IPv6Interface('::/0')
1115 ipv4 = ipaddress.IPv4Interface('0.0.0.0/0')
1116 self.assertRaises(TypeError, ipv4.__lt__, ipv6)
1117 self.assertRaises(TypeError, ipv4.__gt__, ipv6)
1118 self.assertRaises(TypeError, ipv6.__lt__, ipv4)
1119 self.assertRaises(TypeError, ipv6.__gt__, ipv4)
1120
1121 # Regression test for issue 19.
1122 ip1 = ipaddress.ip_network('10.1.2.128/25')
1123 self.assertFalse(ip1 < ip1)
1124 self.assertFalse(ip1 > ip1)
1125 ip2 = ipaddress.ip_network('10.1.3.0/24')
1126 self.assertTrue(ip1 < ip2)
1127 self.assertFalse(ip2 < ip1)
1128 self.assertFalse(ip1 > ip2)
1129 self.assertTrue(ip2 > ip1)
1130 ip3 = ipaddress.ip_network('10.1.3.0/25')
1131 self.assertTrue(ip2 < ip3)
1132 self.assertFalse(ip3 < ip2)
1133 self.assertFalse(ip2 > ip3)
1134 self.assertTrue(ip3 > ip2)
1135
1136 # Regression test for issue 28.
1137 ip1 = ipaddress.ip_network('10.10.10.0/31')
1138 ip2 = ipaddress.ip_network('10.10.10.0')
1139 ip3 = ipaddress.ip_network('10.10.10.2/31')
1140 ip4 = ipaddress.ip_network('10.10.10.2')
1141 sorted = [ip1, ip2, ip3, ip4]
1142 unsorted = [ip2, ip4, ip1, ip3]
1143 unsorted.sort()
1144 self.assertEqual(sorted, unsorted)
1145 unsorted = [ip4, ip1, ip3, ip2]
1146 unsorted.sort()
1147 self.assertEqual(sorted, unsorted)
1148 self.assertRaises(TypeError, ip1.__lt__,
1149 ipaddress.ip_address('10.10.10.0'))
1150 self.assertRaises(TypeError, ip2.__lt__,
1151 ipaddress.ip_address('10.10.10.0'))
1152
1153 # <=, >=
1154 self.assertTrue(ipaddress.ip_network('1.1.1.1') <=
1155 ipaddress.ip_network('1.1.1.1'))
1156 self.assertTrue(ipaddress.ip_network('1.1.1.1') <=
1157 ipaddress.ip_network('1.1.1.2'))
1158 self.assertFalse(ipaddress.ip_network('1.1.1.2') <=
1159 ipaddress.ip_network('1.1.1.1'))
1160 self.assertTrue(ipaddress.ip_network('::1') <=
1161 ipaddress.ip_network('::1'))
1162 self.assertTrue(ipaddress.ip_network('::1') <=
1163 ipaddress.ip_network('::2'))
1164 self.assertFalse(ipaddress.ip_network('::2') <=
1165 ipaddress.ip_network('::1'))
1166
1167 def testStrictNetworks(self):
1168 self.assertRaises(ValueError, ipaddress.ip_network, '192.168.1.1/24')
1169 self.assertRaises(ValueError, ipaddress.ip_network, '::1/120')
1170
1171 def testOverlaps(self):
1172 other = ipaddress.IPv4Network('1.2.3.0/30')
1173 other2 = ipaddress.IPv4Network('1.2.2.0/24')
1174 other3 = ipaddress.IPv4Network('1.2.2.64/26')
1175 self.assertTrue(self.ipv4_network.overlaps(other))
1176 self.assertFalse(self.ipv4_network.overlaps(other2))
1177 self.assertTrue(other2.overlaps(other3))
1178
1179 def testEmbeddedIpv4(self):
1180 ipv4_string = '192.168.0.1'
1181 ipv4 = ipaddress.IPv4Interface(ipv4_string)
1182 v4compat_ipv6 = ipaddress.IPv6Interface('::%s' % ipv4_string)
1183 self.assertEqual(int(v4compat_ipv6.ip), int(ipv4.ip))
1184 v4mapped_ipv6 = ipaddress.IPv6Interface('::ffff:%s' % ipv4_string)
1185 self.assertNotEqual(v4mapped_ipv6.ip, ipv4.ip)
1186 self.assertRaises(ipaddress.AddressValueError, ipaddress.IPv6Interface,
1187 '2001:1.1.1.1:1.1.1.1')
1188
1189 # Issue 67: IPv6 with embedded IPv4 address not recognized.
1190 def testIPv6AddressTooLarge(self):
1191 # RFC4291 2.5.5.2
1192 self.assertEqual(ipaddress.ip_address('::FFFF:192.0.2.1'),
1193 ipaddress.ip_address('::FFFF:c000:201'))
1194 # RFC4291 2.2 (part 3) x::d.d.d.d
1195 self.assertEqual(ipaddress.ip_address('FFFF::192.0.2.1'),
1196 ipaddress.ip_address('FFFF::c000:201'))
1197
1198 def testIPVersion(self):
1199 self.assertEqual(self.ipv4_address.version, 4)
1200 self.assertEqual(self.ipv6_address.version, 6)
1201
1202 def testMaxPrefixLength(self):
1203 self.assertEqual(self.ipv4_interface.max_prefixlen, 32)
1204 self.assertEqual(self.ipv6_interface.max_prefixlen, 128)
1205
1206 def testPacked(self):
1207 self.assertEqual(self.ipv4_address.packed,
Nick Coghlan5cf896f2012-07-07 01:43:31 +10001208 b'\x01\x02\x03\x04')
Nick Coghlandc9b2552012-05-20 21:01:57 +10001209 self.assertEqual(ipaddress.IPv4Interface('255.254.253.252').packed,
Nick Coghlan5cf896f2012-07-07 01:43:31 +10001210 b'\xff\xfe\xfd\xfc')
Nick Coghlandc9b2552012-05-20 21:01:57 +10001211 self.assertEqual(self.ipv6_address.packed,
Nick Coghlan5cf896f2012-07-07 01:43:31 +10001212 b'\x20\x01\x06\x58\x02\x2a\xca\xfe'
1213 b'\x02\x00\x00\x00\x00\x00\x00\x01')
Nick Coghlandc9b2552012-05-20 21:01:57 +10001214 self.assertEqual(ipaddress.IPv6Interface('ffff:2:3:4:ffff::').packed,
Nick Coghlan5cf896f2012-07-07 01:43:31 +10001215 b'\xff\xff\x00\x02\x00\x03\x00\x04\xff\xff'
1216 + b'\x00' * 6)
Nick Coghlandc9b2552012-05-20 21:01:57 +10001217 self.assertEqual(ipaddress.IPv6Interface('::1:0:0:0:0').packed,
Nick Coghlan5cf896f2012-07-07 01:43:31 +10001218 b'\x00' * 6 + b'\x00\x01' + b'\x00' * 8)
Nick Coghlandc9b2552012-05-20 21:01:57 +10001219
1220 def testIpStrFromPrefixlen(self):
1221 ipv4 = ipaddress.IPv4Interface('1.2.3.4/24')
1222 self.assertEqual(ipv4._ip_string_from_prefix(), '255.255.255.0')
1223 self.assertEqual(ipv4._ip_string_from_prefix(28), '255.255.255.240')
1224
1225 def testIpType(self):
1226 ipv4net = ipaddress.ip_network('1.2.3.4')
1227 ipv4addr = ipaddress.ip_address('1.2.3.4')
1228 ipv6net = ipaddress.ip_network('::1.2.3.4')
1229 ipv6addr = ipaddress.ip_address('::1.2.3.4')
1230 self.assertEqual(ipaddress.IPv4Network, type(ipv4net))
1231 self.assertEqual(ipaddress.IPv4Address, type(ipv4addr))
1232 self.assertEqual(ipaddress.IPv6Network, type(ipv6net))
1233 self.assertEqual(ipaddress.IPv6Address, type(ipv6addr))
1234
1235 def testReservedIpv4(self):
1236 # test networks
1237 self.assertEqual(True, ipaddress.ip_interface(
1238 '224.1.1.1/31').is_multicast)
1239 self.assertEqual(False, ipaddress.ip_network('240.0.0.0').is_multicast)
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001240 self.assertEqual(True, ipaddress.ip_network('240.0.0.0').is_reserved)
Nick Coghlandc9b2552012-05-20 21:01:57 +10001241
1242 self.assertEqual(True, ipaddress.ip_interface(
1243 '192.168.1.1/17').is_private)
1244 self.assertEqual(False, ipaddress.ip_network('192.169.0.0').is_private)
1245 self.assertEqual(True, ipaddress.ip_network(
1246 '10.255.255.255').is_private)
1247 self.assertEqual(False, ipaddress.ip_network('11.0.0.0').is_private)
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001248 self.assertEqual(False, ipaddress.ip_network('11.0.0.0').is_reserved)
Nick Coghlandc9b2552012-05-20 21:01:57 +10001249 self.assertEqual(True, ipaddress.ip_network(
1250 '172.31.255.255').is_private)
1251 self.assertEqual(False, ipaddress.ip_network('172.32.0.0').is_private)
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001252 self.assertEqual(True,
1253 ipaddress.ip_network('169.254.1.0/24').is_link_local)
Nick Coghlandc9b2552012-05-20 21:01:57 +10001254
1255 self.assertEqual(True,
1256 ipaddress.ip_interface(
1257 '169.254.100.200/24').is_link_local)
1258 self.assertEqual(False,
1259 ipaddress.ip_interface(
1260 '169.255.100.200/24').is_link_local)
1261
1262 self.assertEqual(True,
1263 ipaddress.ip_network(
1264 '127.100.200.254/32').is_loopback)
1265 self.assertEqual(True, ipaddress.ip_network(
1266 '127.42.0.0/16').is_loopback)
1267 self.assertEqual(False, ipaddress.ip_network('128.0.0.0').is_loopback)
1268
1269 # test addresses
Hynek Schlawackbcd30442012-06-04 14:19:39 +02001270 self.assertEqual(True, ipaddress.ip_address('0.0.0.0').is_unspecified)
Nick Coghlandc9b2552012-05-20 21:01:57 +10001271 self.assertEqual(True, ipaddress.ip_address('224.1.1.1').is_multicast)
1272 self.assertEqual(False, ipaddress.ip_address('240.0.0.0').is_multicast)
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001273 self.assertEqual(True, ipaddress.ip_address('240.0.0.1').is_reserved)
1274 self.assertEqual(False,
1275 ipaddress.ip_address('239.255.255.255').is_reserved)
Nick Coghlandc9b2552012-05-20 21:01:57 +10001276
1277 self.assertEqual(True, ipaddress.ip_address('192.168.1.1').is_private)
1278 self.assertEqual(False, ipaddress.ip_address('192.169.0.0').is_private)
1279 self.assertEqual(True, ipaddress.ip_address(
1280 '10.255.255.255').is_private)
1281 self.assertEqual(False, ipaddress.ip_address('11.0.0.0').is_private)
1282 self.assertEqual(True, ipaddress.ip_address(
1283 '172.31.255.255').is_private)
1284 self.assertEqual(False, ipaddress.ip_address('172.32.0.0').is_private)
1285
1286 self.assertEqual(True,
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001287 ipaddress.ip_address('169.254.100.200').is_link_local)
Nick Coghlandc9b2552012-05-20 21:01:57 +10001288 self.assertEqual(False,
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001289 ipaddress.ip_address('169.255.100.200').is_link_local)
Nick Coghlandc9b2552012-05-20 21:01:57 +10001290
1291 self.assertEqual(True,
1292 ipaddress.ip_address('127.100.200.254').is_loopback)
1293 self.assertEqual(True, ipaddress.ip_address('127.42.0.0').is_loopback)
1294 self.assertEqual(False, ipaddress.ip_address('128.0.0.0').is_loopback)
1295 self.assertEqual(True, ipaddress.ip_network('0.0.0.0').is_unspecified)
1296
1297 def testReservedIpv6(self):
1298
1299 self.assertEqual(True, ipaddress.ip_network('ffff::').is_multicast)
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001300 self.assertEqual(True, ipaddress.ip_network(2**128 - 1).is_multicast)
Nick Coghlandc9b2552012-05-20 21:01:57 +10001301 self.assertEqual(True, ipaddress.ip_network('ff00::').is_multicast)
1302 self.assertEqual(False, ipaddress.ip_network('fdff::').is_multicast)
1303
1304 self.assertEqual(True, ipaddress.ip_network('fecf::').is_site_local)
1305 self.assertEqual(True, ipaddress.ip_network(
1306 'feff:ffff:ffff:ffff::').is_site_local)
1307 self.assertEqual(False, ipaddress.ip_network(
1308 'fbf:ffff::').is_site_local)
1309 self.assertEqual(False, ipaddress.ip_network('ff00::').is_site_local)
1310
1311 self.assertEqual(True, ipaddress.ip_network('fc00::').is_private)
1312 self.assertEqual(True, ipaddress.ip_network(
1313 'fc00:ffff:ffff:ffff::').is_private)
1314 self.assertEqual(False, ipaddress.ip_network('fbff:ffff::').is_private)
1315 self.assertEqual(False, ipaddress.ip_network('fe00::').is_private)
1316
1317 self.assertEqual(True, ipaddress.ip_network('fea0::').is_link_local)
1318 self.assertEqual(True, ipaddress.ip_network(
1319 'febf:ffff::').is_link_local)
1320 self.assertEqual(False, ipaddress.ip_network(
1321 'fe7f:ffff::').is_link_local)
1322 self.assertEqual(False, ipaddress.ip_network('fec0::').is_link_local)
1323
1324 self.assertEqual(True, ipaddress.ip_interface('0:0::0:01').is_loopback)
1325 self.assertEqual(False, ipaddress.ip_interface('::1/127').is_loopback)
1326 self.assertEqual(False, ipaddress.ip_network('::').is_loopback)
1327 self.assertEqual(False, ipaddress.ip_network('::2').is_loopback)
1328
1329 self.assertEqual(True, ipaddress.ip_network('0::0').is_unspecified)
1330 self.assertEqual(False, ipaddress.ip_network('::1').is_unspecified)
1331 self.assertEqual(False, ipaddress.ip_network('::/127').is_unspecified)
1332
1333 # test addresses
1334 self.assertEqual(True, ipaddress.ip_address('ffff::').is_multicast)
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001335 self.assertEqual(True, ipaddress.ip_address(2**128 - 1).is_multicast)
Nick Coghlandc9b2552012-05-20 21:01:57 +10001336 self.assertEqual(True, ipaddress.ip_address('ff00::').is_multicast)
1337 self.assertEqual(False, ipaddress.ip_address('fdff::').is_multicast)
1338
1339 self.assertEqual(True, ipaddress.ip_address('fecf::').is_site_local)
1340 self.assertEqual(True, ipaddress.ip_address(
1341 'feff:ffff:ffff:ffff::').is_site_local)
1342 self.assertEqual(False, ipaddress.ip_address(
1343 'fbf:ffff::').is_site_local)
1344 self.assertEqual(False, ipaddress.ip_address('ff00::').is_site_local)
1345
1346 self.assertEqual(True, ipaddress.ip_address('fc00::').is_private)
1347 self.assertEqual(True, ipaddress.ip_address(
1348 'fc00:ffff:ffff:ffff::').is_private)
1349 self.assertEqual(False, ipaddress.ip_address('fbff:ffff::').is_private)
1350 self.assertEqual(False, ipaddress.ip_address('fe00::').is_private)
1351
1352 self.assertEqual(True, ipaddress.ip_address('fea0::').is_link_local)
1353 self.assertEqual(True, ipaddress.ip_address(
1354 'febf:ffff::').is_link_local)
1355 self.assertEqual(False, ipaddress.ip_address(
1356 'fe7f:ffff::').is_link_local)
1357 self.assertEqual(False, ipaddress.ip_address('fec0::').is_link_local)
1358
1359 self.assertEqual(True, ipaddress.ip_address('0:0::0:01').is_loopback)
1360 self.assertEqual(True, ipaddress.ip_address('::1').is_loopback)
1361 self.assertEqual(False, ipaddress.ip_address('::2').is_loopback)
1362
1363 self.assertEqual(True, ipaddress.ip_address('0::0').is_unspecified)
1364 self.assertEqual(False, ipaddress.ip_address('::1').is_unspecified)
1365
1366 # some generic IETF reserved addresses
1367 self.assertEqual(True, ipaddress.ip_address('100::').is_reserved)
1368 self.assertEqual(True, ipaddress.ip_network('4000::1/128').is_reserved)
1369
1370 def testIpv4Mapped(self):
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001371 self.assertEqual(
1372 ipaddress.ip_address('::ffff:192.168.1.1').ipv4_mapped,
1373 ipaddress.ip_address('192.168.1.1'))
Nick Coghlandc9b2552012-05-20 21:01:57 +10001374 self.assertEqual(ipaddress.ip_address('::c0a8:101').ipv4_mapped, None)
1375 self.assertEqual(ipaddress.ip_address('::ffff:c0a8:101').ipv4_mapped,
1376 ipaddress.ip_address('192.168.1.1'))
1377
1378 def testAddrExclude(self):
1379 addr1 = ipaddress.ip_network('10.1.1.0/24')
1380 addr2 = ipaddress.ip_network('10.1.1.0/26')
1381 addr3 = ipaddress.ip_network('10.2.1.0/24')
1382 addr4 = ipaddress.ip_address('10.1.1.0')
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001383 addr5 = ipaddress.ip_network('2001:db8::0/32')
Nick Coghlandc9b2552012-05-20 21:01:57 +10001384 self.assertEqual(sorted(list(addr1.address_exclude(addr2))),
1385 [ipaddress.ip_network('10.1.1.64/26'),
1386 ipaddress.ip_network('10.1.1.128/25')])
1387 self.assertRaises(ValueError, list, addr1.address_exclude(addr3))
1388 self.assertRaises(TypeError, list, addr1.address_exclude(addr4))
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001389 self.assertRaises(TypeError, list, addr1.address_exclude(addr5))
Nick Coghlandc9b2552012-05-20 21:01:57 +10001390 self.assertEqual(list(addr1.address_exclude(addr1)), [])
1391
1392 def testHash(self):
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001393 self.assertEqual(hash(ipaddress.ip_interface('10.1.1.0/24')),
1394 hash(ipaddress.ip_interface('10.1.1.0/24')))
Nick Coghlandc9b2552012-05-20 21:01:57 +10001395 self.assertEqual(hash(ipaddress.ip_network('10.1.1.0/24')),
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001396 hash(ipaddress.ip_network('10.1.1.0/24')))
Nick Coghlandc9b2552012-05-20 21:01:57 +10001397 self.assertEqual(hash(ipaddress.ip_address('10.1.1.0')),
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001398 hash(ipaddress.ip_address('10.1.1.0')))
Nick Coghlandc9b2552012-05-20 21:01:57 +10001399 # i70
1400 self.assertEqual(hash(ipaddress.ip_address('1.2.3.4')),
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001401 hash(ipaddress.ip_address(
Nick Coghlandc9b2552012-05-20 21:01:57 +10001402 int(ipaddress.ip_address('1.2.3.4')._ip))))
1403 ip1 = ipaddress.ip_address('10.1.1.0')
1404 ip2 = ipaddress.ip_address('1::')
1405 dummy = {}
1406 dummy[self.ipv4_address] = None
1407 dummy[self.ipv6_address] = None
1408 dummy[ip1] = None
1409 dummy[ip2] = None
1410 self.assertTrue(self.ipv4_address in dummy)
1411 self.assertTrue(ip2 in dummy)
1412
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001413 def testIPBases(self):
1414 net = self.ipv4_network
1415 self.assertEqual('1.2.3.0/24', net.compressed)
1416 self.assertEqual(
1417 net._ip_int_from_prefix(24),
1418 net._ip_int_from_prefix(None))
1419 net = self.ipv6_network
1420 self.assertRaises(ValueError, net._string_from_ip_int, 2**128 + 1)
1421 self.assertEqual(
1422 self.ipv6_address._string_from_ip_int(self.ipv6_address._ip),
1423 self.ipv6_address._string_from_ip_int(None))
1424
Hynek Schlawack454a74d2012-06-04 18:14:02 +02001425 def testIPv6NetworkHelpers(self):
1426 net = self.ipv6_network
1427 self.assertEqual('2001:658:22a:cafe::/64', net.with_prefixlen)
1428 self.assertEqual('2001:658:22a:cafe::/ffff:ffff:ffff:ffff::',
1429 net.with_netmask)
1430 self.assertEqual('2001:658:22a:cafe::/::ffff:ffff:ffff:ffff',
1431 net.with_hostmask)
1432 self.assertEqual('2001:658:22a:cafe::/64', str(net))
1433
1434 def testIPv4NetworkHelpers(self):
1435 net = self.ipv4_network
1436 self.assertEqual('1.2.3.0/24', net.with_prefixlen)
1437 self.assertEqual('1.2.3.0/255.255.255.0', net.with_netmask)
1438 self.assertEqual('1.2.3.0/0.0.0.255', net.with_hostmask)
1439 self.assertEqual('1.2.3.0/24', str(net))
1440
Nick Coghlandc9b2552012-05-20 21:01:57 +10001441 def testCopyConstructor(self):
1442 addr1 = ipaddress.ip_network('10.1.1.0/24')
1443 addr2 = ipaddress.ip_network(addr1)
1444 addr3 = ipaddress.ip_interface('2001:658:22a:cafe:200::1/64')
1445 addr4 = ipaddress.ip_interface(addr3)
1446 addr5 = ipaddress.IPv4Address('1.1.1.1')
1447 addr6 = ipaddress.IPv6Address('2001:658:22a:cafe:200::1')
1448
1449 self.assertEqual(addr1, addr2)
1450 self.assertEqual(addr3, addr4)
1451 self.assertEqual(addr5, ipaddress.IPv4Address(addr5))
1452 self.assertEqual(addr6, ipaddress.IPv6Address(addr6))
1453
1454 def testCompressIPv6Address(self):
1455 test_addresses = {
1456 '1:2:3:4:5:6:7:8': '1:2:3:4:5:6:7:8/128',
1457 '2001:0:0:4:0:0:0:8': '2001:0:0:4::8/128',
1458 '2001:0:0:4:5:6:7:8': '2001::4:5:6:7:8/128',
1459 '2001:0:3:4:5:6:7:8': '2001:0:3:4:5:6:7:8/128',
1460 '2001:0:3:4:5:6:7:8': '2001:0:3:4:5:6:7:8/128',
1461 '0:0:3:0:0:0:0:ffff': '0:0:3::ffff/128',
1462 '0:0:0:4:0:0:0:ffff': '::4:0:0:0:ffff/128',
1463 '0:0:0:0:5:0:0:ffff': '::5:0:0:ffff/128',
1464 '1:0:0:4:0:0:7:8': '1::4:0:0:7:8/128',
1465 '0:0:0:0:0:0:0:0': '::/128',
1466 '0:0:0:0:0:0:0:0/0': '::/0',
1467 '0:0:0:0:0:0:0:1': '::1/128',
1468 '2001:0658:022a:cafe:0000:0000:0000:0000/66':
1469 '2001:658:22a:cafe::/66',
1470 '::1.2.3.4': '::102:304/128',
1471 '1:2:3:4:5:ffff:1.2.3.4': '1:2:3:4:5:ffff:102:304/128',
1472 '::7:6:5:4:3:2:1': '0:7:6:5:4:3:2:1/128',
1473 '::7:6:5:4:3:2:0': '0:7:6:5:4:3:2:0/128',
1474 '7:6:5:4:3:2:1::': '7:6:5:4:3:2:1:0/128',
1475 '0:6:5:4:3:2:1::': '0:6:5:4:3:2:1:0/128',
1476 }
1477 for uncompressed, compressed in list(test_addresses.items()):
1478 self.assertEqual(compressed, str(ipaddress.IPv6Interface(
1479 uncompressed)))
1480
1481 def testExplodeShortHandIpStr(self):
1482 addr1 = ipaddress.IPv6Interface('2001::1')
1483 addr2 = ipaddress.IPv6Address('2001:0:5ef5:79fd:0:59d:a0e5:ba1')
1484 addr3 = ipaddress.IPv6Network('2001::/96')
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001485 addr4 = ipaddress.IPv4Address('192.168.178.1')
Nick Coghlandc9b2552012-05-20 21:01:57 +10001486 self.assertEqual('2001:0000:0000:0000:0000:0000:0000:0001/128',
1487 addr1.exploded)
1488 self.assertEqual('0000:0000:0000:0000:0000:0000:0000:0001/128',
1489 ipaddress.IPv6Interface('::1/128').exploded)
1490 # issue 77
1491 self.assertEqual('2001:0000:5ef5:79fd:0000:059d:a0e5:0ba1',
1492 addr2.exploded)
1493 self.assertEqual('2001:0000:0000:0000:0000:0000:0000:0000/96',
1494 addr3.exploded)
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001495 self.assertEqual('192.168.178.1', addr4.exploded)
Nick Coghlandc9b2552012-05-20 21:01:57 +10001496
1497 def testIntRepresentation(self):
1498 self.assertEqual(16909060, int(self.ipv4_address))
1499 self.assertEqual(42540616829182469433547762482097946625,
1500 int(self.ipv6_address))
1501
1502 def testHexRepresentation(self):
1503 self.assertEqual(hex(0x1020304),
1504 hex(self.ipv4_address))
1505
1506 self.assertEqual(hex(0x20010658022ACAFE0200000000000001),
1507 hex(self.ipv6_address))
1508
1509 def testForceVersion(self):
1510 self.assertEqual(ipaddress.ip_network(1).version, 4)
Nick Coghlan51c30672012-05-27 00:25:58 +10001511 self.assertEqual(ipaddress.IPv6Network(1).version, 6)
Sandro Tosi876ecad2012-05-23 22:26:55 +02001512
Nick Coghlandc9b2552012-05-20 21:01:57 +10001513 def testWithStar(self):
1514 self.assertEqual(str(self.ipv4_interface.with_prefixlen), "1.2.3.4/24")
1515 self.assertEqual(str(self.ipv4_interface.with_netmask),
1516 "1.2.3.4/255.255.255.0")
1517 self.assertEqual(str(self.ipv4_interface.with_hostmask),
1518 "1.2.3.4/0.0.0.255")
1519
1520 self.assertEqual(str(self.ipv6_interface.with_prefixlen),
1521 '2001:658:22a:cafe:200::1/64')
1522 # rfc3513 sec 2.3 says that ipv6 only uses cidr notation for
1523 # subnets
1524 self.assertEqual(str(self.ipv6_interface.with_netmask),
1525 '2001:658:22a:cafe:200::1/64')
1526 # this probably don't make much sense, but it's included for
1527 # compatibility with ipv4
1528 self.assertEqual(str(self.ipv6_interface.with_hostmask),
1529 '2001:658:22a:cafe:200::1/::ffff:ffff:ffff:ffff')
1530
1531 def testNetworkElementCaching(self):
1532 # V4 - make sure we're empty
1533 self.assertFalse('network_address' in self.ipv4_network._cache)
1534 self.assertFalse('broadcast_address' in self.ipv4_network._cache)
1535 self.assertFalse('hostmask' in self.ipv4_network._cache)
1536
1537 # V4 - populate and test
1538 self.assertEqual(self.ipv4_network.network_address,
1539 ipaddress.IPv4Address('1.2.3.0'))
1540 self.assertEqual(self.ipv4_network.broadcast_address,
1541 ipaddress.IPv4Address('1.2.3.255'))
1542 self.assertEqual(self.ipv4_network.hostmask,
1543 ipaddress.IPv4Address('0.0.0.255'))
1544
1545 # V4 - check we're cached
1546 self.assertTrue('broadcast_address' in self.ipv4_network._cache)
1547 self.assertTrue('hostmask' in self.ipv4_network._cache)
1548
1549 # V6 - make sure we're empty
1550 self.assertFalse('broadcast_address' in self.ipv6_network._cache)
1551 self.assertFalse('hostmask' in self.ipv6_network._cache)
1552
1553 # V6 - populate and test
1554 self.assertEqual(self.ipv6_network.network_address,
1555 ipaddress.IPv6Address('2001:658:22a:cafe::'))
1556 self.assertEqual(self.ipv6_interface.network.network_address,
1557 ipaddress.IPv6Address('2001:658:22a:cafe::'))
1558
1559 self.assertEqual(
1560 self.ipv6_network.broadcast_address,
1561 ipaddress.IPv6Address('2001:658:22a:cafe:ffff:ffff:ffff:ffff'))
1562 self.assertEqual(self.ipv6_network.hostmask,
1563 ipaddress.IPv6Address('::ffff:ffff:ffff:ffff'))
1564 self.assertEqual(
1565 self.ipv6_interface.network.broadcast_address,
1566 ipaddress.IPv6Address('2001:658:22a:cafe:ffff:ffff:ffff:ffff'))
1567 self.assertEqual(self.ipv6_interface.network.hostmask,
1568 ipaddress.IPv6Address('::ffff:ffff:ffff:ffff'))
1569
1570 # V6 - check we're cached
1571 self.assertTrue('broadcast_address' in self.ipv6_network._cache)
1572 self.assertTrue('hostmask' in self.ipv6_network._cache)
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001573 self.assertTrue(
1574 'broadcast_address' in self.ipv6_interface.network._cache)
Nick Coghlandc9b2552012-05-20 21:01:57 +10001575 self.assertTrue('hostmask' in self.ipv6_interface.network._cache)
1576
1577 def testTeredo(self):
1578 # stolen from wikipedia
1579 server = ipaddress.IPv4Address('65.54.227.120')
1580 client = ipaddress.IPv4Address('192.0.2.45')
1581 teredo_addr = '2001:0000:4136:e378:8000:63bf:3fff:fdd2'
1582 self.assertEqual((server, client),
1583 ipaddress.ip_address(teredo_addr).teredo)
1584 bad_addr = '2000::4136:e378:8000:63bf:3fff:fdd2'
1585 self.assertFalse(ipaddress.ip_address(bad_addr).teredo)
1586 bad_addr = '2001:0001:4136:e378:8000:63bf:3fff:fdd2'
1587 self.assertFalse(ipaddress.ip_address(bad_addr).teredo)
1588
1589 # i77
1590 teredo_addr = ipaddress.IPv6Address('2001:0:5ef5:79fd:0:59d:a0e5:ba1')
1591 self.assertEqual((ipaddress.IPv4Address('94.245.121.253'),
1592 ipaddress.IPv4Address('95.26.244.94')),
1593 teredo_addr.teredo)
1594
Nick Coghlandc9b2552012-05-20 21:01:57 +10001595 def testsixtofour(self):
1596 sixtofouraddr = ipaddress.ip_address('2002:ac1d:2d64::1')
1597 bad_addr = ipaddress.ip_address('2000:ac1d:2d64::1')
1598 self.assertEqual(ipaddress.IPv4Address('172.29.45.100'),
1599 sixtofouraddr.sixtofour)
1600 self.assertFalse(bad_addr.sixtofour)
1601
Nick Coghlandc9b2552012-05-20 21:01:57 +10001602
1603if __name__ == '__main__':
1604 unittest.main()