blob: 8dc4767a016a59d6cd238b0c7650ab5e3e334b52 [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)
554 self.assertEqual(0, ipaddress._get_prefix_length(2**32, 0, 32))
555 self.assertEqual(128, ipaddress._count_righthand_zero_bits(0, 128))
Hynek Schlawack91c5a342012-06-05 11:55:58 +0200556 self.assertEqual("IPv4Network('1.2.3.0/24')", repr(self.ipv4_network))
557 self.assertEqual('0x1020318', hex(self.ipv4_network))
Nick Coghlandc9b2552012-05-20 21:01:57 +1000558
Nick Coghland9722652012-06-17 16:33:00 +1000559 def testMissingAddressVersion(self):
560 class Broken(ipaddress._BaseAddress):
561 pass
562 broken = Broken('127.0.0.1')
563 with self.assertRaisesRegex(NotImplementedError, "Broken.*version"):
564 broken.version
565
566 def testMissingNetworkVersion(self):
567 class Broken(ipaddress._BaseNetwork):
568 pass
569 broken = Broken('127.0.0.1')
570 with self.assertRaisesRegex(NotImplementedError, "Broken.*version"):
571 broken.version
572
573 def testMissingAddressClass(self):
574 class Broken(ipaddress._BaseNetwork):
575 pass
576 broken = Broken('127.0.0.1')
577 with self.assertRaisesRegex(NotImplementedError, "Broken.*address"):
578 broken._address_class
579
Nick Coghlandc9b2552012-05-20 21:01:57 +1000580 def testGetNetwork(self):
581 self.assertEqual(int(self.ipv4_network.network_address), 16909056)
582 self.assertEqual(str(self.ipv4_network.network_address), '1.2.3.0')
583
584 self.assertEqual(int(self.ipv6_network.network_address),
585 42540616829182469433403647294022090752)
586 self.assertEqual(str(self.ipv6_network.network_address),
587 '2001:658:22a:cafe::')
588 self.assertEqual(str(self.ipv6_network.hostmask),
589 '::ffff:ffff:ffff:ffff')
590
Nick Coghlandc9b2552012-05-20 21:01:57 +1000591 def testIpFromInt(self):
592 self.assertEqual(self.ipv4_interface._ip,
593 ipaddress.IPv4Interface(16909060)._ip)
Nick Coghlandc9b2552012-05-20 21:01:57 +1000594
595 ipv4 = ipaddress.ip_network('1.2.3.4')
596 ipv6 = ipaddress.ip_network('2001:658:22a:cafe:200:0:0:1')
597 self.assertEqual(ipv4, ipaddress.ip_network(int(ipv4)))
598 self.assertEqual(ipv6, ipaddress.ip_network(int(ipv6)))
599
600 v6_int = 42540616829182469433547762482097946625
601 self.assertEqual(self.ipv6_interface._ip,
602 ipaddress.IPv6Interface(v6_int)._ip)
Nick Coghlandc9b2552012-05-20 21:01:57 +1000603
Hynek Schlawack91c5a342012-06-05 11:55:58 +0200604 self.assertEqual(ipaddress.ip_network(self.ipv4_address._ip).version,
605 4)
606 self.assertEqual(ipaddress.ip_network(self.ipv6_address._ip).version,
607 6)
Nick Coghlandc9b2552012-05-20 21:01:57 +1000608
609 def testIpFromPacked(self):
Nick Coghlan5cf896f2012-07-07 01:43:31 +1000610 address = ipaddress.ip_address
Nick Coghlandc9b2552012-05-20 21:01:57 +1000611 self.assertEqual(self.ipv4_interface._ip,
Nick Coghlan5cf896f2012-07-07 01:43:31 +1000612 ipaddress.ip_interface(b'\x01\x02\x03\x04')._ip)
613 self.assertEqual(address('255.254.253.252'),
614 address(b'\xff\xfe\xfd\xfc'))
Nick Coghlandc9b2552012-05-20 21:01:57 +1000615 self.assertEqual(self.ipv6_interface.ip,
616 ipaddress.ip_interface(
Nick Coghlan5cf896f2012-07-07 01:43:31 +1000617 b'\x20\x01\x06\x58\x02\x2a\xca\xfe'
618 b'\x02\x00\x00\x00\x00\x00\x00\x01').ip)
619 self.assertEqual(address('ffff:2:3:4:ffff::'),
620 address(b'\xff\xff\x00\x02\x00\x03\x00\x04' +
621 b'\xff\xff' + b'\x00' * 6))
622 self.assertEqual(address('::'),
623 address(b'\x00' * 16))
624
Nick Coghlandc9b2552012-05-20 21:01:57 +1000625 def testGetIp(self):
626 self.assertEqual(int(self.ipv4_interface.ip), 16909060)
627 self.assertEqual(str(self.ipv4_interface.ip), '1.2.3.4')
628
629 self.assertEqual(int(self.ipv6_interface.ip),
630 42540616829182469433547762482097946625)
631 self.assertEqual(str(self.ipv6_interface.ip),
632 '2001:658:22a:cafe:200::1')
633
634 def testGetNetmask(self):
635 self.assertEqual(int(self.ipv4_network.netmask), 4294967040)
636 self.assertEqual(str(self.ipv4_network.netmask), '255.255.255.0')
637 self.assertEqual(int(self.ipv6_network.netmask),
638 340282366920938463444927863358058659840)
639 self.assertEqual(self.ipv6_network.prefixlen, 64)
640
641 def testZeroNetmask(self):
642 ipv4_zero_netmask = ipaddress.IPv4Interface('1.2.3.4/0')
643 self.assertEqual(int(ipv4_zero_netmask.network.netmask), 0)
644 self.assertTrue(ipv4_zero_netmask.network._is_valid_netmask(
645 str(0)))
Hynek Schlawack91c5a342012-06-05 11:55:58 +0200646 self.assertTrue(ipv4_zero_netmask._is_valid_netmask('0'))
647 self.assertTrue(ipv4_zero_netmask._is_valid_netmask('0.0.0.0'))
648 self.assertFalse(ipv4_zero_netmask._is_valid_netmask('invalid'))
Nick Coghlandc9b2552012-05-20 21:01:57 +1000649
650 ipv6_zero_netmask = ipaddress.IPv6Interface('::1/0')
651 self.assertEqual(int(ipv6_zero_netmask.network.netmask), 0)
652 self.assertTrue(ipv6_zero_netmask.network._is_valid_netmask(
653 str(0)))
654
Hynek Schlawack91c5a342012-06-05 11:55:58 +0200655 def testIPv4NetAndHostmasks(self):
656 net = self.ipv4_network
657 self.assertFalse(net._is_valid_netmask('invalid'))
658 self.assertTrue(net._is_valid_netmask('128.128.128.128'))
659 self.assertFalse(net._is_valid_netmask('128.128.128.127'))
660 self.assertFalse(net._is_valid_netmask('128.128.128.255'))
661 self.assertTrue(net._is_valid_netmask('255.128.128.128'))
662
663 self.assertFalse(net._is_hostmask('invalid'))
664 self.assertTrue(net._is_hostmask('128.255.255.255'))
665 self.assertFalse(net._is_hostmask('255.255.255.255'))
666 self.assertFalse(net._is_hostmask('1.2.3.4'))
667
668 net = ipaddress.IPv4Network('127.0.0.0/0.0.0.255')
669 self.assertEqual(24, net.prefixlen)
670
Nick Coghlandc9b2552012-05-20 21:01:57 +1000671 def testGetBroadcast(self):
672 self.assertEqual(int(self.ipv4_network.broadcast_address), 16909311)
673 self.assertEqual(str(self.ipv4_network.broadcast_address), '1.2.3.255')
674
675 self.assertEqual(int(self.ipv6_network.broadcast_address),
676 42540616829182469451850391367731642367)
677 self.assertEqual(str(self.ipv6_network.broadcast_address),
678 '2001:658:22a:cafe:ffff:ffff:ffff:ffff')
679
680 def testGetPrefixlen(self):
681 self.assertEqual(self.ipv4_interface.prefixlen, 24)
682 self.assertEqual(self.ipv6_interface.prefixlen, 64)
683
684 def testGetSupernet(self):
685 self.assertEqual(self.ipv4_network.supernet().prefixlen, 23)
686 self.assertEqual(str(self.ipv4_network.supernet().network_address),
687 '1.2.2.0')
688 self.assertEqual(
689 ipaddress.IPv4Interface('0.0.0.0/0').network.supernet(),
690 ipaddress.IPv4Network('0.0.0.0/0'))
691
692 self.assertEqual(self.ipv6_network.supernet().prefixlen, 63)
693 self.assertEqual(str(self.ipv6_network.supernet().network_address),
694 '2001:658:22a:cafe::')
695 self.assertEqual(ipaddress.IPv6Interface('::0/0').network.supernet(),
696 ipaddress.IPv6Network('::0/0'))
697
698 def testGetSupernet3(self):
699 self.assertEqual(self.ipv4_network.supernet(3).prefixlen, 21)
700 self.assertEqual(str(self.ipv4_network.supernet(3).network_address),
701 '1.2.0.0')
702
703 self.assertEqual(self.ipv6_network.supernet(3).prefixlen, 61)
704 self.assertEqual(str(self.ipv6_network.supernet(3).network_address),
705 '2001:658:22a:caf8::')
706
707 def testGetSupernet4(self):
708 self.assertRaises(ValueError, self.ipv4_network.supernet,
709 prefixlen_diff=2, new_prefix=1)
Hynek Schlawack91c5a342012-06-05 11:55:58 +0200710 self.assertRaises(ValueError, self.ipv4_network.supernet,
711 new_prefix=25)
Nick Coghlandc9b2552012-05-20 21:01:57 +1000712 self.assertEqual(self.ipv4_network.supernet(prefixlen_diff=2),
713 self.ipv4_network.supernet(new_prefix=22))
714
715 self.assertRaises(ValueError, self.ipv6_network.supernet,
716 prefixlen_diff=2, new_prefix=1)
Hynek Schlawack91c5a342012-06-05 11:55:58 +0200717 self.assertRaises(ValueError, self.ipv6_network.supernet,
718 new_prefix=65)
Nick Coghlandc9b2552012-05-20 21:01:57 +1000719 self.assertEqual(self.ipv6_network.supernet(prefixlen_diff=2),
720 self.ipv6_network.supernet(new_prefix=62))
721
722 def testHosts(self):
Hynek Schlawack91c5a342012-06-05 11:55:58 +0200723 hosts = list(self.ipv4_network.hosts())
724 self.assertEqual(254, len(hosts))
725 self.assertEqual(ipaddress.IPv4Address('1.2.3.1'), hosts[0])
726 self.assertEqual(ipaddress.IPv4Address('1.2.3.254'), hosts[-1])
727
728 # special case where only 1 bit is left for address
Nick Coghlandc9b2552012-05-20 21:01:57 +1000729 self.assertEqual([ipaddress.IPv4Address('2.0.0.0'),
730 ipaddress.IPv4Address('2.0.0.1')],
731 list(ipaddress.ip_network('2.0.0.0/31').hosts()))
732
733 def testFancySubnetting(self):
734 self.assertEqual(sorted(self.ipv4_network.subnets(prefixlen_diff=3)),
735 sorted(self.ipv4_network.subnets(new_prefix=27)))
736 self.assertRaises(ValueError, list,
737 self.ipv4_network.subnets(new_prefix=23))
738 self.assertRaises(ValueError, list,
739 self.ipv4_network.subnets(prefixlen_diff=3,
740 new_prefix=27))
741 self.assertEqual(sorted(self.ipv6_network.subnets(prefixlen_diff=4)),
742 sorted(self.ipv6_network.subnets(new_prefix=68)))
743 self.assertRaises(ValueError, list,
744 self.ipv6_network.subnets(new_prefix=63))
745 self.assertRaises(ValueError, list,
746 self.ipv6_network.subnets(prefixlen_diff=4,
747 new_prefix=68))
748
749 def testGetSubnets(self):
750 self.assertEqual(list(self.ipv4_network.subnets())[0].prefixlen, 25)
751 self.assertEqual(str(list(
752 self.ipv4_network.subnets())[0].network_address),
753 '1.2.3.0')
754 self.assertEqual(str(list(
755 self.ipv4_network.subnets())[1].network_address),
756 '1.2.3.128')
757
758 self.assertEqual(list(self.ipv6_network.subnets())[0].prefixlen, 65)
759
760 def testGetSubnetForSingle32(self):
761 ip = ipaddress.IPv4Network('1.2.3.4/32')
762 subnets1 = [str(x) for x in ip.subnets()]
763 subnets2 = [str(x) for x in ip.subnets(2)]
764 self.assertEqual(subnets1, ['1.2.3.4/32'])
765 self.assertEqual(subnets1, subnets2)
766
767 def testGetSubnetForSingle128(self):
768 ip = ipaddress.IPv6Network('::1/128')
769 subnets1 = [str(x) for x in ip.subnets()]
770 subnets2 = [str(x) for x in ip.subnets(2)]
771 self.assertEqual(subnets1, ['::1/128'])
772 self.assertEqual(subnets1, subnets2)
773
774 def testSubnet2(self):
775 ips = [str(x) for x in self.ipv4_network.subnets(2)]
776 self.assertEqual(
777 ips,
778 ['1.2.3.0/26', '1.2.3.64/26', '1.2.3.128/26', '1.2.3.192/26'])
779
780 ipsv6 = [str(x) for x in self.ipv6_network.subnets(2)]
781 self.assertEqual(
782 ipsv6,
783 ['2001:658:22a:cafe::/66',
784 '2001:658:22a:cafe:4000::/66',
785 '2001:658:22a:cafe:8000::/66',
786 '2001:658:22a:cafe:c000::/66'])
787
788 def testSubnetFailsForLargeCidrDiff(self):
789 self.assertRaises(ValueError, list,
790 self.ipv4_interface.network.subnets(9))
791 self.assertRaises(ValueError, list,
792 self.ipv4_network.subnets(9))
793 self.assertRaises(ValueError, list,
794 self.ipv6_interface.network.subnets(65))
795 self.assertRaises(ValueError, list,
796 self.ipv6_network.subnets(65))
797
798 def testSupernetFailsForLargeCidrDiff(self):
799 self.assertRaises(ValueError,
800 self.ipv4_interface.network.supernet, 25)
801 self.assertRaises(ValueError,
802 self.ipv6_interface.network.supernet, 65)
803
804 def testSubnetFailsForNegativeCidrDiff(self):
805 self.assertRaises(ValueError, list,
806 self.ipv4_interface.network.subnets(-1))
807 self.assertRaises(ValueError, list,
Nick Coghlan2c589102012-05-27 01:03:25 +1000808 self.ipv4_network.subnets(-1))
Nick Coghlandc9b2552012-05-20 21:01:57 +1000809 self.assertRaises(ValueError, list,
810 self.ipv6_interface.network.subnets(-1))
811 self.assertRaises(ValueError, list,
812 self.ipv6_network.subnets(-1))
813
814 def testGetNum_Addresses(self):
815 self.assertEqual(self.ipv4_network.num_addresses, 256)
Hynek Schlawack91c5a342012-06-05 11:55:58 +0200816 self.assertEqual(list(self.ipv4_network.subnets())[0].num_addresses,
817 128)
Nick Coghlandc9b2552012-05-20 21:01:57 +1000818 self.assertEqual(self.ipv4_network.supernet().num_addresses, 512)
819
820 self.assertEqual(self.ipv6_network.num_addresses, 18446744073709551616)
821 self.assertEqual(list(self.ipv6_network.subnets())[0].num_addresses,
822 9223372036854775808)
823 self.assertEqual(self.ipv6_network.supernet().num_addresses,
824 36893488147419103232)
825
826 def testContains(self):
827 self.assertTrue(ipaddress.IPv4Interface('1.2.3.128/25') in
828 self.ipv4_network)
829 self.assertFalse(ipaddress.IPv4Interface('1.2.4.1/24') in
830 self.ipv4_network)
831 # We can test addresses and string as well.
832 addr1 = ipaddress.IPv4Address('1.2.3.37')
833 self.assertTrue(addr1 in self.ipv4_network)
834 # issue 61, bad network comparison on like-ip'd network objects
835 # with identical broadcast addresses.
836 self.assertFalse(ipaddress.IPv4Network('1.1.0.0/16').__contains__(
837 ipaddress.IPv4Network('1.0.0.0/15')))
838
Nick Coghlandc9b2552012-05-20 21:01:57 +1000839 def testNth(self):
840 self.assertEqual(str(self.ipv4_network[5]), '1.2.3.5')
841 self.assertRaises(IndexError, self.ipv4_network.__getitem__, 256)
842
843 self.assertEqual(str(self.ipv6_network[5]),
844 '2001:658:22a:cafe::5')
845
846 def testGetitem(self):
847 # http://code.google.com/p/ipaddr-py/issues/detail?id=15
848 addr = ipaddress.IPv4Network('172.31.255.128/255.255.255.240')
849 self.assertEqual(28, addr.prefixlen)
850 addr_list = list(addr)
851 self.assertEqual('172.31.255.128', str(addr_list[0]))
852 self.assertEqual('172.31.255.128', str(addr[0]))
853 self.assertEqual('172.31.255.143', str(addr_list[-1]))
854 self.assertEqual('172.31.255.143', str(addr[-1]))
855 self.assertEqual(addr_list[-1], addr[-1])
856
857 def testEqual(self):
858 self.assertTrue(self.ipv4_interface ==
859 ipaddress.IPv4Interface('1.2.3.4/24'))
860 self.assertFalse(self.ipv4_interface ==
861 ipaddress.IPv4Interface('1.2.3.4/23'))
862 self.assertFalse(self.ipv4_interface ==
863 ipaddress.IPv6Interface('::1.2.3.4/24'))
864 self.assertFalse(self.ipv4_interface == '')
865 self.assertFalse(self.ipv4_interface == [])
866 self.assertFalse(self.ipv4_interface == 2)
867
868 self.assertTrue(self.ipv6_interface ==
869 ipaddress.IPv6Interface('2001:658:22a:cafe:200::1/64'))
870 self.assertFalse(self.ipv6_interface ==
871 ipaddress.IPv6Interface('2001:658:22a:cafe:200::1/63'))
872 self.assertFalse(self.ipv6_interface ==
873 ipaddress.IPv4Interface('1.2.3.4/23'))
874 self.assertFalse(self.ipv6_interface == '')
875 self.assertFalse(self.ipv6_interface == [])
876 self.assertFalse(self.ipv6_interface == 2)
877
878 def testNotEqual(self):
879 self.assertFalse(self.ipv4_interface !=
880 ipaddress.IPv4Interface('1.2.3.4/24'))
881 self.assertTrue(self.ipv4_interface !=
882 ipaddress.IPv4Interface('1.2.3.4/23'))
883 self.assertTrue(self.ipv4_interface !=
884 ipaddress.IPv6Interface('::1.2.3.4/24'))
885 self.assertTrue(self.ipv4_interface != '')
886 self.assertTrue(self.ipv4_interface != [])
887 self.assertTrue(self.ipv4_interface != 2)
888
889 self.assertTrue(self.ipv4_address !=
890 ipaddress.IPv4Address('1.2.3.5'))
891 self.assertTrue(self.ipv4_address != '')
892 self.assertTrue(self.ipv4_address != [])
893 self.assertTrue(self.ipv4_address != 2)
894
895 self.assertFalse(self.ipv6_interface !=
896 ipaddress.IPv6Interface('2001:658:22a:cafe:200::1/64'))
897 self.assertTrue(self.ipv6_interface !=
898 ipaddress.IPv6Interface('2001:658:22a:cafe:200::1/63'))
899 self.assertTrue(self.ipv6_interface !=
900 ipaddress.IPv4Interface('1.2.3.4/23'))
901 self.assertTrue(self.ipv6_interface != '')
902 self.assertTrue(self.ipv6_interface != [])
903 self.assertTrue(self.ipv6_interface != 2)
904
905 self.assertTrue(self.ipv6_address !=
906 ipaddress.IPv4Address('1.2.3.4'))
907 self.assertTrue(self.ipv6_address != '')
908 self.assertTrue(self.ipv6_address != [])
909 self.assertTrue(self.ipv6_address != 2)
910
911 def testSlash32Constructor(self):
912 self.assertEqual(str(ipaddress.IPv4Interface(
913 '1.2.3.4/255.255.255.255')), '1.2.3.4/32')
914
915 def testSlash128Constructor(self):
916 self.assertEqual(str(ipaddress.IPv6Interface('::1/128')),
917 '::1/128')
918
919 def testSlash0Constructor(self):
920 self.assertEqual(str(ipaddress.IPv4Interface('1.2.3.4/0.0.0.0')),
921 '1.2.3.4/0')
922
923 def testCollapsing(self):
924 # test only IP addresses including some duplicates
925 ip1 = ipaddress.IPv4Address('1.1.1.0')
926 ip2 = ipaddress.IPv4Address('1.1.1.1')
927 ip3 = ipaddress.IPv4Address('1.1.1.2')
928 ip4 = ipaddress.IPv4Address('1.1.1.3')
929 ip5 = ipaddress.IPv4Address('1.1.1.4')
930 ip6 = ipaddress.IPv4Address('1.1.1.0')
931 # check that addreses are subsumed properly.
932 collapsed = ipaddress.collapse_addresses(
933 [ip1, ip2, ip3, ip4, ip5, ip6])
Hynek Schlawack91c5a342012-06-05 11:55:58 +0200934 self.assertEqual(list(collapsed),
935 [ipaddress.IPv4Network('1.1.1.0/30'),
936 ipaddress.IPv4Network('1.1.1.4/32')])
Nick Coghlandc9b2552012-05-20 21:01:57 +1000937
938 # test a mix of IP addresses and networks including some duplicates
939 ip1 = ipaddress.IPv4Address('1.1.1.0')
940 ip2 = ipaddress.IPv4Address('1.1.1.1')
941 ip3 = ipaddress.IPv4Address('1.1.1.2')
942 ip4 = ipaddress.IPv4Address('1.1.1.3')
943 #ip5 = ipaddress.IPv4Interface('1.1.1.4/30')
944 #ip6 = ipaddress.IPv4Interface('1.1.1.4/30')
945 # check that addreses are subsumed properly.
946 collapsed = ipaddress.collapse_addresses([ip1, ip2, ip3, ip4])
Hynek Schlawack91c5a342012-06-05 11:55:58 +0200947 self.assertEqual(list(collapsed),
948 [ipaddress.IPv4Network('1.1.1.0/30')])
Nick Coghlandc9b2552012-05-20 21:01:57 +1000949
950 # test only IP networks
951 ip1 = ipaddress.IPv4Network('1.1.0.0/24')
952 ip2 = ipaddress.IPv4Network('1.1.1.0/24')
953 ip3 = ipaddress.IPv4Network('1.1.2.0/24')
954 ip4 = ipaddress.IPv4Network('1.1.3.0/24')
955 ip5 = ipaddress.IPv4Network('1.1.4.0/24')
Hynek Schlawack91c5a342012-06-05 11:55:58 +0200956 # stored in no particular order b/c we want CollapseAddr to call
957 # [].sort
Nick Coghlandc9b2552012-05-20 21:01:57 +1000958 ip6 = ipaddress.IPv4Network('1.1.0.0/22')
959 # check that addreses are subsumed properly.
960 collapsed = ipaddress.collapse_addresses([ip1, ip2, ip3, ip4, ip5,
961 ip6])
Hynek Schlawack91c5a342012-06-05 11:55:58 +0200962 self.assertEqual(list(collapsed),
963 [ipaddress.IPv4Network('1.1.0.0/22'),
964 ipaddress.IPv4Network('1.1.4.0/24')])
Nick Coghlandc9b2552012-05-20 21:01:57 +1000965
966 # test that two addresses are supernet'ed properly
967 collapsed = ipaddress.collapse_addresses([ip1, ip2])
Hynek Schlawack91c5a342012-06-05 11:55:58 +0200968 self.assertEqual(list(collapsed),
969 [ipaddress.IPv4Network('1.1.0.0/23')])
Nick Coghlandc9b2552012-05-20 21:01:57 +1000970
971 # test same IP networks
972 ip_same1 = ip_same2 = ipaddress.IPv4Network('1.1.1.1/32')
973 self.assertEqual(list(ipaddress.collapse_addresses(
974 [ip_same1, ip_same2])),
975 [ip_same1])
976
977 # test same IP addresses
978 ip_same1 = ip_same2 = ipaddress.IPv4Address('1.1.1.1')
979 self.assertEqual(list(ipaddress.collapse_addresses(
980 [ip_same1, ip_same2])),
981 [ipaddress.ip_network('1.1.1.1/32')])
982 ip1 = ipaddress.IPv6Network('2001::/100')
983 ip2 = ipaddress.IPv6Network('2001::/120')
984 ip3 = ipaddress.IPv6Network('2001::/96')
985 # test that ipv6 addresses are subsumed properly.
986 collapsed = ipaddress.collapse_addresses([ip1, ip2, ip3])
987 self.assertEqual(list(collapsed), [ip3])
988
989 # the toejam test
Hynek Schlawack35db5132012-06-01 20:12:17 +0200990 addr_tuples = [
991 (ipaddress.ip_address('1.1.1.1'),
992 ipaddress.ip_address('::1')),
993 (ipaddress.IPv4Network('1.1.0.0/24'),
994 ipaddress.IPv6Network('2001::/120')),
995 (ipaddress.IPv4Network('1.1.0.0/32'),
996 ipaddress.IPv6Network('2001::/128')),
997 ]
998 for ip1, ip2 in addr_tuples:
999 self.assertRaises(TypeError, ipaddress.collapse_addresses,
1000 [ip1, ip2])
Nick Coghlandc9b2552012-05-20 21:01:57 +10001001
1002 def testSummarizing(self):
1003 #ip = ipaddress.ip_address
1004 #ipnet = ipaddress.ip_network
1005 summarize = ipaddress.summarize_address_range
1006 ip1 = ipaddress.ip_address('1.1.1.0')
1007 ip2 = ipaddress.ip_address('1.1.1.255')
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001008
1009 # summarize works only for IPv4 & IPv6
1010 class IPv7Address(ipaddress.IPv6Address):
1011 @property
1012 def version(self):
1013 return 7
1014 ip_invalid1 = IPv7Address('::1')
1015 ip_invalid2 = IPv7Address('::1')
1016 self.assertRaises(ValueError, list,
1017 summarize(ip_invalid1, ip_invalid2))
1018 # test that a summary over ip4 & ip6 fails
1019 self.assertRaises(TypeError, list,
1020 summarize(ip1, ipaddress.IPv6Address('::1')))
1021 # test a /24 is summarized properly
Nick Coghlandc9b2552012-05-20 21:01:57 +10001022 self.assertEqual(list(summarize(ip1, ip2))[0],
1023 ipaddress.ip_network('1.1.1.0/24'))
1024 # test an IPv4 range that isn't on a network byte boundary
1025 ip2 = ipaddress.ip_address('1.1.1.8')
1026 self.assertEqual(list(summarize(ip1, ip2)),
1027 [ipaddress.ip_network('1.1.1.0/29'),
1028 ipaddress.ip_network('1.1.1.8')])
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001029 # all!
1030 ip1 = ipaddress.IPv4Address(0)
1031 ip2 = ipaddress.IPv4Address(ipaddress.IPv4Address._ALL_ONES)
1032 self.assertEqual([ipaddress.IPv4Network('0.0.0.0/0')],
1033 list(summarize(ip1, ip2)))
Nick Coghlandc9b2552012-05-20 21:01:57 +10001034
1035 ip1 = ipaddress.ip_address('1::')
1036 ip2 = ipaddress.ip_address('1:ffff:ffff:ffff:ffff:ffff:ffff:ffff')
1037 # test a IPv6 is sumamrized properly
1038 self.assertEqual(list(summarize(ip1, ip2))[0],
1039 ipaddress.ip_network('1::/16'))
1040 # test an IPv6 range that isn't on a network byte boundary
1041 ip2 = ipaddress.ip_address('2::')
1042 self.assertEqual(list(summarize(ip1, ip2)),
1043 [ipaddress.ip_network('1::/16'),
1044 ipaddress.ip_network('2::/128')])
1045
1046 # test exception raised when first is greater than last
1047 self.assertRaises(ValueError, list,
1048 summarize(ipaddress.ip_address('1.1.1.0'),
1049 ipaddress.ip_address('1.1.0.0')))
1050 # test exception raised when first and last aren't IP addresses
1051 self.assertRaises(TypeError, list,
1052 summarize(ipaddress.ip_network('1.1.1.0'),
1053 ipaddress.ip_network('1.1.0.0')))
1054 self.assertRaises(TypeError, list,
1055 summarize(ipaddress.ip_network('1.1.1.0'),
1056 ipaddress.ip_network('1.1.0.0')))
1057 # test exception raised when first and last are not same version
1058 self.assertRaises(TypeError, list,
1059 summarize(ipaddress.ip_address('::'),
1060 ipaddress.ip_network('1.1.0.0')))
1061
1062 def testAddressComparison(self):
1063 self.assertTrue(ipaddress.ip_address('1.1.1.1') <=
1064 ipaddress.ip_address('1.1.1.1'))
1065 self.assertTrue(ipaddress.ip_address('1.1.1.1') <=
1066 ipaddress.ip_address('1.1.1.2'))
1067 self.assertTrue(ipaddress.ip_address('::1') <=
1068 ipaddress.ip_address('::1'))
1069 self.assertTrue(ipaddress.ip_address('::1') <=
1070 ipaddress.ip_address('::2'))
1071
Nick Coghlan3008ec02012-07-08 00:45:33 +10001072 def testInterfaceComparison(self):
1073 self.assertTrue(ipaddress.ip_interface('1.1.1.1') <=
1074 ipaddress.ip_interface('1.1.1.1'))
1075 self.assertTrue(ipaddress.ip_interface('1.1.1.1') <=
1076 ipaddress.ip_interface('1.1.1.2'))
1077 self.assertTrue(ipaddress.ip_interface('::1') <=
1078 ipaddress.ip_interface('::1'))
1079 self.assertTrue(ipaddress.ip_interface('::1') <=
1080 ipaddress.ip_interface('::2'))
1081
Nick Coghlandc9b2552012-05-20 21:01:57 +10001082 def testNetworkComparison(self):
1083 # ip1 and ip2 have the same network address
1084 ip1 = ipaddress.IPv4Network('1.1.1.0/24')
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001085 ip2 = ipaddress.IPv4Network('1.1.1.0/32')
Nick Coghlandc9b2552012-05-20 21:01:57 +10001086 ip3 = ipaddress.IPv4Network('1.1.2.0/24')
1087
1088 self.assertTrue(ip1 < ip3)
1089 self.assertTrue(ip3 > ip2)
1090
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001091 self.assertEqual(ip1.compare_networks(ip1), 0)
1092
1093 # if addresses are the same, sort by netmask
1094 self.assertEqual(ip1.compare_networks(ip2), -1)
1095 self.assertEqual(ip2.compare_networks(ip1), 1)
1096
Nick Coghlandc9b2552012-05-20 21:01:57 +10001097 self.assertEqual(ip1.compare_networks(ip3), -1)
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001098 self.assertEqual(ip3.compare_networks(ip1), 1)
Nick Coghlandc9b2552012-05-20 21:01:57 +10001099 self.assertTrue(ip1._get_networks_key() < ip3._get_networks_key())
1100
1101 ip1 = ipaddress.IPv6Network('2001:2000::/96')
1102 ip2 = ipaddress.IPv6Network('2001:2001::/96')
1103 ip3 = ipaddress.IPv6Network('2001:ffff:2000::/96')
1104
1105 self.assertTrue(ip1 < ip3)
1106 self.assertTrue(ip3 > ip2)
1107 self.assertEqual(ip1.compare_networks(ip3), -1)
1108 self.assertTrue(ip1._get_networks_key() < ip3._get_networks_key())
1109
1110 # Test comparing different protocols.
1111 # Should always raise a TypeError.
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001112 self.assertRaises(TypeError,
1113 self.ipv4_network.compare_networks,
1114 self.ipv6_network)
Nick Coghlandc9b2552012-05-20 21:01:57 +10001115 ipv6 = ipaddress.IPv6Interface('::/0')
1116 ipv4 = ipaddress.IPv4Interface('0.0.0.0/0')
1117 self.assertRaises(TypeError, ipv4.__lt__, ipv6)
1118 self.assertRaises(TypeError, ipv4.__gt__, ipv6)
1119 self.assertRaises(TypeError, ipv6.__lt__, ipv4)
1120 self.assertRaises(TypeError, ipv6.__gt__, ipv4)
1121
1122 # Regression test for issue 19.
1123 ip1 = ipaddress.ip_network('10.1.2.128/25')
1124 self.assertFalse(ip1 < ip1)
1125 self.assertFalse(ip1 > ip1)
1126 ip2 = ipaddress.ip_network('10.1.3.0/24')
1127 self.assertTrue(ip1 < ip2)
1128 self.assertFalse(ip2 < ip1)
1129 self.assertFalse(ip1 > ip2)
1130 self.assertTrue(ip2 > ip1)
1131 ip3 = ipaddress.ip_network('10.1.3.0/25')
1132 self.assertTrue(ip2 < ip3)
1133 self.assertFalse(ip3 < ip2)
1134 self.assertFalse(ip2 > ip3)
1135 self.assertTrue(ip3 > ip2)
1136
1137 # Regression test for issue 28.
1138 ip1 = ipaddress.ip_network('10.10.10.0/31')
1139 ip2 = ipaddress.ip_network('10.10.10.0')
1140 ip3 = ipaddress.ip_network('10.10.10.2/31')
1141 ip4 = ipaddress.ip_network('10.10.10.2')
1142 sorted = [ip1, ip2, ip3, ip4]
1143 unsorted = [ip2, ip4, ip1, ip3]
1144 unsorted.sort()
1145 self.assertEqual(sorted, unsorted)
1146 unsorted = [ip4, ip1, ip3, ip2]
1147 unsorted.sort()
1148 self.assertEqual(sorted, unsorted)
1149 self.assertRaises(TypeError, ip1.__lt__,
1150 ipaddress.ip_address('10.10.10.0'))
1151 self.assertRaises(TypeError, ip2.__lt__,
1152 ipaddress.ip_address('10.10.10.0'))
1153
1154 # <=, >=
1155 self.assertTrue(ipaddress.ip_network('1.1.1.1') <=
1156 ipaddress.ip_network('1.1.1.1'))
1157 self.assertTrue(ipaddress.ip_network('1.1.1.1') <=
1158 ipaddress.ip_network('1.1.1.2'))
1159 self.assertFalse(ipaddress.ip_network('1.1.1.2') <=
1160 ipaddress.ip_network('1.1.1.1'))
1161 self.assertTrue(ipaddress.ip_network('::1') <=
1162 ipaddress.ip_network('::1'))
1163 self.assertTrue(ipaddress.ip_network('::1') <=
1164 ipaddress.ip_network('::2'))
1165 self.assertFalse(ipaddress.ip_network('::2') <=
1166 ipaddress.ip_network('::1'))
1167
1168 def testStrictNetworks(self):
1169 self.assertRaises(ValueError, ipaddress.ip_network, '192.168.1.1/24')
1170 self.assertRaises(ValueError, ipaddress.ip_network, '::1/120')
1171
1172 def testOverlaps(self):
1173 other = ipaddress.IPv4Network('1.2.3.0/30')
1174 other2 = ipaddress.IPv4Network('1.2.2.0/24')
1175 other3 = ipaddress.IPv4Network('1.2.2.64/26')
1176 self.assertTrue(self.ipv4_network.overlaps(other))
1177 self.assertFalse(self.ipv4_network.overlaps(other2))
1178 self.assertTrue(other2.overlaps(other3))
1179
1180 def testEmbeddedIpv4(self):
1181 ipv4_string = '192.168.0.1'
1182 ipv4 = ipaddress.IPv4Interface(ipv4_string)
1183 v4compat_ipv6 = ipaddress.IPv6Interface('::%s' % ipv4_string)
1184 self.assertEqual(int(v4compat_ipv6.ip), int(ipv4.ip))
1185 v4mapped_ipv6 = ipaddress.IPv6Interface('::ffff:%s' % ipv4_string)
1186 self.assertNotEqual(v4mapped_ipv6.ip, ipv4.ip)
1187 self.assertRaises(ipaddress.AddressValueError, ipaddress.IPv6Interface,
1188 '2001:1.1.1.1:1.1.1.1')
1189
1190 # Issue 67: IPv6 with embedded IPv4 address not recognized.
1191 def testIPv6AddressTooLarge(self):
1192 # RFC4291 2.5.5.2
1193 self.assertEqual(ipaddress.ip_address('::FFFF:192.0.2.1'),
1194 ipaddress.ip_address('::FFFF:c000:201'))
1195 # RFC4291 2.2 (part 3) x::d.d.d.d
1196 self.assertEqual(ipaddress.ip_address('FFFF::192.0.2.1'),
1197 ipaddress.ip_address('FFFF::c000:201'))
1198
1199 def testIPVersion(self):
1200 self.assertEqual(self.ipv4_address.version, 4)
1201 self.assertEqual(self.ipv6_address.version, 6)
1202
1203 def testMaxPrefixLength(self):
1204 self.assertEqual(self.ipv4_interface.max_prefixlen, 32)
1205 self.assertEqual(self.ipv6_interface.max_prefixlen, 128)
1206
1207 def testPacked(self):
1208 self.assertEqual(self.ipv4_address.packed,
Nick Coghlan5cf896f2012-07-07 01:43:31 +10001209 b'\x01\x02\x03\x04')
Nick Coghlandc9b2552012-05-20 21:01:57 +10001210 self.assertEqual(ipaddress.IPv4Interface('255.254.253.252').packed,
Nick Coghlan5cf896f2012-07-07 01:43:31 +10001211 b'\xff\xfe\xfd\xfc')
Nick Coghlandc9b2552012-05-20 21:01:57 +10001212 self.assertEqual(self.ipv6_address.packed,
Nick Coghlan5cf896f2012-07-07 01:43:31 +10001213 b'\x20\x01\x06\x58\x02\x2a\xca\xfe'
1214 b'\x02\x00\x00\x00\x00\x00\x00\x01')
Nick Coghlandc9b2552012-05-20 21:01:57 +10001215 self.assertEqual(ipaddress.IPv6Interface('ffff:2:3:4:ffff::').packed,
Nick Coghlan5cf896f2012-07-07 01:43:31 +10001216 b'\xff\xff\x00\x02\x00\x03\x00\x04\xff\xff'
1217 + b'\x00' * 6)
Nick Coghlandc9b2552012-05-20 21:01:57 +10001218 self.assertEqual(ipaddress.IPv6Interface('::1:0:0:0:0').packed,
Nick Coghlan5cf896f2012-07-07 01:43:31 +10001219 b'\x00' * 6 + b'\x00\x01' + b'\x00' * 8)
Nick Coghlandc9b2552012-05-20 21:01:57 +10001220
1221 def testIpStrFromPrefixlen(self):
1222 ipv4 = ipaddress.IPv4Interface('1.2.3.4/24')
1223 self.assertEqual(ipv4._ip_string_from_prefix(), '255.255.255.0')
1224 self.assertEqual(ipv4._ip_string_from_prefix(28), '255.255.255.240')
1225
1226 def testIpType(self):
1227 ipv4net = ipaddress.ip_network('1.2.3.4')
1228 ipv4addr = ipaddress.ip_address('1.2.3.4')
1229 ipv6net = ipaddress.ip_network('::1.2.3.4')
1230 ipv6addr = ipaddress.ip_address('::1.2.3.4')
1231 self.assertEqual(ipaddress.IPv4Network, type(ipv4net))
1232 self.assertEqual(ipaddress.IPv4Address, type(ipv4addr))
1233 self.assertEqual(ipaddress.IPv6Network, type(ipv6net))
1234 self.assertEqual(ipaddress.IPv6Address, type(ipv6addr))
1235
1236 def testReservedIpv4(self):
1237 # test networks
1238 self.assertEqual(True, ipaddress.ip_interface(
1239 '224.1.1.1/31').is_multicast)
1240 self.assertEqual(False, ipaddress.ip_network('240.0.0.0').is_multicast)
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001241 self.assertEqual(True, ipaddress.ip_network('240.0.0.0').is_reserved)
Nick Coghlandc9b2552012-05-20 21:01:57 +10001242
1243 self.assertEqual(True, ipaddress.ip_interface(
1244 '192.168.1.1/17').is_private)
1245 self.assertEqual(False, ipaddress.ip_network('192.169.0.0').is_private)
1246 self.assertEqual(True, ipaddress.ip_network(
1247 '10.255.255.255').is_private)
1248 self.assertEqual(False, ipaddress.ip_network('11.0.0.0').is_private)
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001249 self.assertEqual(False, ipaddress.ip_network('11.0.0.0').is_reserved)
Nick Coghlandc9b2552012-05-20 21:01:57 +10001250 self.assertEqual(True, ipaddress.ip_network(
1251 '172.31.255.255').is_private)
1252 self.assertEqual(False, ipaddress.ip_network('172.32.0.0').is_private)
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001253 self.assertEqual(True,
1254 ipaddress.ip_network('169.254.1.0/24').is_link_local)
Nick Coghlandc9b2552012-05-20 21:01:57 +10001255
1256 self.assertEqual(True,
1257 ipaddress.ip_interface(
1258 '169.254.100.200/24').is_link_local)
1259 self.assertEqual(False,
1260 ipaddress.ip_interface(
1261 '169.255.100.200/24').is_link_local)
1262
1263 self.assertEqual(True,
1264 ipaddress.ip_network(
1265 '127.100.200.254/32').is_loopback)
1266 self.assertEqual(True, ipaddress.ip_network(
1267 '127.42.0.0/16').is_loopback)
1268 self.assertEqual(False, ipaddress.ip_network('128.0.0.0').is_loopback)
1269
1270 # test addresses
Hynek Schlawackbcd30442012-06-04 14:19:39 +02001271 self.assertEqual(True, ipaddress.ip_address('0.0.0.0').is_unspecified)
Nick Coghlandc9b2552012-05-20 21:01:57 +10001272 self.assertEqual(True, ipaddress.ip_address('224.1.1.1').is_multicast)
1273 self.assertEqual(False, ipaddress.ip_address('240.0.0.0').is_multicast)
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001274 self.assertEqual(True, ipaddress.ip_address('240.0.0.1').is_reserved)
1275 self.assertEqual(False,
1276 ipaddress.ip_address('239.255.255.255').is_reserved)
Nick Coghlandc9b2552012-05-20 21:01:57 +10001277
1278 self.assertEqual(True, ipaddress.ip_address('192.168.1.1').is_private)
1279 self.assertEqual(False, ipaddress.ip_address('192.169.0.0').is_private)
1280 self.assertEqual(True, ipaddress.ip_address(
1281 '10.255.255.255').is_private)
1282 self.assertEqual(False, ipaddress.ip_address('11.0.0.0').is_private)
1283 self.assertEqual(True, ipaddress.ip_address(
1284 '172.31.255.255').is_private)
1285 self.assertEqual(False, ipaddress.ip_address('172.32.0.0').is_private)
1286
1287 self.assertEqual(True,
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001288 ipaddress.ip_address('169.254.100.200').is_link_local)
Nick Coghlandc9b2552012-05-20 21:01:57 +10001289 self.assertEqual(False,
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001290 ipaddress.ip_address('169.255.100.200').is_link_local)
Nick Coghlandc9b2552012-05-20 21:01:57 +10001291
1292 self.assertEqual(True,
1293 ipaddress.ip_address('127.100.200.254').is_loopback)
1294 self.assertEqual(True, ipaddress.ip_address('127.42.0.0').is_loopback)
1295 self.assertEqual(False, ipaddress.ip_address('128.0.0.0').is_loopback)
1296 self.assertEqual(True, ipaddress.ip_network('0.0.0.0').is_unspecified)
1297
1298 def testReservedIpv6(self):
1299
1300 self.assertEqual(True, ipaddress.ip_network('ffff::').is_multicast)
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001301 self.assertEqual(True, ipaddress.ip_network(2**128 - 1).is_multicast)
Nick Coghlandc9b2552012-05-20 21:01:57 +10001302 self.assertEqual(True, ipaddress.ip_network('ff00::').is_multicast)
1303 self.assertEqual(False, ipaddress.ip_network('fdff::').is_multicast)
1304
1305 self.assertEqual(True, ipaddress.ip_network('fecf::').is_site_local)
1306 self.assertEqual(True, ipaddress.ip_network(
1307 'feff:ffff:ffff:ffff::').is_site_local)
1308 self.assertEqual(False, ipaddress.ip_network(
1309 'fbf:ffff::').is_site_local)
1310 self.assertEqual(False, ipaddress.ip_network('ff00::').is_site_local)
1311
1312 self.assertEqual(True, ipaddress.ip_network('fc00::').is_private)
1313 self.assertEqual(True, ipaddress.ip_network(
1314 'fc00:ffff:ffff:ffff::').is_private)
1315 self.assertEqual(False, ipaddress.ip_network('fbff:ffff::').is_private)
1316 self.assertEqual(False, ipaddress.ip_network('fe00::').is_private)
1317
1318 self.assertEqual(True, ipaddress.ip_network('fea0::').is_link_local)
1319 self.assertEqual(True, ipaddress.ip_network(
1320 'febf:ffff::').is_link_local)
1321 self.assertEqual(False, ipaddress.ip_network(
1322 'fe7f:ffff::').is_link_local)
1323 self.assertEqual(False, ipaddress.ip_network('fec0::').is_link_local)
1324
1325 self.assertEqual(True, ipaddress.ip_interface('0:0::0:01').is_loopback)
1326 self.assertEqual(False, ipaddress.ip_interface('::1/127').is_loopback)
1327 self.assertEqual(False, ipaddress.ip_network('::').is_loopback)
1328 self.assertEqual(False, ipaddress.ip_network('::2').is_loopback)
1329
1330 self.assertEqual(True, ipaddress.ip_network('0::0').is_unspecified)
1331 self.assertEqual(False, ipaddress.ip_network('::1').is_unspecified)
1332 self.assertEqual(False, ipaddress.ip_network('::/127').is_unspecified)
1333
1334 # test addresses
1335 self.assertEqual(True, ipaddress.ip_address('ffff::').is_multicast)
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001336 self.assertEqual(True, ipaddress.ip_address(2**128 - 1).is_multicast)
Nick Coghlandc9b2552012-05-20 21:01:57 +10001337 self.assertEqual(True, ipaddress.ip_address('ff00::').is_multicast)
1338 self.assertEqual(False, ipaddress.ip_address('fdff::').is_multicast)
1339
1340 self.assertEqual(True, ipaddress.ip_address('fecf::').is_site_local)
1341 self.assertEqual(True, ipaddress.ip_address(
1342 'feff:ffff:ffff:ffff::').is_site_local)
1343 self.assertEqual(False, ipaddress.ip_address(
1344 'fbf:ffff::').is_site_local)
1345 self.assertEqual(False, ipaddress.ip_address('ff00::').is_site_local)
1346
1347 self.assertEqual(True, ipaddress.ip_address('fc00::').is_private)
1348 self.assertEqual(True, ipaddress.ip_address(
1349 'fc00:ffff:ffff:ffff::').is_private)
1350 self.assertEqual(False, ipaddress.ip_address('fbff:ffff::').is_private)
1351 self.assertEqual(False, ipaddress.ip_address('fe00::').is_private)
1352
1353 self.assertEqual(True, ipaddress.ip_address('fea0::').is_link_local)
1354 self.assertEqual(True, ipaddress.ip_address(
1355 'febf:ffff::').is_link_local)
1356 self.assertEqual(False, ipaddress.ip_address(
1357 'fe7f:ffff::').is_link_local)
1358 self.assertEqual(False, ipaddress.ip_address('fec0::').is_link_local)
1359
1360 self.assertEqual(True, ipaddress.ip_address('0:0::0:01').is_loopback)
1361 self.assertEqual(True, ipaddress.ip_address('::1').is_loopback)
1362 self.assertEqual(False, ipaddress.ip_address('::2').is_loopback)
1363
1364 self.assertEqual(True, ipaddress.ip_address('0::0').is_unspecified)
1365 self.assertEqual(False, ipaddress.ip_address('::1').is_unspecified)
1366
1367 # some generic IETF reserved addresses
1368 self.assertEqual(True, ipaddress.ip_address('100::').is_reserved)
1369 self.assertEqual(True, ipaddress.ip_network('4000::1/128').is_reserved)
1370
1371 def testIpv4Mapped(self):
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001372 self.assertEqual(
1373 ipaddress.ip_address('::ffff:192.168.1.1').ipv4_mapped,
1374 ipaddress.ip_address('192.168.1.1'))
Nick Coghlandc9b2552012-05-20 21:01:57 +10001375 self.assertEqual(ipaddress.ip_address('::c0a8:101').ipv4_mapped, None)
1376 self.assertEqual(ipaddress.ip_address('::ffff:c0a8:101').ipv4_mapped,
1377 ipaddress.ip_address('192.168.1.1'))
1378
1379 def testAddrExclude(self):
1380 addr1 = ipaddress.ip_network('10.1.1.0/24')
1381 addr2 = ipaddress.ip_network('10.1.1.0/26')
1382 addr3 = ipaddress.ip_network('10.2.1.0/24')
1383 addr4 = ipaddress.ip_address('10.1.1.0')
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001384 addr5 = ipaddress.ip_network('2001:db8::0/32')
Nick Coghlandc9b2552012-05-20 21:01:57 +10001385 self.assertEqual(sorted(list(addr1.address_exclude(addr2))),
1386 [ipaddress.ip_network('10.1.1.64/26'),
1387 ipaddress.ip_network('10.1.1.128/25')])
1388 self.assertRaises(ValueError, list, addr1.address_exclude(addr3))
1389 self.assertRaises(TypeError, list, addr1.address_exclude(addr4))
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001390 self.assertRaises(TypeError, list, addr1.address_exclude(addr5))
Nick Coghlandc9b2552012-05-20 21:01:57 +10001391 self.assertEqual(list(addr1.address_exclude(addr1)), [])
1392
1393 def testHash(self):
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001394 self.assertEqual(hash(ipaddress.ip_interface('10.1.1.0/24')),
1395 hash(ipaddress.ip_interface('10.1.1.0/24')))
Nick Coghlandc9b2552012-05-20 21:01:57 +10001396 self.assertEqual(hash(ipaddress.ip_network('10.1.1.0/24')),
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001397 hash(ipaddress.ip_network('10.1.1.0/24')))
Nick Coghlandc9b2552012-05-20 21:01:57 +10001398 self.assertEqual(hash(ipaddress.ip_address('10.1.1.0')),
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001399 hash(ipaddress.ip_address('10.1.1.0')))
Nick Coghlandc9b2552012-05-20 21:01:57 +10001400 # i70
1401 self.assertEqual(hash(ipaddress.ip_address('1.2.3.4')),
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001402 hash(ipaddress.ip_address(
Nick Coghlandc9b2552012-05-20 21:01:57 +10001403 int(ipaddress.ip_address('1.2.3.4')._ip))))
1404 ip1 = ipaddress.ip_address('10.1.1.0')
1405 ip2 = ipaddress.ip_address('1::')
1406 dummy = {}
1407 dummy[self.ipv4_address] = None
1408 dummy[self.ipv6_address] = None
1409 dummy[ip1] = None
1410 dummy[ip2] = None
1411 self.assertTrue(self.ipv4_address in dummy)
1412 self.assertTrue(ip2 in dummy)
1413
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001414 def testIPBases(self):
1415 net = self.ipv4_network
1416 self.assertEqual('1.2.3.0/24', net.compressed)
1417 self.assertEqual(
1418 net._ip_int_from_prefix(24),
1419 net._ip_int_from_prefix(None))
1420 net = self.ipv6_network
1421 self.assertRaises(ValueError, net._string_from_ip_int, 2**128 + 1)
1422 self.assertEqual(
1423 self.ipv6_address._string_from_ip_int(self.ipv6_address._ip),
1424 self.ipv6_address._string_from_ip_int(None))
1425
Hynek Schlawack454a74d2012-06-04 18:14:02 +02001426 def testIPv6NetworkHelpers(self):
1427 net = self.ipv6_network
1428 self.assertEqual('2001:658:22a:cafe::/64', net.with_prefixlen)
1429 self.assertEqual('2001:658:22a:cafe::/ffff:ffff:ffff:ffff::',
1430 net.with_netmask)
1431 self.assertEqual('2001:658:22a:cafe::/::ffff:ffff:ffff:ffff',
1432 net.with_hostmask)
1433 self.assertEqual('2001:658:22a:cafe::/64', str(net))
1434
1435 def testIPv4NetworkHelpers(self):
1436 net = self.ipv4_network
1437 self.assertEqual('1.2.3.0/24', net.with_prefixlen)
1438 self.assertEqual('1.2.3.0/255.255.255.0', net.with_netmask)
1439 self.assertEqual('1.2.3.0/0.0.0.255', net.with_hostmask)
1440 self.assertEqual('1.2.3.0/24', str(net))
1441
Nick Coghlandc9b2552012-05-20 21:01:57 +10001442 def testCopyConstructor(self):
1443 addr1 = ipaddress.ip_network('10.1.1.0/24')
1444 addr2 = ipaddress.ip_network(addr1)
1445 addr3 = ipaddress.ip_interface('2001:658:22a:cafe:200::1/64')
1446 addr4 = ipaddress.ip_interface(addr3)
1447 addr5 = ipaddress.IPv4Address('1.1.1.1')
1448 addr6 = ipaddress.IPv6Address('2001:658:22a:cafe:200::1')
1449
1450 self.assertEqual(addr1, addr2)
1451 self.assertEqual(addr3, addr4)
1452 self.assertEqual(addr5, ipaddress.IPv4Address(addr5))
1453 self.assertEqual(addr6, ipaddress.IPv6Address(addr6))
1454
1455 def testCompressIPv6Address(self):
1456 test_addresses = {
1457 '1:2:3:4:5:6:7:8': '1:2:3:4:5:6:7:8/128',
1458 '2001:0:0:4:0:0:0:8': '2001:0:0:4::8/128',
1459 '2001:0:0:4:5:6:7:8': '2001::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 '2001:0:3:4:5:6:7:8': '2001:0:3:4:5:6:7:8/128',
1462 '0:0:3:0:0:0:0:ffff': '0:0:3::ffff/128',
1463 '0:0:0:4:0:0:0:ffff': '::4:0:0:0:ffff/128',
1464 '0:0:0:0:5:0:0:ffff': '::5:0:0:ffff/128',
1465 '1:0:0:4:0:0:7:8': '1::4:0:0:7:8/128',
1466 '0:0:0:0:0:0:0:0': '::/128',
1467 '0:0:0:0:0:0:0:0/0': '::/0',
1468 '0:0:0:0:0:0:0:1': '::1/128',
1469 '2001:0658:022a:cafe:0000:0000:0000:0000/66':
1470 '2001:658:22a:cafe::/66',
1471 '::1.2.3.4': '::102:304/128',
1472 '1:2:3:4:5:ffff:1.2.3.4': '1:2:3:4:5:ffff:102:304/128',
1473 '::7:6:5:4:3:2:1': '0:7:6:5:4:3:2:1/128',
1474 '::7:6:5:4:3:2:0': '0:7:6:5:4:3:2:0/128',
1475 '7:6:5:4:3:2:1::': '7:6:5:4:3:2:1:0/128',
1476 '0:6:5:4:3:2:1::': '0:6:5:4:3:2:1:0/128',
1477 }
1478 for uncompressed, compressed in list(test_addresses.items()):
1479 self.assertEqual(compressed, str(ipaddress.IPv6Interface(
1480 uncompressed)))
1481
1482 def testExplodeShortHandIpStr(self):
1483 addr1 = ipaddress.IPv6Interface('2001::1')
1484 addr2 = ipaddress.IPv6Address('2001:0:5ef5:79fd:0:59d:a0e5:ba1')
1485 addr3 = ipaddress.IPv6Network('2001::/96')
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001486 addr4 = ipaddress.IPv4Address('192.168.178.1')
Nick Coghlandc9b2552012-05-20 21:01:57 +10001487 self.assertEqual('2001:0000:0000:0000:0000:0000:0000:0001/128',
1488 addr1.exploded)
1489 self.assertEqual('0000:0000:0000:0000:0000:0000:0000:0001/128',
1490 ipaddress.IPv6Interface('::1/128').exploded)
1491 # issue 77
1492 self.assertEqual('2001:0000:5ef5:79fd:0000:059d:a0e5:0ba1',
1493 addr2.exploded)
1494 self.assertEqual('2001:0000:0000:0000:0000:0000:0000:0000/96',
1495 addr3.exploded)
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001496 self.assertEqual('192.168.178.1', addr4.exploded)
Nick Coghlandc9b2552012-05-20 21:01:57 +10001497
1498 def testIntRepresentation(self):
1499 self.assertEqual(16909060, int(self.ipv4_address))
1500 self.assertEqual(42540616829182469433547762482097946625,
1501 int(self.ipv6_address))
1502
1503 def testHexRepresentation(self):
1504 self.assertEqual(hex(0x1020304),
1505 hex(self.ipv4_address))
1506
1507 self.assertEqual(hex(0x20010658022ACAFE0200000000000001),
1508 hex(self.ipv6_address))
1509
1510 def testForceVersion(self):
1511 self.assertEqual(ipaddress.ip_network(1).version, 4)
Nick Coghlan51c30672012-05-27 00:25:58 +10001512 self.assertEqual(ipaddress.IPv6Network(1).version, 6)
Sandro Tosi876ecad2012-05-23 22:26:55 +02001513
Nick Coghlandc9b2552012-05-20 21:01:57 +10001514 def testWithStar(self):
1515 self.assertEqual(str(self.ipv4_interface.with_prefixlen), "1.2.3.4/24")
1516 self.assertEqual(str(self.ipv4_interface.with_netmask),
1517 "1.2.3.4/255.255.255.0")
1518 self.assertEqual(str(self.ipv4_interface.with_hostmask),
1519 "1.2.3.4/0.0.0.255")
1520
1521 self.assertEqual(str(self.ipv6_interface.with_prefixlen),
1522 '2001:658:22a:cafe:200::1/64')
1523 # rfc3513 sec 2.3 says that ipv6 only uses cidr notation for
1524 # subnets
1525 self.assertEqual(str(self.ipv6_interface.with_netmask),
1526 '2001:658:22a:cafe:200::1/64')
1527 # this probably don't make much sense, but it's included for
1528 # compatibility with ipv4
1529 self.assertEqual(str(self.ipv6_interface.with_hostmask),
1530 '2001:658:22a:cafe:200::1/::ffff:ffff:ffff:ffff')
1531
1532 def testNetworkElementCaching(self):
1533 # V4 - make sure we're empty
1534 self.assertFalse('network_address' in self.ipv4_network._cache)
1535 self.assertFalse('broadcast_address' in self.ipv4_network._cache)
1536 self.assertFalse('hostmask' in self.ipv4_network._cache)
1537
1538 # V4 - populate and test
1539 self.assertEqual(self.ipv4_network.network_address,
1540 ipaddress.IPv4Address('1.2.3.0'))
1541 self.assertEqual(self.ipv4_network.broadcast_address,
1542 ipaddress.IPv4Address('1.2.3.255'))
1543 self.assertEqual(self.ipv4_network.hostmask,
1544 ipaddress.IPv4Address('0.0.0.255'))
1545
1546 # V4 - check we're cached
1547 self.assertTrue('broadcast_address' in self.ipv4_network._cache)
1548 self.assertTrue('hostmask' in self.ipv4_network._cache)
1549
1550 # V6 - make sure we're empty
1551 self.assertFalse('broadcast_address' in self.ipv6_network._cache)
1552 self.assertFalse('hostmask' in self.ipv6_network._cache)
1553
1554 # V6 - populate and test
1555 self.assertEqual(self.ipv6_network.network_address,
1556 ipaddress.IPv6Address('2001:658:22a:cafe::'))
1557 self.assertEqual(self.ipv6_interface.network.network_address,
1558 ipaddress.IPv6Address('2001:658:22a:cafe::'))
1559
1560 self.assertEqual(
1561 self.ipv6_network.broadcast_address,
1562 ipaddress.IPv6Address('2001:658:22a:cafe:ffff:ffff:ffff:ffff'))
1563 self.assertEqual(self.ipv6_network.hostmask,
1564 ipaddress.IPv6Address('::ffff:ffff:ffff:ffff'))
1565 self.assertEqual(
1566 self.ipv6_interface.network.broadcast_address,
1567 ipaddress.IPv6Address('2001:658:22a:cafe:ffff:ffff:ffff:ffff'))
1568 self.assertEqual(self.ipv6_interface.network.hostmask,
1569 ipaddress.IPv6Address('::ffff:ffff:ffff:ffff'))
1570
1571 # V6 - check we're cached
1572 self.assertTrue('broadcast_address' in self.ipv6_network._cache)
1573 self.assertTrue('hostmask' in self.ipv6_network._cache)
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001574 self.assertTrue(
1575 'broadcast_address' in self.ipv6_interface.network._cache)
Nick Coghlandc9b2552012-05-20 21:01:57 +10001576 self.assertTrue('hostmask' in self.ipv6_interface.network._cache)
1577
1578 def testTeredo(self):
1579 # stolen from wikipedia
1580 server = ipaddress.IPv4Address('65.54.227.120')
1581 client = ipaddress.IPv4Address('192.0.2.45')
1582 teredo_addr = '2001:0000:4136:e378:8000:63bf:3fff:fdd2'
1583 self.assertEqual((server, client),
1584 ipaddress.ip_address(teredo_addr).teredo)
1585 bad_addr = '2000::4136:e378:8000:63bf:3fff:fdd2'
1586 self.assertFalse(ipaddress.ip_address(bad_addr).teredo)
1587 bad_addr = '2001:0001:4136:e378:8000:63bf:3fff:fdd2'
1588 self.assertFalse(ipaddress.ip_address(bad_addr).teredo)
1589
1590 # i77
1591 teredo_addr = ipaddress.IPv6Address('2001:0:5ef5:79fd:0:59d:a0e5:ba1')
1592 self.assertEqual((ipaddress.IPv4Address('94.245.121.253'),
1593 ipaddress.IPv4Address('95.26.244.94')),
1594 teredo_addr.teredo)
1595
Nick Coghlandc9b2552012-05-20 21:01:57 +10001596 def testsixtofour(self):
1597 sixtofouraddr = ipaddress.ip_address('2002:ac1d:2d64::1')
1598 bad_addr = ipaddress.ip_address('2000:ac1d:2d64::1')
1599 self.assertEqual(ipaddress.IPv4Address('172.29.45.100'),
1600 sixtofouraddr.sixtofour)
1601 self.assertFalse(bad_addr.sixtofour)
1602
Nick Coghlandc9b2552012-05-20 21:01:57 +10001603
1604if __name__ == '__main__':
1605 unittest.main()