from ast import literal_eval import pickle import pytest from netaddr import iter_iprange, IPAddress, cidr_merge, IPNetwork, IPRange, ZEROFILL, AddrFormatError from netaddr.compat import _sys_maxint def test_ip_range(): ip_list = list(iter_iprange('192.0.2.1', '192.0.2.14')) assert len(ip_list) == 14 assert ip_list == [ IPAddress('192.0.2.1'), IPAddress('192.0.2.2'), IPAddress('192.0.2.3'), IPAddress('192.0.2.4'), IPAddress('192.0.2.5'), IPAddress('192.0.2.6'), IPAddress('192.0.2.7'), IPAddress('192.0.2.8'), IPAddress('192.0.2.9'), IPAddress('192.0.2.10'), IPAddress('192.0.2.11'), IPAddress('192.0.2.12'), IPAddress('192.0.2.13'), IPAddress('192.0.2.14'), ] assert cidr_merge(ip_list) == [ IPNetwork('192.0.2.1/32'), IPNetwork('192.0.2.2/31'), IPNetwork('192.0.2.4/30'), IPNetwork('192.0.2.8/30'), IPNetwork('192.0.2.12/31'), IPNetwork('192.0.2.14/32'), ] def test_iprange(): range1 = IPRange('192.0.2.1', '192.0.2.15') assert range1 == IPRange('192.0.2.1', '192.0.2.15') assert range1.cidrs() == [ IPNetwork('192.0.2.1/32'), IPNetwork('192.0.2.2/31'), IPNetwork('192.0.2.4/30'), IPNetwork('192.0.2.8/29'), ] assert IPRange('192.0.2.0', '192.0.2.255') == IPNetwork('192.0.2.0/24') range2 = IPRange('192.0.2.1', '192.0.2.15') addrs = list(range2) assert addrs == [ IPAddress('192.0.2.1'), IPAddress('192.0.2.2'), IPAddress('192.0.2.3'), IPAddress('192.0.2.4'), IPAddress('192.0.2.5'), IPAddress('192.0.2.6'), IPAddress('192.0.2.7'), IPAddress('192.0.2.8'), IPAddress('192.0.2.9'), IPAddress('192.0.2.10'), IPAddress('192.0.2.11'), IPAddress('192.0.2.12'), IPAddress('192.0.2.13'), IPAddress('192.0.2.14'), IPAddress('192.0.2.15'), ] assert range2 != addrs assert list(range2) == addrs subnets = range2.cidrs() assert subnets == [ IPNetwork('192.0.2.1/32'), IPNetwork('192.0.2.2/31'), IPNetwork('192.0.2.4/30'), IPNetwork('192.0.2.8/29')] assert range2 != subnets assert range2.cidrs() == subnets def test_iprange_boundaries(): assert list(iter_iprange('192.0.2.0', '192.0.2.7')) == [ IPAddress('192.0.2.0'), IPAddress('192.0.2.1'), IPAddress('192.0.2.2'), IPAddress('192.0.2.3'), IPAddress('192.0.2.4'), IPAddress('192.0.2.5'), IPAddress('192.0.2.6'), IPAddress('192.0.2.7'), ] assert list(iter_iprange('::ffff:192.0.2.0', '::ffff:192.0.2.7')) == [ IPAddress('::ffff:192.0.2.0'), IPAddress('::ffff:192.0.2.1'), IPAddress('::ffff:192.0.2.2'), IPAddress('::ffff:192.0.2.3'), IPAddress('::ffff:192.0.2.4'), IPAddress('::ffff:192.0.2.5'), IPAddress('::ffff:192.0.2.6'), IPAddress('::ffff:192.0.2.7'), ] def test_iprange_boolean_evaluation(): assert bool(IPRange('0.0.0.0', '255.255.255.255')) assert bool(IPRange('0.0.0.0', '0.0.0.0')) def test_iprange_sorting(): ranges = ( (IPAddress('::'), IPAddress('::')), (IPAddress('0.0.0.0'), IPAddress('255.255.255.255')), (IPAddress('::'), IPAddress('::255.255.255.255')), (IPAddress('0.0.0.0'), IPAddress('0.0.0.0')), ) assert sorted(ranges) == [ (IPAddress('0.0.0.0'), IPAddress('0.0.0.0')), (IPAddress('0.0.0.0'), IPAddress('255.255.255.255')), (IPAddress('::'), IPAddress('::')), (IPAddress('::'), IPAddress('::255.255.255.255')), ] def test_iprange_constructor(): iprange = IPRange('192.0.2.1', '192.0.2.254') assert iprange == IPRange('192.0.2.1', '192.0.2.254') assert '%s' % iprange == '192.0.2.1-192.0.2.254' assert IPRange('::ffff:192.0.2.1', '::ffff:192.0.2.254') == IPRange('::ffff:192.0.2.1', '::ffff:192.0.2.254') assert IPRange('192.0.2.1', '192.0.2.1') == IPRange('192.0.2.1', '192.0.2.1') assert IPRange('208.049.164.000', '208.050.066.255', flags=ZEROFILL) == IPRange('208.49.164.0', '208.50.66.255') with pytest.raises(AddrFormatError): IPRange('192.0.2.2', '192.0.2.1') with pytest.raises(AddrFormatError): IPRange('::', '0.0.0.1') with pytest.raises(AddrFormatError): IPRange('0.0.0.0', '::1') def test_iprange_indexing(): iprange = IPRange('192.0.2.1', '192.0.2.254') assert len(iprange) == 254 assert iprange.first == 3221225985 assert iprange.last == 3221226238 assert iprange[0] == IPAddress('192.0.2.1') assert iprange[-1] == IPAddress('192.0.2.254') with pytest.raises(IndexError): iprange[512] def test_iprange_slicing(): iprange = IPRange('192.0.2.1', '192.0.2.254') assert list(iprange[0:3]) == [ IPAddress('192.0.2.1'), IPAddress('192.0.2.2'), IPAddress('192.0.2.3'), ] assert list(iprange[0:10:2]) == [ IPAddress('192.0.2.1'), IPAddress('192.0.2.3'), IPAddress('192.0.2.5'), IPAddress('192.0.2.7'), IPAddress('192.0.2.9'), ] assert list(iprange[0:1024:512]) == [IPAddress('192.0.2.1')] def test_iprange_ipv6_unsupported_slicing(): with pytest.raises(TypeError): IPRange('::ffff:192.0.2.1', '::ffff:192.0.2.254')[0:10:2] def test_iprange_membership(): assert IPRange('192.0.2.5', '192.0.2.10') in IPRange('192.0.2.1', '192.0.2.254') assert IPRange('fe80::1', 'fe80::fffe') in IPRange('fe80::', 'fe80::ffff:ffff:ffff:ffff') assert IPRange('192.0.2.5', '192.0.2.10') not in IPRange('::', '::255.255.255.255') def test_more_iprange_sorting(): ipranges = (IPRange('192.0.2.40', '192.0.2.50'), IPRange('192.0.2.20', '192.0.2.30'), IPRange('192.0.2.1', '192.0.2.254'),) assert sorted(ipranges) == [IPRange('192.0.2.1', '192.0.2.254'), IPRange('192.0.2.20', '192.0.2.30'), IPRange('192.0.2.40', '192.0.2.50')] ipranges = list(ipranges) ipranges.append(IPRange('192.0.2.45', '192.0.2.49')) assert sorted(ipranges) == [ IPRange('192.0.2.1', '192.0.2.254'), IPRange('192.0.2.20', '192.0.2.30'), IPRange('192.0.2.40', '192.0.2.50'), IPRange('192.0.2.45', '192.0.2.49'), ] def test_iprange_cidr_interoperability(): assert IPRange('192.0.2.5', '192.0.2.10').cidrs() == [ IPNetwork('192.0.2.5/32'), IPNetwork('192.0.2.6/31'), IPNetwork('192.0.2.8/31'), IPNetwork('192.0.2.10/32'), ] assert IPRange('fe80::', 'fe80::ffff:ffff:ffff:ffff').cidrs() == [IPNetwork('fe80::/64')] def test_iprange_info_and_properties(): iprange = IPRange('192.0.2.1', '192.0.2.254') assert literal_eval(str(iprange.info)) == { 'IPv4': [{ 'date': '1993-05', 'designation': 'Administered by ARIN', 'prefix': '192/8', 'status': 'Legacy', 'whois': 'whois.arin.net'}] } assert iprange.is_reserved() assert iprange.version == 4 def test_iprange_invalid_len_and_alternative(): range1 = IPRange(IPAddress("::0"), IPAddress(_sys_maxint, 6)) with pytest.raises(IndexError): len(range1) range2 = IPRange(IPAddress("::0"), IPAddress(_sys_maxint - 1, 6)) assert len(range2) == _sys_maxint def test_iprange_pickling_v4(): iprange = IPRange('192.0.2.1', '192.0.2.254') assert iprange == IPRange('192.0.2.1', '192.0.2.254') assert iprange.first == 3221225985 assert iprange.last == 3221226238 assert iprange.version == 4 buf = pickle.dumps(iprange) iprange2 = pickle.loads(buf) assert iprange2 == iprange assert id(iprange2) != id(iprange) assert iprange2.first == 3221225985 assert iprange2.last == 3221226238 assert iprange2.version == 4 def test_iprange_pickling_v6(): iprange = IPRange('::ffff:192.0.2.1', '::ffff:192.0.2.254') assert iprange == IPRange('::ffff:192.0.2.1', '::ffff:192.0.2.254') assert iprange.first == 281473902969345 assert iprange.last == 281473902969598 assert iprange.version == 6 buf = pickle.dumps(iprange) iprange2 = pickle.loads(buf) assert iprange2 == iprange assert iprange2.first == 281473902969345 assert iprange2.last == 281473902969598 assert iprange2.version == 6