blob: 99c54f161404bdf3d4476fdbe278b05e62ce48ea [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 Coghlane0c3f5e2012-08-05 18:20:17 +100010import operator
Nick Coghlandc9b2552012-05-20 21:01:57 +100011import ipaddress
12
Nick Coghlan07c4e332012-07-08 23:06:45 +100013class BaseTestCase(unittest.TestCase):
Nick Coghlan36f8dcd2012-07-07 19:23:53 +100014 # One big change in ipaddress over the original ipaddr module is
15 # error reporting that tries to assume users *don't know the rules*
16 # for what constitutes an RFC compliant IP address
17
Nick Coghlan07c4e332012-07-08 23:06:45 +100018 # Ensuring these errors are emitted correctly in all relevant cases
19 # meant moving to a more systematic test structure that allows the
20 # test structure to map more directly to the module structure
21
Nick Coghlan36f8dcd2012-07-07 19:23:53 +100022 # Note that if the constructors are refactored so that addresses with
23 # multiple problems get classified differently, that's OK - just
24 # move the affected examples to the newly appropriate test case.
25
Nick Coghlan07c4e332012-07-08 23:06:45 +100026 # There is some duplication between the original relatively ad hoc
27 # test suite and the new systematic tests. While some redundancy in
28 # testing is considered preferable to accidentally deleting a valid
29 # test, the original test suite will likely be reduced over time as
30 # redundant tests are identified.
Nick Coghlan36f8dcd2012-07-07 19:23:53 +100031
Nick Coghlan297b1432012-07-08 17:11:04 +100032 @property
33 def factory(self):
34 raise NotImplementedError
35
Nick Coghlan36f8dcd2012-07-07 19:23:53 +100036 @contextlib.contextmanager
37 def assertCleanError(self, exc_type, details, *args):
38 """
39 Ensure exception does not display a context by default
40
41 Wraps unittest.TestCase.assertRaisesRegex
42 """
43 if args:
44 details = details % args
45 cm = self.assertRaisesRegex(exc_type, details)
46 with cm as exc:
47 yield exc
48 # Ensure we produce clean tracebacks on failure
49 if exc.exception.__context__ is not None:
50 self.assertTrue(exc.exception.__suppress_context__)
51
52 def assertAddressError(self, details, *args):
53 """Ensure a clean AddressValueError"""
54 return self.assertCleanError(ipaddress.AddressValueError,
55 details, *args)
56
57 def assertNetmaskError(self, details, *args):
58 """Ensure a clean NetmaskValueError"""
59 return self.assertCleanError(ipaddress.NetmaskValueError,
60 details, *args)
61
Nick Coghlan07c4e332012-07-08 23:06:45 +100062 def assertInstancesEqual(self, lhs, rhs):
63 """Check constructor arguments produce equivalent instances"""
64 self.assertEqual(self.factory(lhs), self.factory(rhs))
65
66class CommonTestMixin:
Nick Coghlan36f8dcd2012-07-07 19:23:53 +100067
68 def test_empty_address(self):
69 with self.assertAddressError("Address cannot be empty"):
Nick Coghlan297b1432012-07-08 17:11:04 +100070 self.factory("")
71
72 def test_floats_rejected(self):
73 with self.assertAddressError(re.escape(repr("1.0"))):
74 self.factory(1.0)
75
Nick Coghlane0c3f5e2012-08-05 18:20:17 +100076 def test_not_an_index_issue15559(self):
77 # Implementing __index__ makes for a very nasty interaction with the
78 # bytes constructor. Thus, we disallow implicit use as an integer
79 self.assertRaises(TypeError, operator.index, self.factory(1))
80 self.assertRaises(TypeError, hex, self.factory(1))
81 self.assertRaises(TypeError, bytes, self.factory(1))
82
83
Nick Coghlan07c4e332012-07-08 23:06:45 +100084class CommonTestMixin_v4(CommonTestMixin):
85
86 def test_leading_zeros(self):
87 self.assertInstancesEqual("000.000.000.000", "0.0.0.0")
88 self.assertInstancesEqual("192.168.000.001", "192.168.0.1")
89
90 def test_int(self):
91 self.assertInstancesEqual(0, "0.0.0.0")
92 self.assertInstancesEqual(3232235521, "192.168.0.1")
93
94 def test_packed(self):
95 self.assertInstancesEqual(bytes.fromhex("00000000"), "0.0.0.0")
96 self.assertInstancesEqual(bytes.fromhex("c0a80001"), "192.168.0.1")
Nick Coghlan297b1432012-07-08 17:11:04 +100097
98 def test_negative_ints_rejected(self):
99 msg = "-1 (< 0) is not permitted as an IPv4 address"
100 with self.assertAddressError(re.escape(msg)):
101 self.factory(-1)
102
103 def test_large_ints_rejected(self):
104 msg = "%d (>= 2**32) is not permitted as an IPv4 address"
105 with self.assertAddressError(re.escape(msg % 2**32)):
106 self.factory(2**32)
107
108 def test_bad_packed_length(self):
109 def assertBadLength(length):
Nick Coghlan07c4e332012-07-08 23:06:45 +1000110 addr = bytes(length)
Nick Coghlan297b1432012-07-08 17:11:04 +1000111 msg = "%r (len %d != 4) is not permitted as an IPv4 address"
112 with self.assertAddressError(re.escape(msg % (addr, length))):
113 self.factory(addr)
114
115 assertBadLength(3)
116 assertBadLength(5)
117
Nick Coghlan07c4e332012-07-08 23:06:45 +1000118class CommonTestMixin_v6(CommonTestMixin):
119
120 def test_leading_zeros(self):
121 self.assertInstancesEqual("0000::0000", "::")
122 self.assertInstancesEqual("000::c0a8:0001", "::c0a8:1")
123
124 def test_int(self):
125 self.assertInstancesEqual(0, "::")
126 self.assertInstancesEqual(3232235521, "::c0a8:1")
127
128 def test_packed(self):
129 addr = bytes(12) + bytes.fromhex("00000000")
130 self.assertInstancesEqual(addr, "::")
131 addr = bytes(12) + bytes.fromhex("c0a80001")
132 self.assertInstancesEqual(addr, "::c0a8:1")
133 addr = bytes.fromhex("c0a80001") + bytes(12)
134 self.assertInstancesEqual(addr, "c0a8:1::")
Nick Coghlan297b1432012-07-08 17:11:04 +1000135
136 def test_negative_ints_rejected(self):
137 msg = "-1 (< 0) is not permitted as an IPv6 address"
138 with self.assertAddressError(re.escape(msg)):
139 self.factory(-1)
140
141 def test_large_ints_rejected(self):
142 msg = "%d (>= 2**128) is not permitted as an IPv6 address"
143 with self.assertAddressError(re.escape(msg % 2**128)):
144 self.factory(2**128)
145
146 def test_bad_packed_length(self):
147 def assertBadLength(length):
Nick Coghlan07c4e332012-07-08 23:06:45 +1000148 addr = bytes(length)
Nick Coghlan297b1432012-07-08 17:11:04 +1000149 msg = "%r (len %d != 16) is not permitted as an IPv6 address"
150 with self.assertAddressError(re.escape(msg % (addr, length))):
151 self.factory(addr)
152 self.factory(addr)
153
154 assertBadLength(15)
155 assertBadLength(17)
156
157
Nick Coghlan07c4e332012-07-08 23:06:45 +1000158class AddressTestCase_v4(BaseTestCase, CommonTestMixin_v4):
Nick Coghlan297b1432012-07-08 17:11:04 +1000159 factory = ipaddress.IPv4Address
Nick Coghlan36f8dcd2012-07-07 19:23:53 +1000160
161 def test_network_passed_as_address(self):
162 addr = "127.0.0.1/24"
163 with self.assertAddressError("Unexpected '/' in %r", addr):
164 ipaddress.IPv4Address(addr)
165
166 def test_bad_address_split(self):
167 def assertBadSplit(addr):
168 with self.assertAddressError("Expected 4 octets in %r", addr):
169 ipaddress.IPv4Address(addr)
170
171 assertBadSplit("127.0.1")
172 assertBadSplit("42.42.42.42.42")
173 assertBadSplit("42.42.42")
174 assertBadSplit("42.42")
175 assertBadSplit("42")
176 assertBadSplit("42..42.42.42")
177 assertBadSplit("42.42.42.42.")
178 assertBadSplit("42.42.42.42...")
179 assertBadSplit(".42.42.42.42")
180 assertBadSplit("...42.42.42.42")
181 assertBadSplit("016.016.016")
182 assertBadSplit("016.016")
183 assertBadSplit("016")
184 assertBadSplit("000")
185 assertBadSplit("0x0a.0x0a.0x0a")
186 assertBadSplit("0x0a.0x0a")
187 assertBadSplit("0x0a")
188 assertBadSplit(".")
189 assertBadSplit("bogus")
190 assertBadSplit("bogus.com")
191 assertBadSplit("1000")
192 assertBadSplit("1000000000000000")
193 assertBadSplit("192.168.0.1.com")
194
195 def test_empty_octet(self):
196 def assertBadOctet(addr):
197 with self.assertAddressError("Empty octet not permitted in %r",
198 addr):
199 ipaddress.IPv4Address(addr)
200
201 assertBadOctet("42..42.42")
202 assertBadOctet("...")
203
204 def test_invalid_characters(self):
205 def assertBadOctet(addr, octet):
206 msg = "Only decimal digits permitted in %r in %r" % (octet, addr)
207 with self.assertAddressError(re.escape(msg)):
208 ipaddress.IPv4Address(addr)
209
210 assertBadOctet("0x0a.0x0a.0x0a.0x0a", "0x0a")
Nick Coghlan07c4e332012-07-08 23:06:45 +1000211 assertBadOctet("0xa.0x0a.0x0a.0x0a", "0xa")
Nick Coghlan36f8dcd2012-07-07 19:23:53 +1000212 assertBadOctet("42.42.42.-0", "-0")
213 assertBadOctet("42.42.42.+0", "+0")
214 assertBadOctet("42.42.42.-42", "-42")
215 assertBadOctet("+1.+2.+3.4", "+1")
216 assertBadOctet("1.2.3.4e0", "4e0")
217 assertBadOctet("1.2.3.4::", "4::")
218 assertBadOctet("1.a.2.3", "a")
219
Nick Coghlan07c4e332012-07-08 23:06:45 +1000220 def test_octal_decimal_ambiguity(self):
Nick Coghlan36f8dcd2012-07-07 19:23:53 +1000221 def assertBadOctet(addr, octet):
Nick Coghlan07c4e332012-07-08 23:06:45 +1000222 msg = "Ambiguous (octal/decimal) value in %r not permitted in %r"
223 with self.assertAddressError(re.escape(msg % (octet, addr))):
Nick Coghlan36f8dcd2012-07-07 19:23:53 +1000224 ipaddress.IPv4Address(addr)
225
226 assertBadOctet("016.016.016.016", "016")
227 assertBadOctet("001.000.008.016", "008")
Nick Coghlan07c4e332012-07-08 23:06:45 +1000228
229 def test_octet_length(self):
230 def assertBadOctet(addr, octet):
231 msg = "At most 3 characters permitted in %r in %r"
232 with self.assertAddressError(re.escape(msg % (octet, addr))):
233 ipaddress.IPv4Address(addr)
234
235 assertBadOctet("0000.000.000.000", "0000")
236 assertBadOctet("12345.67899.-54321.-98765", "12345")
Nick Coghlan36f8dcd2012-07-07 19:23:53 +1000237
238 def test_octet_limit(self):
239 def assertBadOctet(addr, octet):
Nick Coghlanb582ecc2012-07-07 22:15:22 +1000240 msg = "Octet %d (> 255) not permitted in %r" % (octet, addr)
241 with self.assertAddressError(re.escape(msg)):
Nick Coghlan36f8dcd2012-07-07 19:23:53 +1000242 ipaddress.IPv4Address(addr)
243
Nick Coghlan36f8dcd2012-07-07 19:23:53 +1000244 assertBadOctet("257.0.0.0", 257)
Nick Coghlan07c4e332012-07-08 23:06:45 +1000245 assertBadOctet("192.168.0.999", 999)
Nick Coghlan36f8dcd2012-07-07 19:23:53 +1000246
Nick Coghlan36f8dcd2012-07-07 19:23:53 +1000247
Nick Coghlan07c4e332012-07-08 23:06:45 +1000248class AddressTestCase_v6(BaseTestCase, CommonTestMixin_v6):
Nick Coghlan297b1432012-07-08 17:11:04 +1000249 factory = ipaddress.IPv6Address
Nick Coghlan36f8dcd2012-07-07 19:23:53 +1000250
251 def test_network_passed_as_address(self):
252 addr = "::1/24"
253 with self.assertAddressError("Unexpected '/' in %r", addr):
254 ipaddress.IPv6Address(addr)
255
256 def test_bad_address_split_v6_not_enough_parts(self):
257 def assertBadSplit(addr):
258 msg = "At least 3 parts expected in %r"
259 with self.assertAddressError(msg, addr):
260 ipaddress.IPv6Address(addr)
261
262 assertBadSplit(":")
263 assertBadSplit(":1")
264 assertBadSplit("FEDC:9878")
265
266 def test_bad_address_split_v6_too_many_colons(self):
267 def assertBadSplit(addr):
268 msg = "At most 8 colons permitted in %r"
269 with self.assertAddressError(msg, addr):
270 ipaddress.IPv6Address(addr)
271
272 assertBadSplit("9:8:7:6:5:4:3::2:1")
273 assertBadSplit("10:9:8:7:6:5:4:3:2:1")
274 assertBadSplit("::8:7:6:5:4:3:2:1")
275 assertBadSplit("8:7:6:5:4:3:2:1::")
276 # A trailing IPv4 address is two parts
277 assertBadSplit("10:9:8:7:6:5:4:3:42.42.42.42")
278
279 def test_bad_address_split_v6_too_many_parts(self):
280 def assertBadSplit(addr):
281 msg = "Exactly 8 parts expected without '::' in %r"
282 with self.assertAddressError(msg, addr):
283 ipaddress.IPv6Address(addr)
284
285 assertBadSplit("3ffe:0:0:0:0:0:0:0:1")
286 assertBadSplit("9:8:7:6:5:4:3:2:1")
287 assertBadSplit("7:6:5:4:3:2:1")
288 # A trailing IPv4 address is two parts
289 assertBadSplit("9:8:7:6:5:4:3:42.42.42.42")
290 assertBadSplit("7:6:5:4:3:42.42.42.42")
291
292 def test_bad_address_split_v6_too_many_parts_with_double_colon(self):
293 def assertBadSplit(addr):
294 msg = "Expected at most 7 other parts with '::' in %r"
295 with self.assertAddressError(msg, addr):
296 ipaddress.IPv6Address(addr)
297
298 assertBadSplit("1:2:3:4::5:6:7:8")
299
300 def test_bad_address_split_v6_repeated_double_colon(self):
301 def assertBadSplit(addr):
302 msg = "At most one '::' permitted in %r"
303 with self.assertAddressError(msg, addr):
304 ipaddress.IPv6Address(addr)
305
306 assertBadSplit("3ffe::1::1")
307 assertBadSplit("1::2::3::4:5")
308 assertBadSplit("2001::db:::1")
309 assertBadSplit("3ffe::1::")
310 assertBadSplit("::3ffe::1")
311 assertBadSplit(":3ffe::1::1")
312 assertBadSplit("3ffe::1::1:")
313 assertBadSplit(":3ffe::1::1:")
314 assertBadSplit(":::")
315 assertBadSplit('2001:db8:::1')
316
317 def test_bad_address_split_v6_leading_colon(self):
318 def assertBadSplit(addr):
319 msg = "Leading ':' only permitted as part of '::' in %r"
320 with self.assertAddressError(msg, addr):
321 ipaddress.IPv6Address(addr)
322
323 assertBadSplit(":2001:db8::1")
324 assertBadSplit(":1:2:3:4:5:6:7")
325 assertBadSplit(":1:2:3:4:5:6:")
326 assertBadSplit(":6:5:4:3:2:1::")
327
328 def test_bad_address_split_v6_trailing_colon(self):
329 def assertBadSplit(addr):
330 msg = "Trailing ':' only permitted as part of '::' in %r"
331 with self.assertAddressError(msg, addr):
332 ipaddress.IPv6Address(addr)
333
334 assertBadSplit("2001:db8::1:")
335 assertBadSplit("1:2:3:4:5:6:7:")
336 assertBadSplit("::1.2.3.4:")
337 assertBadSplit("::7:6:5:4:3:2:")
338
339 def test_bad_v4_part_in(self):
340 def assertBadAddressPart(addr, v4_error):
341 with self.assertAddressError("%s in %r", v4_error, addr):
342 ipaddress.IPv6Address(addr)
343
344 assertBadAddressPart("3ffe::1.net", "Expected 4 octets in '1.net'")
345 assertBadAddressPart("3ffe::127.0.1",
346 "Expected 4 octets in '127.0.1'")
347 assertBadAddressPart("::1.2.3",
348 "Expected 4 octets in '1.2.3'")
349 assertBadAddressPart("::1.2.3.4.5",
350 "Expected 4 octets in '1.2.3.4.5'")
351 assertBadAddressPart("3ffe::1.1.1.net",
352 "Only decimal digits permitted in 'net' "
353 "in '1.1.1.net'")
354
355 def test_invalid_characters(self):
356 def assertBadPart(addr, part):
357 msg = "Only hex digits permitted in %r in %r" % (part, addr)
358 with self.assertAddressError(re.escape(msg)):
359 ipaddress.IPv6Address(addr)
360
361 assertBadPart("3ffe::goog", "goog")
362 assertBadPart("3ffe::-0", "-0")
363 assertBadPart("3ffe::+0", "+0")
364 assertBadPart("3ffe::-1", "-1")
365 assertBadPart("1.2.3.4::", "1.2.3.4")
366 assertBadPart('1234:axy::b', "axy")
367
368 def test_part_length(self):
369 def assertBadPart(addr, part):
370 msg = "At most 4 characters permitted in %r in %r"
371 with self.assertAddressError(msg, part, addr):
372 ipaddress.IPv6Address(addr)
373
Nick Coghlan07c4e332012-07-08 23:06:45 +1000374 assertBadPart("::00000", "00000")
Nick Coghlan36f8dcd2012-07-07 19:23:53 +1000375 assertBadPart("3ffe::10000", "10000")
376 assertBadPart("02001:db8::", "02001")
377 assertBadPart('2001:888888::1', "888888")
378
Nick Coghlan36f8dcd2012-07-07 19:23:53 +1000379
Nick Coghlan07c4e332012-07-08 23:06:45 +1000380class NetmaskTestMixin_v4(CommonTestMixin_v4):
Nick Coghlan36f8dcd2012-07-07 19:23:53 +1000381 """Input validation on interfaces and networks is very similar"""
382
Nick Coghlan36f8dcd2012-07-07 19:23:53 +1000383 def test_split_netmask(self):
384 addr = "1.2.3.4/32/24"
385 with self.assertAddressError("Only one '/' permitted in %r" % addr):
386 self.factory(addr)
387
388 def test_address_errors(self):
389 def assertBadAddress(addr, details):
390 with self.assertAddressError(details):
391 self.factory(addr)
392
Nick Coghlan297b1432012-07-08 17:11:04 +1000393 assertBadAddress("/", "Address cannot be empty")
394 assertBadAddress("/8", "Address cannot be empty")
Nick Coghlan36f8dcd2012-07-07 19:23:53 +1000395 assertBadAddress("bogus", "Expected 4 octets")
396 assertBadAddress("google.com", "Expected 4 octets")
397 assertBadAddress("10/8", "Expected 4 octets")
398 assertBadAddress("::1.2.3.4", "Only decimal digits")
Nick Coghlanb582ecc2012-07-07 22:15:22 +1000399 assertBadAddress("1.2.3.256", re.escape("256 (> 255)"))
Nick Coghlan36f8dcd2012-07-07 19:23:53 +1000400
401 def test_netmask_errors(self):
402 def assertBadNetmask(addr, netmask):
403 msg = "%r is not a valid netmask"
404 with self.assertNetmaskError(msg % netmask):
405 self.factory("%s/%s" % (addr, netmask))
406
407 assertBadNetmask("1.2.3.4", "")
408 assertBadNetmask("1.2.3.4", "33")
409 assertBadNetmask("1.2.3.4", "254.254.255.256")
Nick Coghlan07c4e332012-07-08 23:06:45 +1000410 assertBadNetmask("1.1.1.1", "254.xyz.2.3")
Nick Coghlan36f8dcd2012-07-07 19:23:53 +1000411 assertBadNetmask("1.1.1.1", "240.255.0.0")
Nick Coghlan36f8dcd2012-07-07 19:23:53 +1000412 assertBadNetmask("1.1.1.1", "pudding")
413
Nick Coghlan07c4e332012-07-08 23:06:45 +1000414class InterfaceTestCase_v4(BaseTestCase, NetmaskTestMixin_v4):
Nick Coghlan36f8dcd2012-07-07 19:23:53 +1000415 factory = ipaddress.IPv4Interface
416
Nick Coghlan07c4e332012-07-08 23:06:45 +1000417class NetworkTestCase_v4(BaseTestCase, NetmaskTestMixin_v4):
Nick Coghlan36f8dcd2012-07-07 19:23:53 +1000418 factory = ipaddress.IPv4Network
419
420
Nick Coghlan07c4e332012-07-08 23:06:45 +1000421class NetmaskTestMixin_v6(CommonTestMixin_v6):
Nick Coghlan36f8dcd2012-07-07 19:23:53 +1000422 """Input validation on interfaces and networks is very similar"""
423
Nick Coghlan36f8dcd2012-07-07 19:23:53 +1000424 def test_split_netmask(self):
425 addr = "cafe:cafe::/128/190"
426 with self.assertAddressError("Only one '/' permitted in %r" % addr):
427 self.factory(addr)
428
429 def test_address_errors(self):
430 def assertBadAddress(addr, details):
431 with self.assertAddressError(details):
432 self.factory(addr)
433
Nick Coghlan297b1432012-07-08 17:11:04 +1000434 assertBadAddress("/", "Address cannot be empty")
435 assertBadAddress("/8", "Address cannot be empty")
Nick Coghlan36f8dcd2012-07-07 19:23:53 +1000436 assertBadAddress("google.com", "At least 3 parts")
437 assertBadAddress("1.2.3.4", "At least 3 parts")
438 assertBadAddress("10/8", "At least 3 parts")
439 assertBadAddress("1234:axy::b", "Only hex digits")
440
441 def test_netmask_errors(self):
442 def assertBadNetmask(addr, netmask):
443 msg = "%r is not a valid netmask"
444 with self.assertNetmaskError(msg % netmask):
445 self.factory("%s/%s" % (addr, netmask))
446
447 assertBadNetmask("::1", "")
448 assertBadNetmask("::1", "::1")
449 assertBadNetmask("::1", "1::")
450 assertBadNetmask("::1", "129")
451 assertBadNetmask("::1", "pudding")
452
Nick Coghlan07c4e332012-07-08 23:06:45 +1000453class InterfaceTestCase_v6(BaseTestCase, NetmaskTestMixin_v6):
Nick Coghlan36f8dcd2012-07-07 19:23:53 +1000454 factory = ipaddress.IPv6Interface
455
Nick Coghlan07c4e332012-07-08 23:06:45 +1000456class NetworkTestCase_v6(BaseTestCase, NetmaskTestMixin_v6):
Nick Coghlan36f8dcd2012-07-07 19:23:53 +1000457 factory = ipaddress.IPv6Network
458
459
Nick Coghlan07c4e332012-07-08 23:06:45 +1000460class FactoryFunctionErrors(BaseTestCase):
Nick Coghlan36f8dcd2012-07-07 19:23:53 +1000461
462 def assertFactoryError(self, factory, kind):
463 """Ensure a clean ValueError with the expected message"""
464 addr = "camelot"
465 msg = '%r does not appear to be an IPv4 or IPv6 %s'
466 with self.assertCleanError(ValueError, msg, addr, kind):
467 factory(addr)
468
469 def test_ip_address(self):
470 self.assertFactoryError(ipaddress.ip_address, "address")
471
472 def test_ip_interface(self):
473 self.assertFactoryError(ipaddress.ip_interface, "interface")
474
475 def test_ip_network(self):
476 self.assertFactoryError(ipaddress.ip_network, "network")
477
Hynek Schlawack91c5a342012-06-05 11:55:58 +0200478
Nick Coghlan3008ec02012-07-08 00:45:33 +1000479class ComparisonTests(unittest.TestCase):
480
481 v4addr = ipaddress.IPv4Address(1)
482 v4net = ipaddress.IPv4Network(1)
483 v4intf = ipaddress.IPv4Interface(1)
484 v6addr = ipaddress.IPv6Address(1)
485 v6net = ipaddress.IPv6Network(1)
486 v6intf = ipaddress.IPv6Interface(1)
487
488 v4_addresses = [v4addr, v4intf]
489 v4_objects = v4_addresses + [v4net]
490 v6_addresses = [v6addr, v6intf]
491 v6_objects = v6_addresses + [v6net]
492 objects = v4_objects + v6_objects
493
494 def test_foreign_type_equality(self):
495 # __eq__ should never raise TypeError directly
496 other = object()
497 for obj in self.objects:
498 self.assertNotEqual(obj, other)
499 self.assertFalse(obj == other)
500 self.assertEqual(obj.__eq__(other), NotImplemented)
501 self.assertEqual(obj.__ne__(other), NotImplemented)
502
503 def test_mixed_type_equality(self):
504 # Ensure none of the internal objects accidentally
505 # expose the right set of attributes to become "equal"
506 for lhs in self.objects:
507 for rhs in self.objects:
508 if lhs is rhs:
509 continue
510 self.assertNotEqual(lhs, rhs)
511
512 def test_containment(self):
513 for obj in self.v4_addresses:
514 self.assertIn(obj, self.v4net)
515 for obj in self.v6_addresses:
516 self.assertIn(obj, self.v6net)
517 for obj in self.v4_objects + [self.v6net]:
518 self.assertNotIn(obj, self.v6net)
519 for obj in self.v6_objects + [self.v4net]:
520 self.assertNotIn(obj, self.v4net)
521
522 def test_mixed_type_ordering(self):
523 for lhs in self.objects:
524 for rhs in self.objects:
525 if isinstance(lhs, type(rhs)) or isinstance(rhs, type(lhs)):
526 continue
527 self.assertRaises(TypeError, lambda: lhs < rhs)
528 self.assertRaises(TypeError, lambda: lhs > rhs)
529 self.assertRaises(TypeError, lambda: lhs <= rhs)
530 self.assertRaises(TypeError, lambda: lhs >= rhs)
531
532 def test_mixed_type_key(self):
533 # with get_mixed_type_key, you can sort addresses and network.
534 v4_ordered = [self.v4addr, self.v4net, self.v4intf]
535 v6_ordered = [self.v6addr, self.v6net, self.v6intf]
536 self.assertEqual(v4_ordered,
537 sorted(self.v4_objects,
538 key=ipaddress.get_mixed_type_key))
539 self.assertEqual(v6_ordered,
540 sorted(self.v6_objects,
541 key=ipaddress.get_mixed_type_key))
542 self.assertEqual(v4_ordered + v6_ordered,
543 sorted(self.objects,
544 key=ipaddress.get_mixed_type_key))
545 self.assertEqual(NotImplemented, ipaddress.get_mixed_type_key(object))
546
547 def test_incompatible_versions(self):
548 # These should always raise TypeError
549 v4addr = ipaddress.ip_address('1.1.1.1')
550 v4net = ipaddress.ip_network('1.1.1.1')
551 v6addr = ipaddress.ip_address('::1')
552 v6net = ipaddress.ip_address('::1')
553
554 self.assertRaises(TypeError, v4addr.__lt__, v6addr)
555 self.assertRaises(TypeError, v4addr.__gt__, v6addr)
556 self.assertRaises(TypeError, v4net.__lt__, v6net)
557 self.assertRaises(TypeError, v4net.__gt__, v6net)
558
559 self.assertRaises(TypeError, v6addr.__lt__, v4addr)
560 self.assertRaises(TypeError, v6addr.__gt__, v4addr)
561 self.assertRaises(TypeError, v6net.__lt__, v4net)
562 self.assertRaises(TypeError, v6net.__gt__, v4net)
563
564
565
Nick Coghlandc9b2552012-05-20 21:01:57 +1000566class IpaddrUnitTest(unittest.TestCase):
567
568 def setUp(self):
569 self.ipv4_address = ipaddress.IPv4Address('1.2.3.4')
570 self.ipv4_interface = ipaddress.IPv4Interface('1.2.3.4/24')
571 self.ipv4_network = ipaddress.IPv4Network('1.2.3.0/24')
572 #self.ipv4_hostmask = ipaddress.IPv4Interface('10.0.0.1/0.255.255.255')
573 self.ipv6_address = ipaddress.IPv6Interface(
574 '2001:658:22a:cafe:200:0:0:1')
575 self.ipv6_interface = ipaddress.IPv6Interface(
576 '2001:658:22a:cafe:200:0:0:1/64')
577 self.ipv6_network = ipaddress.IPv6Network('2001:658:22a:cafe::/64')
578
579 def testRepr(self):
580 self.assertEqual("IPv4Interface('1.2.3.4/32')",
581 repr(ipaddress.IPv4Interface('1.2.3.4')))
582 self.assertEqual("IPv6Interface('::1/128')",
583 repr(ipaddress.IPv6Interface('::1')))
584
585 # issue57
586 def testAddressIntMath(self):
587 self.assertEqual(ipaddress.IPv4Address('1.1.1.1') + 255,
588 ipaddress.IPv4Address('1.1.2.0'))
589 self.assertEqual(ipaddress.IPv4Address('1.1.1.1') - 256,
590 ipaddress.IPv4Address('1.1.0.1'))
591 self.assertEqual(ipaddress.IPv6Address('::1') + (2**16 - 2),
592 ipaddress.IPv6Address('::ffff'))
593 self.assertEqual(ipaddress.IPv6Address('::ffff') - (2**16 - 2),
594 ipaddress.IPv6Address('::1'))
595
Nick Coghlan3c2570c2012-07-07 01:13:55 +1000596 def testInvalidIntToBytes(self):
597 self.assertRaises(ValueError, ipaddress.v4_int_to_packed, -1)
598 self.assertRaises(ValueError, ipaddress.v4_int_to_packed,
599 2 ** ipaddress.IPV4LENGTH)
600 self.assertRaises(ValueError, ipaddress.v6_int_to_packed, -1)
601 self.assertRaises(ValueError, ipaddress.v6_int_to_packed,
602 2 ** ipaddress.IPV6LENGTH)
603
Hynek Schlawack91c5a342012-06-05 11:55:58 +0200604 def testInternals(self):
605 first, last = ipaddress._find_address_range([
606 ipaddress.IPv4Address('10.10.10.10'),
607 ipaddress.IPv4Address('10.10.10.12')])
608 self.assertEqual(first, last)
Hynek Schlawack91c5a342012-06-05 11:55:58 +0200609 self.assertEqual(128, ipaddress._count_righthand_zero_bits(0, 128))
Hynek Schlawack91c5a342012-06-05 11:55:58 +0200610 self.assertEqual("IPv4Network('1.2.3.0/24')", repr(self.ipv4_network))
Nick Coghlandc9b2552012-05-20 21:01:57 +1000611
Nick Coghland9722652012-06-17 16:33:00 +1000612 def testMissingAddressVersion(self):
613 class Broken(ipaddress._BaseAddress):
614 pass
615 broken = Broken('127.0.0.1')
616 with self.assertRaisesRegex(NotImplementedError, "Broken.*version"):
617 broken.version
618
619 def testMissingNetworkVersion(self):
620 class Broken(ipaddress._BaseNetwork):
621 pass
622 broken = Broken('127.0.0.1')
623 with self.assertRaisesRegex(NotImplementedError, "Broken.*version"):
624 broken.version
625
626 def testMissingAddressClass(self):
627 class Broken(ipaddress._BaseNetwork):
628 pass
629 broken = Broken('127.0.0.1')
630 with self.assertRaisesRegex(NotImplementedError, "Broken.*address"):
631 broken._address_class
632
Nick Coghlandc9b2552012-05-20 21:01:57 +1000633 def testGetNetwork(self):
634 self.assertEqual(int(self.ipv4_network.network_address), 16909056)
635 self.assertEqual(str(self.ipv4_network.network_address), '1.2.3.0')
636
637 self.assertEqual(int(self.ipv6_network.network_address),
638 42540616829182469433403647294022090752)
639 self.assertEqual(str(self.ipv6_network.network_address),
640 '2001:658:22a:cafe::')
641 self.assertEqual(str(self.ipv6_network.hostmask),
642 '::ffff:ffff:ffff:ffff')
643
Nick Coghlandc9b2552012-05-20 21:01:57 +1000644 def testIpFromInt(self):
645 self.assertEqual(self.ipv4_interface._ip,
646 ipaddress.IPv4Interface(16909060)._ip)
Nick Coghlandc9b2552012-05-20 21:01:57 +1000647
648 ipv4 = ipaddress.ip_network('1.2.3.4')
649 ipv6 = ipaddress.ip_network('2001:658:22a:cafe:200:0:0:1')
Nick Coghlan730f67f2012-08-05 22:02:18 +1000650 self.assertEqual(ipv4, ipaddress.ip_network(int(ipv4.network_address)))
651 self.assertEqual(ipv6, ipaddress.ip_network(int(ipv6.network_address)))
Nick Coghlandc9b2552012-05-20 21:01:57 +1000652
653 v6_int = 42540616829182469433547762482097946625
654 self.assertEqual(self.ipv6_interface._ip,
655 ipaddress.IPv6Interface(v6_int)._ip)
Nick Coghlandc9b2552012-05-20 21:01:57 +1000656
Hynek Schlawack91c5a342012-06-05 11:55:58 +0200657 self.assertEqual(ipaddress.ip_network(self.ipv4_address._ip).version,
658 4)
659 self.assertEqual(ipaddress.ip_network(self.ipv6_address._ip).version,
660 6)
Nick Coghlandc9b2552012-05-20 21:01:57 +1000661
662 def testIpFromPacked(self):
Nick Coghlan5cf896f2012-07-07 01:43:31 +1000663 address = ipaddress.ip_address
Nick Coghlandc9b2552012-05-20 21:01:57 +1000664 self.assertEqual(self.ipv4_interface._ip,
Nick Coghlan5cf896f2012-07-07 01:43:31 +1000665 ipaddress.ip_interface(b'\x01\x02\x03\x04')._ip)
666 self.assertEqual(address('255.254.253.252'),
667 address(b'\xff\xfe\xfd\xfc'))
Nick Coghlandc9b2552012-05-20 21:01:57 +1000668 self.assertEqual(self.ipv6_interface.ip,
669 ipaddress.ip_interface(
Nick Coghlan5cf896f2012-07-07 01:43:31 +1000670 b'\x20\x01\x06\x58\x02\x2a\xca\xfe'
671 b'\x02\x00\x00\x00\x00\x00\x00\x01').ip)
672 self.assertEqual(address('ffff:2:3:4:ffff::'),
673 address(b'\xff\xff\x00\x02\x00\x03\x00\x04' +
674 b'\xff\xff' + b'\x00' * 6))
675 self.assertEqual(address('::'),
676 address(b'\x00' * 16))
677
Nick Coghlandc9b2552012-05-20 21:01:57 +1000678 def testGetIp(self):
679 self.assertEqual(int(self.ipv4_interface.ip), 16909060)
680 self.assertEqual(str(self.ipv4_interface.ip), '1.2.3.4')
681
682 self.assertEqual(int(self.ipv6_interface.ip),
683 42540616829182469433547762482097946625)
684 self.assertEqual(str(self.ipv6_interface.ip),
685 '2001:658:22a:cafe:200::1')
686
687 def testGetNetmask(self):
688 self.assertEqual(int(self.ipv4_network.netmask), 4294967040)
689 self.assertEqual(str(self.ipv4_network.netmask), '255.255.255.0')
690 self.assertEqual(int(self.ipv6_network.netmask),
691 340282366920938463444927863358058659840)
692 self.assertEqual(self.ipv6_network.prefixlen, 64)
693
694 def testZeroNetmask(self):
695 ipv4_zero_netmask = ipaddress.IPv4Interface('1.2.3.4/0')
696 self.assertEqual(int(ipv4_zero_netmask.network.netmask), 0)
697 self.assertTrue(ipv4_zero_netmask.network._is_valid_netmask(
698 str(0)))
Hynek Schlawack91c5a342012-06-05 11:55:58 +0200699 self.assertTrue(ipv4_zero_netmask._is_valid_netmask('0'))
700 self.assertTrue(ipv4_zero_netmask._is_valid_netmask('0.0.0.0'))
701 self.assertFalse(ipv4_zero_netmask._is_valid_netmask('invalid'))
Nick Coghlandc9b2552012-05-20 21:01:57 +1000702
703 ipv6_zero_netmask = ipaddress.IPv6Interface('::1/0')
704 self.assertEqual(int(ipv6_zero_netmask.network.netmask), 0)
705 self.assertTrue(ipv6_zero_netmask.network._is_valid_netmask(
706 str(0)))
707
Hynek Schlawack91c5a342012-06-05 11:55:58 +0200708 def testIPv4NetAndHostmasks(self):
709 net = self.ipv4_network
710 self.assertFalse(net._is_valid_netmask('invalid'))
711 self.assertTrue(net._is_valid_netmask('128.128.128.128'))
712 self.assertFalse(net._is_valid_netmask('128.128.128.127'))
713 self.assertFalse(net._is_valid_netmask('128.128.128.255'))
714 self.assertTrue(net._is_valid_netmask('255.128.128.128'))
715
716 self.assertFalse(net._is_hostmask('invalid'))
717 self.assertTrue(net._is_hostmask('128.255.255.255'))
718 self.assertFalse(net._is_hostmask('255.255.255.255'))
719 self.assertFalse(net._is_hostmask('1.2.3.4'))
720
721 net = ipaddress.IPv4Network('127.0.0.0/0.0.0.255')
722 self.assertEqual(24, net.prefixlen)
723
Nick Coghlandc9b2552012-05-20 21:01:57 +1000724 def testGetBroadcast(self):
725 self.assertEqual(int(self.ipv4_network.broadcast_address), 16909311)
726 self.assertEqual(str(self.ipv4_network.broadcast_address), '1.2.3.255')
727
728 self.assertEqual(int(self.ipv6_network.broadcast_address),
729 42540616829182469451850391367731642367)
730 self.assertEqual(str(self.ipv6_network.broadcast_address),
731 '2001:658:22a:cafe:ffff:ffff:ffff:ffff')
732
733 def testGetPrefixlen(self):
Nick Coghlane3ded952012-08-05 22:45:22 +1000734 self.assertEqual(self.ipv4_interface.network.prefixlen, 24)
735 self.assertEqual(self.ipv6_interface.network.prefixlen, 64)
Nick Coghlandc9b2552012-05-20 21:01:57 +1000736
737 def testGetSupernet(self):
738 self.assertEqual(self.ipv4_network.supernet().prefixlen, 23)
739 self.assertEqual(str(self.ipv4_network.supernet().network_address),
740 '1.2.2.0')
741 self.assertEqual(
742 ipaddress.IPv4Interface('0.0.0.0/0').network.supernet(),
743 ipaddress.IPv4Network('0.0.0.0/0'))
744
745 self.assertEqual(self.ipv6_network.supernet().prefixlen, 63)
746 self.assertEqual(str(self.ipv6_network.supernet().network_address),
747 '2001:658:22a:cafe::')
748 self.assertEqual(ipaddress.IPv6Interface('::0/0').network.supernet(),
749 ipaddress.IPv6Network('::0/0'))
750
751 def testGetSupernet3(self):
752 self.assertEqual(self.ipv4_network.supernet(3).prefixlen, 21)
753 self.assertEqual(str(self.ipv4_network.supernet(3).network_address),
754 '1.2.0.0')
755
756 self.assertEqual(self.ipv6_network.supernet(3).prefixlen, 61)
757 self.assertEqual(str(self.ipv6_network.supernet(3).network_address),
758 '2001:658:22a:caf8::')
759
760 def testGetSupernet4(self):
761 self.assertRaises(ValueError, self.ipv4_network.supernet,
762 prefixlen_diff=2, new_prefix=1)
Hynek Schlawack91c5a342012-06-05 11:55:58 +0200763 self.assertRaises(ValueError, self.ipv4_network.supernet,
764 new_prefix=25)
Nick Coghlandc9b2552012-05-20 21:01:57 +1000765 self.assertEqual(self.ipv4_network.supernet(prefixlen_diff=2),
766 self.ipv4_network.supernet(new_prefix=22))
767
768 self.assertRaises(ValueError, self.ipv6_network.supernet,
769 prefixlen_diff=2, new_prefix=1)
Hynek Schlawack91c5a342012-06-05 11:55:58 +0200770 self.assertRaises(ValueError, self.ipv6_network.supernet,
771 new_prefix=65)
Nick Coghlandc9b2552012-05-20 21:01:57 +1000772 self.assertEqual(self.ipv6_network.supernet(prefixlen_diff=2),
773 self.ipv6_network.supernet(new_prefix=62))
774
775 def testHosts(self):
Hynek Schlawack91c5a342012-06-05 11:55:58 +0200776 hosts = list(self.ipv4_network.hosts())
777 self.assertEqual(254, len(hosts))
778 self.assertEqual(ipaddress.IPv4Address('1.2.3.1'), hosts[0])
779 self.assertEqual(ipaddress.IPv4Address('1.2.3.254'), hosts[-1])
780
781 # special case where only 1 bit is left for address
Nick Coghlandc9b2552012-05-20 21:01:57 +1000782 self.assertEqual([ipaddress.IPv4Address('2.0.0.0'),
783 ipaddress.IPv4Address('2.0.0.1')],
784 list(ipaddress.ip_network('2.0.0.0/31').hosts()))
785
786 def testFancySubnetting(self):
787 self.assertEqual(sorted(self.ipv4_network.subnets(prefixlen_diff=3)),
788 sorted(self.ipv4_network.subnets(new_prefix=27)))
789 self.assertRaises(ValueError, list,
790 self.ipv4_network.subnets(new_prefix=23))
791 self.assertRaises(ValueError, list,
792 self.ipv4_network.subnets(prefixlen_diff=3,
793 new_prefix=27))
794 self.assertEqual(sorted(self.ipv6_network.subnets(prefixlen_diff=4)),
795 sorted(self.ipv6_network.subnets(new_prefix=68)))
796 self.assertRaises(ValueError, list,
797 self.ipv6_network.subnets(new_prefix=63))
798 self.assertRaises(ValueError, list,
799 self.ipv6_network.subnets(prefixlen_diff=4,
800 new_prefix=68))
801
802 def testGetSubnets(self):
803 self.assertEqual(list(self.ipv4_network.subnets())[0].prefixlen, 25)
804 self.assertEqual(str(list(
805 self.ipv4_network.subnets())[0].network_address),
806 '1.2.3.0')
807 self.assertEqual(str(list(
808 self.ipv4_network.subnets())[1].network_address),
809 '1.2.3.128')
810
811 self.assertEqual(list(self.ipv6_network.subnets())[0].prefixlen, 65)
812
813 def testGetSubnetForSingle32(self):
814 ip = ipaddress.IPv4Network('1.2.3.4/32')
815 subnets1 = [str(x) for x in ip.subnets()]
816 subnets2 = [str(x) for x in ip.subnets(2)]
817 self.assertEqual(subnets1, ['1.2.3.4/32'])
818 self.assertEqual(subnets1, subnets2)
819
820 def testGetSubnetForSingle128(self):
821 ip = ipaddress.IPv6Network('::1/128')
822 subnets1 = [str(x) for x in ip.subnets()]
823 subnets2 = [str(x) for x in ip.subnets(2)]
824 self.assertEqual(subnets1, ['::1/128'])
825 self.assertEqual(subnets1, subnets2)
826
827 def testSubnet2(self):
828 ips = [str(x) for x in self.ipv4_network.subnets(2)]
829 self.assertEqual(
830 ips,
831 ['1.2.3.0/26', '1.2.3.64/26', '1.2.3.128/26', '1.2.3.192/26'])
832
833 ipsv6 = [str(x) for x in self.ipv6_network.subnets(2)]
834 self.assertEqual(
835 ipsv6,
836 ['2001:658:22a:cafe::/66',
837 '2001:658:22a:cafe:4000::/66',
838 '2001:658:22a:cafe:8000::/66',
839 '2001:658:22a:cafe:c000::/66'])
840
841 def testSubnetFailsForLargeCidrDiff(self):
842 self.assertRaises(ValueError, list,
843 self.ipv4_interface.network.subnets(9))
844 self.assertRaises(ValueError, list,
845 self.ipv4_network.subnets(9))
846 self.assertRaises(ValueError, list,
847 self.ipv6_interface.network.subnets(65))
848 self.assertRaises(ValueError, list,
849 self.ipv6_network.subnets(65))
850
851 def testSupernetFailsForLargeCidrDiff(self):
852 self.assertRaises(ValueError,
853 self.ipv4_interface.network.supernet, 25)
854 self.assertRaises(ValueError,
855 self.ipv6_interface.network.supernet, 65)
856
857 def testSubnetFailsForNegativeCidrDiff(self):
858 self.assertRaises(ValueError, list,
859 self.ipv4_interface.network.subnets(-1))
860 self.assertRaises(ValueError, list,
Nick Coghlan2c589102012-05-27 01:03:25 +1000861 self.ipv4_network.subnets(-1))
Nick Coghlandc9b2552012-05-20 21:01:57 +1000862 self.assertRaises(ValueError, list,
863 self.ipv6_interface.network.subnets(-1))
864 self.assertRaises(ValueError, list,
865 self.ipv6_network.subnets(-1))
866
867 def testGetNum_Addresses(self):
868 self.assertEqual(self.ipv4_network.num_addresses, 256)
Hynek Schlawack91c5a342012-06-05 11:55:58 +0200869 self.assertEqual(list(self.ipv4_network.subnets())[0].num_addresses,
870 128)
Nick Coghlandc9b2552012-05-20 21:01:57 +1000871 self.assertEqual(self.ipv4_network.supernet().num_addresses, 512)
872
873 self.assertEqual(self.ipv6_network.num_addresses, 18446744073709551616)
874 self.assertEqual(list(self.ipv6_network.subnets())[0].num_addresses,
875 9223372036854775808)
876 self.assertEqual(self.ipv6_network.supernet().num_addresses,
877 36893488147419103232)
878
879 def testContains(self):
880 self.assertTrue(ipaddress.IPv4Interface('1.2.3.128/25') in
881 self.ipv4_network)
882 self.assertFalse(ipaddress.IPv4Interface('1.2.4.1/24') in
883 self.ipv4_network)
884 # We can test addresses and string as well.
885 addr1 = ipaddress.IPv4Address('1.2.3.37')
886 self.assertTrue(addr1 in self.ipv4_network)
887 # issue 61, bad network comparison on like-ip'd network objects
888 # with identical broadcast addresses.
889 self.assertFalse(ipaddress.IPv4Network('1.1.0.0/16').__contains__(
890 ipaddress.IPv4Network('1.0.0.0/15')))
891
Nick Coghlandc9b2552012-05-20 21:01:57 +1000892 def testNth(self):
893 self.assertEqual(str(self.ipv4_network[5]), '1.2.3.5')
894 self.assertRaises(IndexError, self.ipv4_network.__getitem__, 256)
895
896 self.assertEqual(str(self.ipv6_network[5]),
897 '2001:658:22a:cafe::5')
898
899 def testGetitem(self):
900 # http://code.google.com/p/ipaddr-py/issues/detail?id=15
901 addr = ipaddress.IPv4Network('172.31.255.128/255.255.255.240')
902 self.assertEqual(28, addr.prefixlen)
903 addr_list = list(addr)
904 self.assertEqual('172.31.255.128', str(addr_list[0]))
905 self.assertEqual('172.31.255.128', str(addr[0]))
906 self.assertEqual('172.31.255.143', str(addr_list[-1]))
907 self.assertEqual('172.31.255.143', str(addr[-1]))
908 self.assertEqual(addr_list[-1], addr[-1])
909
910 def testEqual(self):
911 self.assertTrue(self.ipv4_interface ==
912 ipaddress.IPv4Interface('1.2.3.4/24'))
913 self.assertFalse(self.ipv4_interface ==
914 ipaddress.IPv4Interface('1.2.3.4/23'))
915 self.assertFalse(self.ipv4_interface ==
916 ipaddress.IPv6Interface('::1.2.3.4/24'))
917 self.assertFalse(self.ipv4_interface == '')
918 self.assertFalse(self.ipv4_interface == [])
919 self.assertFalse(self.ipv4_interface == 2)
920
921 self.assertTrue(self.ipv6_interface ==
922 ipaddress.IPv6Interface('2001:658:22a:cafe:200::1/64'))
923 self.assertFalse(self.ipv6_interface ==
924 ipaddress.IPv6Interface('2001:658:22a:cafe:200::1/63'))
925 self.assertFalse(self.ipv6_interface ==
926 ipaddress.IPv4Interface('1.2.3.4/23'))
927 self.assertFalse(self.ipv6_interface == '')
928 self.assertFalse(self.ipv6_interface == [])
929 self.assertFalse(self.ipv6_interface == 2)
930
931 def testNotEqual(self):
932 self.assertFalse(self.ipv4_interface !=
933 ipaddress.IPv4Interface('1.2.3.4/24'))
934 self.assertTrue(self.ipv4_interface !=
935 ipaddress.IPv4Interface('1.2.3.4/23'))
936 self.assertTrue(self.ipv4_interface !=
937 ipaddress.IPv6Interface('::1.2.3.4/24'))
938 self.assertTrue(self.ipv4_interface != '')
939 self.assertTrue(self.ipv4_interface != [])
940 self.assertTrue(self.ipv4_interface != 2)
941
942 self.assertTrue(self.ipv4_address !=
943 ipaddress.IPv4Address('1.2.3.5'))
944 self.assertTrue(self.ipv4_address != '')
945 self.assertTrue(self.ipv4_address != [])
946 self.assertTrue(self.ipv4_address != 2)
947
948 self.assertFalse(self.ipv6_interface !=
949 ipaddress.IPv6Interface('2001:658:22a:cafe:200::1/64'))
950 self.assertTrue(self.ipv6_interface !=
951 ipaddress.IPv6Interface('2001:658:22a:cafe:200::1/63'))
952 self.assertTrue(self.ipv6_interface !=
953 ipaddress.IPv4Interface('1.2.3.4/23'))
954 self.assertTrue(self.ipv6_interface != '')
955 self.assertTrue(self.ipv6_interface != [])
956 self.assertTrue(self.ipv6_interface != 2)
957
958 self.assertTrue(self.ipv6_address !=
959 ipaddress.IPv4Address('1.2.3.4'))
960 self.assertTrue(self.ipv6_address != '')
961 self.assertTrue(self.ipv6_address != [])
962 self.assertTrue(self.ipv6_address != 2)
963
964 def testSlash32Constructor(self):
965 self.assertEqual(str(ipaddress.IPv4Interface(
966 '1.2.3.4/255.255.255.255')), '1.2.3.4/32')
967
968 def testSlash128Constructor(self):
969 self.assertEqual(str(ipaddress.IPv6Interface('::1/128')),
970 '::1/128')
971
972 def testSlash0Constructor(self):
973 self.assertEqual(str(ipaddress.IPv4Interface('1.2.3.4/0.0.0.0')),
974 '1.2.3.4/0')
975
976 def testCollapsing(self):
977 # test only IP addresses including some duplicates
978 ip1 = ipaddress.IPv4Address('1.1.1.0')
979 ip2 = ipaddress.IPv4Address('1.1.1.1')
980 ip3 = ipaddress.IPv4Address('1.1.1.2')
981 ip4 = ipaddress.IPv4Address('1.1.1.3')
982 ip5 = ipaddress.IPv4Address('1.1.1.4')
983 ip6 = ipaddress.IPv4Address('1.1.1.0')
984 # check that addreses are subsumed properly.
985 collapsed = ipaddress.collapse_addresses(
986 [ip1, ip2, ip3, ip4, ip5, ip6])
Hynek Schlawack91c5a342012-06-05 11:55:58 +0200987 self.assertEqual(list(collapsed),
988 [ipaddress.IPv4Network('1.1.1.0/30'),
989 ipaddress.IPv4Network('1.1.1.4/32')])
Nick Coghlandc9b2552012-05-20 21:01:57 +1000990
991 # test a mix of IP addresses and networks including some duplicates
992 ip1 = ipaddress.IPv4Address('1.1.1.0')
993 ip2 = ipaddress.IPv4Address('1.1.1.1')
994 ip3 = ipaddress.IPv4Address('1.1.1.2')
995 ip4 = ipaddress.IPv4Address('1.1.1.3')
996 #ip5 = ipaddress.IPv4Interface('1.1.1.4/30')
997 #ip6 = ipaddress.IPv4Interface('1.1.1.4/30')
998 # check that addreses are subsumed properly.
999 collapsed = ipaddress.collapse_addresses([ip1, ip2, ip3, ip4])
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001000 self.assertEqual(list(collapsed),
1001 [ipaddress.IPv4Network('1.1.1.0/30')])
Nick Coghlandc9b2552012-05-20 21:01:57 +10001002
1003 # test only IP networks
1004 ip1 = ipaddress.IPv4Network('1.1.0.0/24')
1005 ip2 = ipaddress.IPv4Network('1.1.1.0/24')
1006 ip3 = ipaddress.IPv4Network('1.1.2.0/24')
1007 ip4 = ipaddress.IPv4Network('1.1.3.0/24')
1008 ip5 = ipaddress.IPv4Network('1.1.4.0/24')
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001009 # stored in no particular order b/c we want CollapseAddr to call
1010 # [].sort
Nick Coghlandc9b2552012-05-20 21:01:57 +10001011 ip6 = ipaddress.IPv4Network('1.1.0.0/22')
1012 # check that addreses are subsumed properly.
1013 collapsed = ipaddress.collapse_addresses([ip1, ip2, ip3, ip4, ip5,
1014 ip6])
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001015 self.assertEqual(list(collapsed),
1016 [ipaddress.IPv4Network('1.1.0.0/22'),
1017 ipaddress.IPv4Network('1.1.4.0/24')])
Nick Coghlandc9b2552012-05-20 21:01:57 +10001018
1019 # test that two addresses are supernet'ed properly
1020 collapsed = ipaddress.collapse_addresses([ip1, ip2])
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001021 self.assertEqual(list(collapsed),
1022 [ipaddress.IPv4Network('1.1.0.0/23')])
Nick Coghlandc9b2552012-05-20 21:01:57 +10001023
1024 # test same IP networks
1025 ip_same1 = ip_same2 = ipaddress.IPv4Network('1.1.1.1/32')
1026 self.assertEqual(list(ipaddress.collapse_addresses(
1027 [ip_same1, ip_same2])),
1028 [ip_same1])
1029
1030 # test same IP addresses
1031 ip_same1 = ip_same2 = ipaddress.IPv4Address('1.1.1.1')
1032 self.assertEqual(list(ipaddress.collapse_addresses(
1033 [ip_same1, ip_same2])),
1034 [ipaddress.ip_network('1.1.1.1/32')])
1035 ip1 = ipaddress.IPv6Network('2001::/100')
1036 ip2 = ipaddress.IPv6Network('2001::/120')
1037 ip3 = ipaddress.IPv6Network('2001::/96')
1038 # test that ipv6 addresses are subsumed properly.
1039 collapsed = ipaddress.collapse_addresses([ip1, ip2, ip3])
1040 self.assertEqual(list(collapsed), [ip3])
1041
1042 # the toejam test
Hynek Schlawack35db5132012-06-01 20:12:17 +02001043 addr_tuples = [
1044 (ipaddress.ip_address('1.1.1.1'),
1045 ipaddress.ip_address('::1')),
1046 (ipaddress.IPv4Network('1.1.0.0/24'),
1047 ipaddress.IPv6Network('2001::/120')),
1048 (ipaddress.IPv4Network('1.1.0.0/32'),
1049 ipaddress.IPv6Network('2001::/128')),
1050 ]
1051 for ip1, ip2 in addr_tuples:
1052 self.assertRaises(TypeError, ipaddress.collapse_addresses,
1053 [ip1, ip2])
Nick Coghlandc9b2552012-05-20 21:01:57 +10001054
1055 def testSummarizing(self):
1056 #ip = ipaddress.ip_address
1057 #ipnet = ipaddress.ip_network
1058 summarize = ipaddress.summarize_address_range
1059 ip1 = ipaddress.ip_address('1.1.1.0')
1060 ip2 = ipaddress.ip_address('1.1.1.255')
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001061
1062 # summarize works only for IPv4 & IPv6
1063 class IPv7Address(ipaddress.IPv6Address):
1064 @property
1065 def version(self):
1066 return 7
1067 ip_invalid1 = IPv7Address('::1')
1068 ip_invalid2 = IPv7Address('::1')
1069 self.assertRaises(ValueError, list,
1070 summarize(ip_invalid1, ip_invalid2))
1071 # test that a summary over ip4 & ip6 fails
1072 self.assertRaises(TypeError, list,
1073 summarize(ip1, ipaddress.IPv6Address('::1')))
1074 # test a /24 is summarized properly
Nick Coghlandc9b2552012-05-20 21:01:57 +10001075 self.assertEqual(list(summarize(ip1, ip2))[0],
1076 ipaddress.ip_network('1.1.1.0/24'))
1077 # test an IPv4 range that isn't on a network byte boundary
1078 ip2 = ipaddress.ip_address('1.1.1.8')
1079 self.assertEqual(list(summarize(ip1, ip2)),
1080 [ipaddress.ip_network('1.1.1.0/29'),
1081 ipaddress.ip_network('1.1.1.8')])
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001082 # all!
1083 ip1 = ipaddress.IPv4Address(0)
1084 ip2 = ipaddress.IPv4Address(ipaddress.IPv4Address._ALL_ONES)
1085 self.assertEqual([ipaddress.IPv4Network('0.0.0.0/0')],
1086 list(summarize(ip1, ip2)))
Nick Coghlandc9b2552012-05-20 21:01:57 +10001087
1088 ip1 = ipaddress.ip_address('1::')
1089 ip2 = ipaddress.ip_address('1:ffff:ffff:ffff:ffff:ffff:ffff:ffff')
1090 # test a IPv6 is sumamrized properly
1091 self.assertEqual(list(summarize(ip1, ip2))[0],
1092 ipaddress.ip_network('1::/16'))
1093 # test an IPv6 range that isn't on a network byte boundary
1094 ip2 = ipaddress.ip_address('2::')
1095 self.assertEqual(list(summarize(ip1, ip2)),
1096 [ipaddress.ip_network('1::/16'),
1097 ipaddress.ip_network('2::/128')])
1098
1099 # test exception raised when first is greater than last
1100 self.assertRaises(ValueError, list,
1101 summarize(ipaddress.ip_address('1.1.1.0'),
1102 ipaddress.ip_address('1.1.0.0')))
1103 # test exception raised when first and last aren't IP addresses
1104 self.assertRaises(TypeError, list,
1105 summarize(ipaddress.ip_network('1.1.1.0'),
1106 ipaddress.ip_network('1.1.0.0')))
1107 self.assertRaises(TypeError, list,
1108 summarize(ipaddress.ip_network('1.1.1.0'),
1109 ipaddress.ip_network('1.1.0.0')))
1110 # test exception raised when first and last are not same version
1111 self.assertRaises(TypeError, list,
1112 summarize(ipaddress.ip_address('::'),
1113 ipaddress.ip_network('1.1.0.0')))
1114
1115 def testAddressComparison(self):
1116 self.assertTrue(ipaddress.ip_address('1.1.1.1') <=
1117 ipaddress.ip_address('1.1.1.1'))
1118 self.assertTrue(ipaddress.ip_address('1.1.1.1') <=
1119 ipaddress.ip_address('1.1.1.2'))
1120 self.assertTrue(ipaddress.ip_address('::1') <=
1121 ipaddress.ip_address('::1'))
1122 self.assertTrue(ipaddress.ip_address('::1') <=
1123 ipaddress.ip_address('::2'))
1124
Nick Coghlan3008ec02012-07-08 00:45:33 +10001125 def testInterfaceComparison(self):
1126 self.assertTrue(ipaddress.ip_interface('1.1.1.1') <=
1127 ipaddress.ip_interface('1.1.1.1'))
1128 self.assertTrue(ipaddress.ip_interface('1.1.1.1') <=
1129 ipaddress.ip_interface('1.1.1.2'))
1130 self.assertTrue(ipaddress.ip_interface('::1') <=
1131 ipaddress.ip_interface('::1'))
1132 self.assertTrue(ipaddress.ip_interface('::1') <=
1133 ipaddress.ip_interface('::2'))
1134
Nick Coghlandc9b2552012-05-20 21:01:57 +10001135 def testNetworkComparison(self):
1136 # ip1 and ip2 have the same network address
1137 ip1 = ipaddress.IPv4Network('1.1.1.0/24')
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001138 ip2 = ipaddress.IPv4Network('1.1.1.0/32')
Nick Coghlandc9b2552012-05-20 21:01:57 +10001139 ip3 = ipaddress.IPv4Network('1.1.2.0/24')
1140
1141 self.assertTrue(ip1 < ip3)
1142 self.assertTrue(ip3 > ip2)
1143
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001144 self.assertEqual(ip1.compare_networks(ip1), 0)
1145
1146 # if addresses are the same, sort by netmask
1147 self.assertEqual(ip1.compare_networks(ip2), -1)
1148 self.assertEqual(ip2.compare_networks(ip1), 1)
1149
Nick Coghlandc9b2552012-05-20 21:01:57 +10001150 self.assertEqual(ip1.compare_networks(ip3), -1)
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001151 self.assertEqual(ip3.compare_networks(ip1), 1)
Nick Coghlandc9b2552012-05-20 21:01:57 +10001152 self.assertTrue(ip1._get_networks_key() < ip3._get_networks_key())
1153
1154 ip1 = ipaddress.IPv6Network('2001:2000::/96')
1155 ip2 = ipaddress.IPv6Network('2001:2001::/96')
1156 ip3 = ipaddress.IPv6Network('2001:ffff:2000::/96')
1157
1158 self.assertTrue(ip1 < ip3)
1159 self.assertTrue(ip3 > ip2)
1160 self.assertEqual(ip1.compare_networks(ip3), -1)
1161 self.assertTrue(ip1._get_networks_key() < ip3._get_networks_key())
1162
1163 # Test comparing different protocols.
1164 # Should always raise a TypeError.
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001165 self.assertRaises(TypeError,
1166 self.ipv4_network.compare_networks,
1167 self.ipv6_network)
Nick Coghlandc9b2552012-05-20 21:01:57 +10001168 ipv6 = ipaddress.IPv6Interface('::/0')
1169 ipv4 = ipaddress.IPv4Interface('0.0.0.0/0')
1170 self.assertRaises(TypeError, ipv4.__lt__, ipv6)
1171 self.assertRaises(TypeError, ipv4.__gt__, ipv6)
1172 self.assertRaises(TypeError, ipv6.__lt__, ipv4)
1173 self.assertRaises(TypeError, ipv6.__gt__, ipv4)
1174
1175 # Regression test for issue 19.
1176 ip1 = ipaddress.ip_network('10.1.2.128/25')
1177 self.assertFalse(ip1 < ip1)
1178 self.assertFalse(ip1 > ip1)
1179 ip2 = ipaddress.ip_network('10.1.3.0/24')
1180 self.assertTrue(ip1 < ip2)
1181 self.assertFalse(ip2 < ip1)
1182 self.assertFalse(ip1 > ip2)
1183 self.assertTrue(ip2 > ip1)
1184 ip3 = ipaddress.ip_network('10.1.3.0/25')
1185 self.assertTrue(ip2 < ip3)
1186 self.assertFalse(ip3 < ip2)
1187 self.assertFalse(ip2 > ip3)
1188 self.assertTrue(ip3 > ip2)
1189
1190 # Regression test for issue 28.
1191 ip1 = ipaddress.ip_network('10.10.10.0/31')
1192 ip2 = ipaddress.ip_network('10.10.10.0')
1193 ip3 = ipaddress.ip_network('10.10.10.2/31')
1194 ip4 = ipaddress.ip_network('10.10.10.2')
1195 sorted = [ip1, ip2, ip3, ip4]
1196 unsorted = [ip2, ip4, ip1, ip3]
1197 unsorted.sort()
1198 self.assertEqual(sorted, unsorted)
1199 unsorted = [ip4, ip1, ip3, ip2]
1200 unsorted.sort()
1201 self.assertEqual(sorted, unsorted)
1202 self.assertRaises(TypeError, ip1.__lt__,
1203 ipaddress.ip_address('10.10.10.0'))
1204 self.assertRaises(TypeError, ip2.__lt__,
1205 ipaddress.ip_address('10.10.10.0'))
1206
1207 # <=, >=
1208 self.assertTrue(ipaddress.ip_network('1.1.1.1') <=
1209 ipaddress.ip_network('1.1.1.1'))
1210 self.assertTrue(ipaddress.ip_network('1.1.1.1') <=
1211 ipaddress.ip_network('1.1.1.2'))
1212 self.assertFalse(ipaddress.ip_network('1.1.1.2') <=
1213 ipaddress.ip_network('1.1.1.1'))
1214 self.assertTrue(ipaddress.ip_network('::1') <=
1215 ipaddress.ip_network('::1'))
1216 self.assertTrue(ipaddress.ip_network('::1') <=
1217 ipaddress.ip_network('::2'))
1218 self.assertFalse(ipaddress.ip_network('::2') <=
1219 ipaddress.ip_network('::1'))
1220
1221 def testStrictNetworks(self):
1222 self.assertRaises(ValueError, ipaddress.ip_network, '192.168.1.1/24')
1223 self.assertRaises(ValueError, ipaddress.ip_network, '::1/120')
1224
1225 def testOverlaps(self):
1226 other = ipaddress.IPv4Network('1.2.3.0/30')
1227 other2 = ipaddress.IPv4Network('1.2.2.0/24')
1228 other3 = ipaddress.IPv4Network('1.2.2.64/26')
1229 self.assertTrue(self.ipv4_network.overlaps(other))
1230 self.assertFalse(self.ipv4_network.overlaps(other2))
1231 self.assertTrue(other2.overlaps(other3))
1232
1233 def testEmbeddedIpv4(self):
1234 ipv4_string = '192.168.0.1'
1235 ipv4 = ipaddress.IPv4Interface(ipv4_string)
1236 v4compat_ipv6 = ipaddress.IPv6Interface('::%s' % ipv4_string)
1237 self.assertEqual(int(v4compat_ipv6.ip), int(ipv4.ip))
1238 v4mapped_ipv6 = ipaddress.IPv6Interface('::ffff:%s' % ipv4_string)
1239 self.assertNotEqual(v4mapped_ipv6.ip, ipv4.ip)
1240 self.assertRaises(ipaddress.AddressValueError, ipaddress.IPv6Interface,
1241 '2001:1.1.1.1:1.1.1.1')
1242
1243 # Issue 67: IPv6 with embedded IPv4 address not recognized.
1244 def testIPv6AddressTooLarge(self):
1245 # RFC4291 2.5.5.2
1246 self.assertEqual(ipaddress.ip_address('::FFFF:192.0.2.1'),
1247 ipaddress.ip_address('::FFFF:c000:201'))
1248 # RFC4291 2.2 (part 3) x::d.d.d.d
1249 self.assertEqual(ipaddress.ip_address('FFFF::192.0.2.1'),
1250 ipaddress.ip_address('FFFF::c000:201'))
1251
1252 def testIPVersion(self):
1253 self.assertEqual(self.ipv4_address.version, 4)
1254 self.assertEqual(self.ipv6_address.version, 6)
1255
1256 def testMaxPrefixLength(self):
1257 self.assertEqual(self.ipv4_interface.max_prefixlen, 32)
1258 self.assertEqual(self.ipv6_interface.max_prefixlen, 128)
1259
1260 def testPacked(self):
1261 self.assertEqual(self.ipv4_address.packed,
Nick Coghlan5cf896f2012-07-07 01:43:31 +10001262 b'\x01\x02\x03\x04')
Nick Coghlandc9b2552012-05-20 21:01:57 +10001263 self.assertEqual(ipaddress.IPv4Interface('255.254.253.252').packed,
Nick Coghlan5cf896f2012-07-07 01:43:31 +10001264 b'\xff\xfe\xfd\xfc')
Nick Coghlandc9b2552012-05-20 21:01:57 +10001265 self.assertEqual(self.ipv6_address.packed,
Nick Coghlan5cf896f2012-07-07 01:43:31 +10001266 b'\x20\x01\x06\x58\x02\x2a\xca\xfe'
1267 b'\x02\x00\x00\x00\x00\x00\x00\x01')
Nick Coghlandc9b2552012-05-20 21:01:57 +10001268 self.assertEqual(ipaddress.IPv6Interface('ffff:2:3:4:ffff::').packed,
Nick Coghlan5cf896f2012-07-07 01:43:31 +10001269 b'\xff\xff\x00\x02\x00\x03\x00\x04\xff\xff'
1270 + b'\x00' * 6)
Nick Coghlandc9b2552012-05-20 21:01:57 +10001271 self.assertEqual(ipaddress.IPv6Interface('::1:0:0:0:0').packed,
Nick Coghlan5cf896f2012-07-07 01:43:31 +10001272 b'\x00' * 6 + b'\x00\x01' + b'\x00' * 8)
Nick Coghlandc9b2552012-05-20 21:01:57 +10001273
1274 def testIpStrFromPrefixlen(self):
1275 ipv4 = ipaddress.IPv4Interface('1.2.3.4/24')
1276 self.assertEqual(ipv4._ip_string_from_prefix(), '255.255.255.0')
1277 self.assertEqual(ipv4._ip_string_from_prefix(28), '255.255.255.240')
1278
1279 def testIpType(self):
1280 ipv4net = ipaddress.ip_network('1.2.3.4')
1281 ipv4addr = ipaddress.ip_address('1.2.3.4')
1282 ipv6net = ipaddress.ip_network('::1.2.3.4')
1283 ipv6addr = ipaddress.ip_address('::1.2.3.4')
1284 self.assertEqual(ipaddress.IPv4Network, type(ipv4net))
1285 self.assertEqual(ipaddress.IPv4Address, type(ipv4addr))
1286 self.assertEqual(ipaddress.IPv6Network, type(ipv6net))
1287 self.assertEqual(ipaddress.IPv6Address, type(ipv6addr))
1288
1289 def testReservedIpv4(self):
1290 # test networks
1291 self.assertEqual(True, ipaddress.ip_interface(
1292 '224.1.1.1/31').is_multicast)
1293 self.assertEqual(False, ipaddress.ip_network('240.0.0.0').is_multicast)
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001294 self.assertEqual(True, ipaddress.ip_network('240.0.0.0').is_reserved)
Nick Coghlandc9b2552012-05-20 21:01:57 +10001295
1296 self.assertEqual(True, ipaddress.ip_interface(
1297 '192.168.1.1/17').is_private)
1298 self.assertEqual(False, ipaddress.ip_network('192.169.0.0').is_private)
1299 self.assertEqual(True, ipaddress.ip_network(
1300 '10.255.255.255').is_private)
1301 self.assertEqual(False, ipaddress.ip_network('11.0.0.0').is_private)
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001302 self.assertEqual(False, ipaddress.ip_network('11.0.0.0').is_reserved)
Nick Coghlandc9b2552012-05-20 21:01:57 +10001303 self.assertEqual(True, ipaddress.ip_network(
1304 '172.31.255.255').is_private)
1305 self.assertEqual(False, ipaddress.ip_network('172.32.0.0').is_private)
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001306 self.assertEqual(True,
1307 ipaddress.ip_network('169.254.1.0/24').is_link_local)
Nick Coghlandc9b2552012-05-20 21:01:57 +10001308
1309 self.assertEqual(True,
1310 ipaddress.ip_interface(
1311 '169.254.100.200/24').is_link_local)
1312 self.assertEqual(False,
1313 ipaddress.ip_interface(
1314 '169.255.100.200/24').is_link_local)
1315
1316 self.assertEqual(True,
1317 ipaddress.ip_network(
1318 '127.100.200.254/32').is_loopback)
1319 self.assertEqual(True, ipaddress.ip_network(
1320 '127.42.0.0/16').is_loopback)
1321 self.assertEqual(False, ipaddress.ip_network('128.0.0.0').is_loopback)
1322
1323 # test addresses
Hynek Schlawackbcd30442012-06-04 14:19:39 +02001324 self.assertEqual(True, ipaddress.ip_address('0.0.0.0').is_unspecified)
Nick Coghlandc9b2552012-05-20 21:01:57 +10001325 self.assertEqual(True, ipaddress.ip_address('224.1.1.1').is_multicast)
1326 self.assertEqual(False, ipaddress.ip_address('240.0.0.0').is_multicast)
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001327 self.assertEqual(True, ipaddress.ip_address('240.0.0.1').is_reserved)
1328 self.assertEqual(False,
1329 ipaddress.ip_address('239.255.255.255').is_reserved)
Nick Coghlandc9b2552012-05-20 21:01:57 +10001330
1331 self.assertEqual(True, ipaddress.ip_address('192.168.1.1').is_private)
1332 self.assertEqual(False, ipaddress.ip_address('192.169.0.0').is_private)
1333 self.assertEqual(True, ipaddress.ip_address(
1334 '10.255.255.255').is_private)
1335 self.assertEqual(False, ipaddress.ip_address('11.0.0.0').is_private)
1336 self.assertEqual(True, ipaddress.ip_address(
1337 '172.31.255.255').is_private)
1338 self.assertEqual(False, ipaddress.ip_address('172.32.0.0').is_private)
1339
1340 self.assertEqual(True,
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001341 ipaddress.ip_address('169.254.100.200').is_link_local)
Nick Coghlandc9b2552012-05-20 21:01:57 +10001342 self.assertEqual(False,
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001343 ipaddress.ip_address('169.255.100.200').is_link_local)
Nick Coghlandc9b2552012-05-20 21:01:57 +10001344
1345 self.assertEqual(True,
1346 ipaddress.ip_address('127.100.200.254').is_loopback)
1347 self.assertEqual(True, ipaddress.ip_address('127.42.0.0').is_loopback)
1348 self.assertEqual(False, ipaddress.ip_address('128.0.0.0').is_loopback)
1349 self.assertEqual(True, ipaddress.ip_network('0.0.0.0').is_unspecified)
1350
1351 def testReservedIpv6(self):
1352
1353 self.assertEqual(True, ipaddress.ip_network('ffff::').is_multicast)
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001354 self.assertEqual(True, ipaddress.ip_network(2**128 - 1).is_multicast)
Nick Coghlandc9b2552012-05-20 21:01:57 +10001355 self.assertEqual(True, ipaddress.ip_network('ff00::').is_multicast)
1356 self.assertEqual(False, ipaddress.ip_network('fdff::').is_multicast)
1357
1358 self.assertEqual(True, ipaddress.ip_network('fecf::').is_site_local)
1359 self.assertEqual(True, ipaddress.ip_network(
1360 'feff:ffff:ffff:ffff::').is_site_local)
1361 self.assertEqual(False, ipaddress.ip_network(
1362 'fbf:ffff::').is_site_local)
1363 self.assertEqual(False, ipaddress.ip_network('ff00::').is_site_local)
1364
1365 self.assertEqual(True, ipaddress.ip_network('fc00::').is_private)
1366 self.assertEqual(True, ipaddress.ip_network(
1367 'fc00:ffff:ffff:ffff::').is_private)
1368 self.assertEqual(False, ipaddress.ip_network('fbff:ffff::').is_private)
1369 self.assertEqual(False, ipaddress.ip_network('fe00::').is_private)
1370
1371 self.assertEqual(True, ipaddress.ip_network('fea0::').is_link_local)
1372 self.assertEqual(True, ipaddress.ip_network(
1373 'febf:ffff::').is_link_local)
1374 self.assertEqual(False, ipaddress.ip_network(
1375 'fe7f:ffff::').is_link_local)
1376 self.assertEqual(False, ipaddress.ip_network('fec0::').is_link_local)
1377
1378 self.assertEqual(True, ipaddress.ip_interface('0:0::0:01').is_loopback)
1379 self.assertEqual(False, ipaddress.ip_interface('::1/127').is_loopback)
1380 self.assertEqual(False, ipaddress.ip_network('::').is_loopback)
1381 self.assertEqual(False, ipaddress.ip_network('::2').is_loopback)
1382
1383 self.assertEqual(True, ipaddress.ip_network('0::0').is_unspecified)
1384 self.assertEqual(False, ipaddress.ip_network('::1').is_unspecified)
1385 self.assertEqual(False, ipaddress.ip_network('::/127').is_unspecified)
1386
1387 # test addresses
1388 self.assertEqual(True, ipaddress.ip_address('ffff::').is_multicast)
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001389 self.assertEqual(True, ipaddress.ip_address(2**128 - 1).is_multicast)
Nick Coghlandc9b2552012-05-20 21:01:57 +10001390 self.assertEqual(True, ipaddress.ip_address('ff00::').is_multicast)
1391 self.assertEqual(False, ipaddress.ip_address('fdff::').is_multicast)
1392
1393 self.assertEqual(True, ipaddress.ip_address('fecf::').is_site_local)
1394 self.assertEqual(True, ipaddress.ip_address(
1395 'feff:ffff:ffff:ffff::').is_site_local)
1396 self.assertEqual(False, ipaddress.ip_address(
1397 'fbf:ffff::').is_site_local)
1398 self.assertEqual(False, ipaddress.ip_address('ff00::').is_site_local)
1399
1400 self.assertEqual(True, ipaddress.ip_address('fc00::').is_private)
1401 self.assertEqual(True, ipaddress.ip_address(
1402 'fc00:ffff:ffff:ffff::').is_private)
1403 self.assertEqual(False, ipaddress.ip_address('fbff:ffff::').is_private)
1404 self.assertEqual(False, ipaddress.ip_address('fe00::').is_private)
1405
1406 self.assertEqual(True, ipaddress.ip_address('fea0::').is_link_local)
1407 self.assertEqual(True, ipaddress.ip_address(
1408 'febf:ffff::').is_link_local)
1409 self.assertEqual(False, ipaddress.ip_address(
1410 'fe7f:ffff::').is_link_local)
1411 self.assertEqual(False, ipaddress.ip_address('fec0::').is_link_local)
1412
1413 self.assertEqual(True, ipaddress.ip_address('0:0::0:01').is_loopback)
1414 self.assertEqual(True, ipaddress.ip_address('::1').is_loopback)
1415 self.assertEqual(False, ipaddress.ip_address('::2').is_loopback)
1416
1417 self.assertEqual(True, ipaddress.ip_address('0::0').is_unspecified)
1418 self.assertEqual(False, ipaddress.ip_address('::1').is_unspecified)
1419
1420 # some generic IETF reserved addresses
1421 self.assertEqual(True, ipaddress.ip_address('100::').is_reserved)
1422 self.assertEqual(True, ipaddress.ip_network('4000::1/128').is_reserved)
1423
1424 def testIpv4Mapped(self):
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001425 self.assertEqual(
1426 ipaddress.ip_address('::ffff:192.168.1.1').ipv4_mapped,
1427 ipaddress.ip_address('192.168.1.1'))
Nick Coghlandc9b2552012-05-20 21:01:57 +10001428 self.assertEqual(ipaddress.ip_address('::c0a8:101').ipv4_mapped, None)
1429 self.assertEqual(ipaddress.ip_address('::ffff:c0a8:101').ipv4_mapped,
1430 ipaddress.ip_address('192.168.1.1'))
1431
1432 def testAddrExclude(self):
1433 addr1 = ipaddress.ip_network('10.1.1.0/24')
1434 addr2 = ipaddress.ip_network('10.1.1.0/26')
1435 addr3 = ipaddress.ip_network('10.2.1.0/24')
1436 addr4 = ipaddress.ip_address('10.1.1.0')
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001437 addr5 = ipaddress.ip_network('2001:db8::0/32')
Nick Coghlandc9b2552012-05-20 21:01:57 +10001438 self.assertEqual(sorted(list(addr1.address_exclude(addr2))),
1439 [ipaddress.ip_network('10.1.1.64/26'),
1440 ipaddress.ip_network('10.1.1.128/25')])
1441 self.assertRaises(ValueError, list, addr1.address_exclude(addr3))
1442 self.assertRaises(TypeError, list, addr1.address_exclude(addr4))
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001443 self.assertRaises(TypeError, list, addr1.address_exclude(addr5))
Nick Coghlandc9b2552012-05-20 21:01:57 +10001444 self.assertEqual(list(addr1.address_exclude(addr1)), [])
1445
1446 def testHash(self):
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001447 self.assertEqual(hash(ipaddress.ip_interface('10.1.1.0/24')),
1448 hash(ipaddress.ip_interface('10.1.1.0/24')))
Nick Coghlandc9b2552012-05-20 21:01:57 +10001449 self.assertEqual(hash(ipaddress.ip_network('10.1.1.0/24')),
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001450 hash(ipaddress.ip_network('10.1.1.0/24')))
Nick Coghlandc9b2552012-05-20 21:01:57 +10001451 self.assertEqual(hash(ipaddress.ip_address('10.1.1.0')),
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001452 hash(ipaddress.ip_address('10.1.1.0')))
Nick Coghlandc9b2552012-05-20 21:01:57 +10001453 # i70
1454 self.assertEqual(hash(ipaddress.ip_address('1.2.3.4')),
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001455 hash(ipaddress.ip_address(
Nick Coghlandc9b2552012-05-20 21:01:57 +10001456 int(ipaddress.ip_address('1.2.3.4')._ip))))
1457 ip1 = ipaddress.ip_address('10.1.1.0')
1458 ip2 = ipaddress.ip_address('1::')
1459 dummy = {}
1460 dummy[self.ipv4_address] = None
1461 dummy[self.ipv6_address] = None
1462 dummy[ip1] = None
1463 dummy[ip2] = None
1464 self.assertTrue(self.ipv4_address in dummy)
1465 self.assertTrue(ip2 in dummy)
1466
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001467 def testIPBases(self):
1468 net = self.ipv4_network
1469 self.assertEqual('1.2.3.0/24', net.compressed)
1470 self.assertEqual(
1471 net._ip_int_from_prefix(24),
1472 net._ip_int_from_prefix(None))
1473 net = self.ipv6_network
1474 self.assertRaises(ValueError, net._string_from_ip_int, 2**128 + 1)
1475 self.assertEqual(
1476 self.ipv6_address._string_from_ip_int(self.ipv6_address._ip),
1477 self.ipv6_address._string_from_ip_int(None))
1478
Hynek Schlawack454a74d2012-06-04 18:14:02 +02001479 def testIPv6NetworkHelpers(self):
1480 net = self.ipv6_network
1481 self.assertEqual('2001:658:22a:cafe::/64', net.with_prefixlen)
1482 self.assertEqual('2001:658:22a:cafe::/ffff:ffff:ffff:ffff::',
1483 net.with_netmask)
1484 self.assertEqual('2001:658:22a:cafe::/::ffff:ffff:ffff:ffff',
1485 net.with_hostmask)
1486 self.assertEqual('2001:658:22a:cafe::/64', str(net))
1487
1488 def testIPv4NetworkHelpers(self):
1489 net = self.ipv4_network
1490 self.assertEqual('1.2.3.0/24', net.with_prefixlen)
1491 self.assertEqual('1.2.3.0/255.255.255.0', net.with_netmask)
1492 self.assertEqual('1.2.3.0/0.0.0.255', net.with_hostmask)
1493 self.assertEqual('1.2.3.0/24', str(net))
1494
Nick Coghlandc9b2552012-05-20 21:01:57 +10001495 def testCopyConstructor(self):
1496 addr1 = ipaddress.ip_network('10.1.1.0/24')
1497 addr2 = ipaddress.ip_network(addr1)
1498 addr3 = ipaddress.ip_interface('2001:658:22a:cafe:200::1/64')
1499 addr4 = ipaddress.ip_interface(addr3)
1500 addr5 = ipaddress.IPv4Address('1.1.1.1')
1501 addr6 = ipaddress.IPv6Address('2001:658:22a:cafe:200::1')
1502
1503 self.assertEqual(addr1, addr2)
1504 self.assertEqual(addr3, addr4)
1505 self.assertEqual(addr5, ipaddress.IPv4Address(addr5))
1506 self.assertEqual(addr6, ipaddress.IPv6Address(addr6))
1507
1508 def testCompressIPv6Address(self):
1509 test_addresses = {
1510 '1:2:3:4:5:6:7:8': '1:2:3:4:5:6:7:8/128',
1511 '2001:0:0:4:0:0:0:8': '2001:0:0:4::8/128',
1512 '2001:0:0:4:5:6:7:8': '2001::4:5:6:7:8/128',
1513 '2001:0:3:4:5:6:7:8': '2001:0:3:4:5:6:7:8/128',
1514 '2001:0:3:4:5:6:7:8': '2001:0:3:4:5:6:7:8/128',
1515 '0:0:3:0:0:0:0:ffff': '0:0:3::ffff/128',
1516 '0:0:0:4:0:0:0:ffff': '::4:0:0:0:ffff/128',
1517 '0:0:0:0:5:0:0:ffff': '::5:0:0:ffff/128',
1518 '1:0:0:4:0:0:7:8': '1::4:0:0:7:8/128',
1519 '0:0:0:0:0:0:0:0': '::/128',
1520 '0:0:0:0:0:0:0:0/0': '::/0',
1521 '0:0:0:0:0:0:0:1': '::1/128',
1522 '2001:0658:022a:cafe:0000:0000:0000:0000/66':
1523 '2001:658:22a:cafe::/66',
1524 '::1.2.3.4': '::102:304/128',
1525 '1:2:3:4:5:ffff:1.2.3.4': '1:2:3:4:5:ffff:102:304/128',
1526 '::7:6:5:4:3:2:1': '0:7:6:5:4:3:2:1/128',
1527 '::7:6:5:4:3:2:0': '0:7:6:5:4:3:2:0/128',
1528 '7:6:5:4:3:2:1::': '7:6:5:4:3:2:1:0/128',
1529 '0:6:5:4:3:2:1::': '0:6:5:4:3:2:1:0/128',
1530 }
1531 for uncompressed, compressed in list(test_addresses.items()):
1532 self.assertEqual(compressed, str(ipaddress.IPv6Interface(
1533 uncompressed)))
1534
1535 def testExplodeShortHandIpStr(self):
1536 addr1 = ipaddress.IPv6Interface('2001::1')
1537 addr2 = ipaddress.IPv6Address('2001:0:5ef5:79fd:0:59d:a0e5:ba1')
1538 addr3 = ipaddress.IPv6Network('2001::/96')
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001539 addr4 = ipaddress.IPv4Address('192.168.178.1')
Nick Coghlandc9b2552012-05-20 21:01:57 +10001540 self.assertEqual('2001:0000:0000:0000:0000:0000:0000:0001/128',
1541 addr1.exploded)
1542 self.assertEqual('0000:0000:0000:0000:0000:0000:0000:0001/128',
1543 ipaddress.IPv6Interface('::1/128').exploded)
1544 # issue 77
1545 self.assertEqual('2001:0000:5ef5:79fd:0000:059d:a0e5:0ba1',
1546 addr2.exploded)
1547 self.assertEqual('2001:0000:0000:0000:0000:0000:0000:0000/96',
1548 addr3.exploded)
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001549 self.assertEqual('192.168.178.1', addr4.exploded)
Nick Coghlandc9b2552012-05-20 21:01:57 +10001550
1551 def testIntRepresentation(self):
1552 self.assertEqual(16909060, int(self.ipv4_address))
1553 self.assertEqual(42540616829182469433547762482097946625,
1554 int(self.ipv6_address))
1555
Nick Coghlandc9b2552012-05-20 21:01:57 +10001556 def testForceVersion(self):
1557 self.assertEqual(ipaddress.ip_network(1).version, 4)
Nick Coghlan51c30672012-05-27 00:25:58 +10001558 self.assertEqual(ipaddress.IPv6Network(1).version, 6)
Sandro Tosi876ecad2012-05-23 22:26:55 +02001559
Nick Coghlandc9b2552012-05-20 21:01:57 +10001560 def testWithStar(self):
Nick Coghlana8517ad2012-08-20 10:04:26 +10001561 self.assertEqual(self.ipv4_interface.with_prefixlen, "1.2.3.4/24")
1562 self.assertEqual(self.ipv4_interface.with_netmask,
Nick Coghlandc9b2552012-05-20 21:01:57 +10001563 "1.2.3.4/255.255.255.0")
Nick Coghlana8517ad2012-08-20 10:04:26 +10001564 self.assertEqual(self.ipv4_interface.with_hostmask,
Nick Coghlandc9b2552012-05-20 21:01:57 +10001565 "1.2.3.4/0.0.0.255")
1566
Nick Coghlana8517ad2012-08-20 10:04:26 +10001567 self.assertEqual(self.ipv6_interface.with_prefixlen,
Nick Coghlandc9b2552012-05-20 21:01:57 +10001568 '2001:658:22a:cafe:200::1/64')
Nick Coghlana8517ad2012-08-20 10:04:26 +10001569 self.assertEqual(self.ipv6_interface.with_netmask,
1570 '2001:658:22a:cafe:200::1/ffff:ffff:ffff:ffff::')
Nick Coghlandc9b2552012-05-20 21:01:57 +10001571 # this probably don't make much sense, but it's included for
1572 # compatibility with ipv4
Nick Coghlana8517ad2012-08-20 10:04:26 +10001573 self.assertEqual(self.ipv6_interface.with_hostmask,
Nick Coghlandc9b2552012-05-20 21:01:57 +10001574 '2001:658:22a:cafe:200::1/::ffff:ffff:ffff:ffff')
1575
1576 def testNetworkElementCaching(self):
1577 # V4 - make sure we're empty
1578 self.assertFalse('network_address' in self.ipv4_network._cache)
1579 self.assertFalse('broadcast_address' in self.ipv4_network._cache)
1580 self.assertFalse('hostmask' in self.ipv4_network._cache)
1581
1582 # V4 - populate and test
1583 self.assertEqual(self.ipv4_network.network_address,
1584 ipaddress.IPv4Address('1.2.3.0'))
1585 self.assertEqual(self.ipv4_network.broadcast_address,
1586 ipaddress.IPv4Address('1.2.3.255'))
1587 self.assertEqual(self.ipv4_network.hostmask,
1588 ipaddress.IPv4Address('0.0.0.255'))
1589
1590 # V4 - check we're cached
1591 self.assertTrue('broadcast_address' in self.ipv4_network._cache)
1592 self.assertTrue('hostmask' in self.ipv4_network._cache)
1593
1594 # V6 - make sure we're empty
1595 self.assertFalse('broadcast_address' in self.ipv6_network._cache)
1596 self.assertFalse('hostmask' in self.ipv6_network._cache)
1597
1598 # V6 - populate and test
1599 self.assertEqual(self.ipv6_network.network_address,
1600 ipaddress.IPv6Address('2001:658:22a:cafe::'))
1601 self.assertEqual(self.ipv6_interface.network.network_address,
1602 ipaddress.IPv6Address('2001:658:22a:cafe::'))
1603
1604 self.assertEqual(
1605 self.ipv6_network.broadcast_address,
1606 ipaddress.IPv6Address('2001:658:22a:cafe:ffff:ffff:ffff:ffff'))
1607 self.assertEqual(self.ipv6_network.hostmask,
1608 ipaddress.IPv6Address('::ffff:ffff:ffff:ffff'))
1609 self.assertEqual(
1610 self.ipv6_interface.network.broadcast_address,
1611 ipaddress.IPv6Address('2001:658:22a:cafe:ffff:ffff:ffff:ffff'))
1612 self.assertEqual(self.ipv6_interface.network.hostmask,
1613 ipaddress.IPv6Address('::ffff:ffff:ffff:ffff'))
1614
1615 # V6 - check we're cached
1616 self.assertTrue('broadcast_address' in self.ipv6_network._cache)
1617 self.assertTrue('hostmask' in self.ipv6_network._cache)
Hynek Schlawack91c5a342012-06-05 11:55:58 +02001618 self.assertTrue(
1619 'broadcast_address' in self.ipv6_interface.network._cache)
Nick Coghlandc9b2552012-05-20 21:01:57 +10001620 self.assertTrue('hostmask' in self.ipv6_interface.network._cache)
1621
1622 def testTeredo(self):
1623 # stolen from wikipedia
1624 server = ipaddress.IPv4Address('65.54.227.120')
1625 client = ipaddress.IPv4Address('192.0.2.45')
1626 teredo_addr = '2001:0000:4136:e378:8000:63bf:3fff:fdd2'
1627 self.assertEqual((server, client),
1628 ipaddress.ip_address(teredo_addr).teredo)
1629 bad_addr = '2000::4136:e378:8000:63bf:3fff:fdd2'
1630 self.assertFalse(ipaddress.ip_address(bad_addr).teredo)
1631 bad_addr = '2001:0001:4136:e378:8000:63bf:3fff:fdd2'
1632 self.assertFalse(ipaddress.ip_address(bad_addr).teredo)
1633
1634 # i77
1635 teredo_addr = ipaddress.IPv6Address('2001:0:5ef5:79fd:0:59d:a0e5:ba1')
1636 self.assertEqual((ipaddress.IPv4Address('94.245.121.253'),
1637 ipaddress.IPv4Address('95.26.244.94')),
1638 teredo_addr.teredo)
1639
Nick Coghlandc9b2552012-05-20 21:01:57 +10001640 def testsixtofour(self):
1641 sixtofouraddr = ipaddress.ip_address('2002:ac1d:2d64::1')
1642 bad_addr = ipaddress.ip_address('2000:ac1d:2d64::1')
1643 self.assertEqual(ipaddress.IPv4Address('172.29.45.100'),
1644 sixtofouraddr.sixtofour)
1645 self.assertFalse(bad_addr.sixtofour)
1646
Nick Coghlandc9b2552012-05-20 21:01:57 +10001647
1648if __name__ == '__main__':
1649 unittest.main()