=IPSet Tests= Copyright (c) 2008-2012, David P. D. Moss. All rights reserved. {{{ >>> from netaddr import * }}} Basic operations. {{{ >>> IPSet() IPSet([]) >>> IPSet([]) IPSet([]) >>> IPSet(['192.0.2.0']) IPSet(['192.0.2.0/32']) >>> IPSet([IPAddress('192.0.2.0')]) IPSet(['192.0.2.0/32']) >>> IPSet([IPNetwork('192.0.2.0')]) IPSet(['192.0.2.0/32']) >>> IPSet([IPNetwork('192.0.2.0/24')]) IPSet(['192.0.2.0/24']) >>> for ip in IPSet(['192.0.2.0/28', '::192.0.2.0/124']): ... print(ip) 192.0.2.0 192.0.2.1 192.0.2.2 192.0.2.3 192.0.2.4 192.0.2.5 192.0.2.6 192.0.2.7 192.0.2.8 192.0.2.9 192.0.2.10 192.0.2.11 192.0.2.12 192.0.2.13 192.0.2.14 192.0.2.15 ::192.0.2.0 ::192.0.2.1 ::192.0.2.2 ::192.0.2.3 ::192.0.2.4 ::192.0.2.5 ::192.0.2.6 ::192.0.2.7 ::192.0.2.8 ::192.0.2.9 ::192.0.2.10 ::192.0.2.11 ::192.0.2.12 ::192.0.2.13 ::192.0.2.14 ::192.0.2.15 }}} Adding and removing elements. {{{ >>> s1 = IPSet() >>> s1.add('192.0.2.0') >>> s1 IPSet(['192.0.2.0/32']) >>> s1.remove('192.0.2.0') >>> s1 IPSet([]) >>> s1.remove('192.0.2.0') }}} Set membership. {{{ >>> iprange = IPRange('192.0.1.255', '192.0.2.16') >>> iprange.cidrs() [IPNetwork('192.0.1.255/32'), IPNetwork('192.0.2.0/28'), IPNetwork('192.0.2.16/32')] >>> ipset = IPSet(['192.0.2.0/28']) >>> for ip in iprange: ... print(ip, ip in ipset) 192.0.1.255 False 192.0.2.0 True 192.0.2.1 True 192.0.2.2 True 192.0.2.3 True 192.0.2.4 True 192.0.2.5 True 192.0.2.6 True 192.0.2.7 True 192.0.2.8 True 192.0.2.9 True 192.0.2.10 True 192.0.2.11 True 192.0.2.12 True 192.0.2.13 True 192.0.2.14 True 192.0.2.15 True 192.0.2.16 False }}} Set union. {{{ >>> IPSet(['192.0.2.0']) IPSet(['192.0.2.0/32']) >>> IPSet(['192.0.2.0']) | IPSet(['192.0.2.1']) IPSet(['192.0.2.0/31']) >>> IPSet(['192.0.2.0']) | IPSet(['192.0.2.1']) | IPSet(['192.0.2.3']) IPSet(['192.0.2.0/31', '192.0.2.3/32']) >>> IPSet(['192.0.2.0']) | IPSet(['192.0.2.1']) | IPSet(['192.0.2.3/30']) IPSet(['192.0.2.0/30']) >>> IPSet(['192.0.2.0']) | IPSet(['192.0.2.1']) | IPSet(['192.0.2.3/31']) IPSet(['192.0.2.0/30']) >>> IPSet(['192.0.2.0/24']) | IPSet(['192.0.3.0/24']) | IPSet(['192.0.4.0/24']) IPSet(['192.0.2.0/23', '192.0.4.0/24']) }}} A joined up example of the union, intersection and symmetric difference operations. {{{ >>> adj_cidrs = list(IPNetwork('192.0.2.0/24').subnet(28)) >>> even_cidrs = adj_cidrs[::2] >>> evens = IPSet(even_cidrs) >>> evens IPSet(['192.0.2.0/28', '192.0.2.32/28', '192.0.2.64/28', '192.0.2.96/28', '192.0.2.128/28', '192.0.2.160/28', '192.0.2.192/28', '192.0.2.224/28']) >>> IPSet(['192.0.2.0/24']) & evens IPSet(['192.0.2.0/28', '192.0.2.32/28', '192.0.2.64/28', '192.0.2.96/28', '192.0.2.128/28', '192.0.2.160/28', '192.0.2.192/28', '192.0.2.224/28']) >>> odds = IPSet(['192.0.2.0/24']) ^ evens >>> odds IPSet(['192.0.2.16/28', '192.0.2.48/28', '192.0.2.80/28', '192.0.2.112/28', '192.0.2.144/28', '192.0.2.176/28', '192.0.2.208/28', '192.0.2.240/28']) >>> evens | odds IPSet(['192.0.2.0/24']) >>> evens & odds IPSet([]) >>> evens ^ odds IPSet(['192.0.2.0/24']) }}} Superset and subset tests. {{{ >>> s1 = IPSet(['192.0.2.0/24', '192.0.4.0/24']) >>> s2 = IPSet(['192.0.2.0', '192.0.4.0']) >>> s1 IPSet(['192.0.2.0/24', '192.0.4.0/24']) >>> s2 IPSet(['192.0.2.0/32', '192.0.4.0/32']) >>> s1.issuperset(s2) True >>> s2.issubset(s1) True >>> s2.issuperset(s1) False >>> s1.issubset(s2) False }}} {{{ >>> ipv4_addr_space = IPSet(['0.0.0.0/0']) >>> private = IPSet(['10.0.0.0/8', '172.16.0.0/12', '192.0.2.0/24', '192.168.0.0/16', '239.192.0.0/14']) >>> reserved = IPSet(['225.0.0.0/8', '226.0.0.0/7', '228.0.0.0/6', '234.0.0.0/7', '236.0.0.0/7', '238.0.0.0/8', '240.0.0.0/4']) >>> unavailable = reserved | private >>> available = ipv4_addr_space ^ unavailable >>> for cidr in available.iter_cidrs(): ... print(cidr, cidr[0], cidr[-1]) 0.0.0.0/5 0.0.0.0 7.255.255.255 8.0.0.0/7 8.0.0.0 9.255.255.255 11.0.0.0/8 11.0.0.0 11.255.255.255 12.0.0.0/6 12.0.0.0 15.255.255.255 16.0.0.0/4 16.0.0.0 31.255.255.255 32.0.0.0/3 32.0.0.0 63.255.255.255 64.0.0.0/2 64.0.0.0 127.255.255.255 128.0.0.0/3 128.0.0.0 159.255.255.255 160.0.0.0/5 160.0.0.0 167.255.255.255 168.0.0.0/6 168.0.0.0 171.255.255.255 172.0.0.0/12 172.0.0.0 172.15.255.255 172.32.0.0/11 172.32.0.0 172.63.255.255 172.64.0.0/10 172.64.0.0 172.127.255.255 172.128.0.0/9 172.128.0.0 172.255.255.255 173.0.0.0/8 173.0.0.0 173.255.255.255 174.0.0.0/7 174.0.0.0 175.255.255.255 176.0.0.0/4 176.0.0.0 191.255.255.255 192.0.0.0/23 192.0.0.0 192.0.1.255 192.0.3.0/24 192.0.3.0 192.0.3.255 192.0.4.0/22 192.0.4.0 192.0.7.255 192.0.8.0/21 192.0.8.0 192.0.15.255 192.0.16.0/20 192.0.16.0 192.0.31.255 192.0.32.0/19 192.0.32.0 192.0.63.255 192.0.64.0/18 192.0.64.0 192.0.127.255 192.0.128.0/17 192.0.128.0 192.0.255.255 192.1.0.0/16 192.1.0.0 192.1.255.255 192.2.0.0/15 192.2.0.0 192.3.255.255 192.4.0.0/14 192.4.0.0 192.7.255.255 192.8.0.0/13 192.8.0.0 192.15.255.255 192.16.0.0/12 192.16.0.0 192.31.255.255 192.32.0.0/11 192.32.0.0 192.63.255.255 192.64.0.0/10 192.64.0.0 192.127.255.255 192.128.0.0/11 192.128.0.0 192.159.255.255 192.160.0.0/13 192.160.0.0 192.167.255.255 192.169.0.0/16 192.169.0.0 192.169.255.255 192.170.0.0/15 192.170.0.0 192.171.255.255 192.172.0.0/14 192.172.0.0 192.175.255.255 192.176.0.0/12 192.176.0.0 192.191.255.255 192.192.0.0/10 192.192.0.0 192.255.255.255 193.0.0.0/8 193.0.0.0 193.255.255.255 194.0.0.0/7 194.0.0.0 195.255.255.255 196.0.0.0/6 196.0.0.0 199.255.255.255 200.0.0.0/5 200.0.0.0 207.255.255.255 208.0.0.0/4 208.0.0.0 223.255.255.255 224.0.0.0/8 224.0.0.0 224.255.255.255 232.0.0.0/7 232.0.0.0 233.255.255.255 239.0.0.0/9 239.0.0.0 239.127.255.255 239.128.0.0/10 239.128.0.0 239.191.255.255 239.196.0.0/14 239.196.0.0 239.199.255.255 239.200.0.0/13 239.200.0.0 239.207.255.255 239.208.0.0/12 239.208.0.0 239.223.255.255 239.224.0.0/11 239.224.0.0 239.255.255.255 >>> ipv4_addr_space ^ available IPSet(['10.0.0.0/8', '172.16.0.0/12', '192.0.2.0/24', '192.168.0.0/16', '225.0.0.0/8', '226.0.0.0/7', '228.0.0.0/6', '234.0.0.0/7', '236.0.0.0/7', '238.0.0.0/8', '239.192.0.0/14', '240.0.0.0/4']) }}} ==Tests on combined IPv4 and IPv6 sets== {{{ >>> s1 = IPSet(['192.0.2.0', '::192.0.2.0', '192.0.2.2', '::192.0.2.2']) >>> s2 = IPSet(['192.0.2.2', '::192.0.2.2', '192.0.2.4', '::192.0.2.4']) >>> s1 IPSet(['192.0.2.0/32', '192.0.2.2/32', '::192.0.2.0/128', '::192.0.2.2/128']) >>> s2 IPSet(['192.0.2.2/32', '192.0.2.4/32', '::192.0.2.2/128', '::192.0.2.4/128']) }}} Set union. {{{ >>> s1 | s2 IPSet(['192.0.2.0/32', '192.0.2.2/32', '192.0.2.4/32', '::192.0.2.0/128', '::192.0.2.2/128', '::192.0.2.4/128']) }}} Set intersection. {{{ >>> s1 & s2 IPSet(['192.0.2.2/32', '::192.0.2.2/128']) }}} Set difference. {{{ >>> s1 - s2 IPSet(['192.0.2.0/32', '::192.0.2.0/128']) >>> s2 - s1 IPSet(['192.0.2.4/32', '::192.0.2.4/128']) }}} Symmetric set difference. {{{ >>> s1 ^ s2 IPSet(['192.0.2.0/32', '192.0.2.4/32', '::192.0.2.0/128', '::192.0.2.4/128']) }}} Disjointed sets. {{{ >>> s1 = IPSet(['192.0.2.0', '192.0.2.1', '192.0.2.2']) >>> s2 = IPSet(['192.0.2.2', '192.0.2.3', '192.0.2.4']) >>> s1 & s2 IPSet(['192.0.2.2/32']) >>> s1.isdisjoint(s2) False >>> s1 = IPSet(['192.0.2.0', '192.0.2.1']) >>> s2 = IPSet(['192.0.2.3', '192.0.2.4']) >>> s1 & s2 IPSet([]) >>> s1.isdisjoint(s2) True }}} Updating a set. {{{ >>> s1 = IPSet(['192.0.2.0/25']) >>> s1 IPSet(['192.0.2.0/25']) >>> s2 = IPSet(['192.0.2.128/25']) >>> s2 IPSet(['192.0.2.128/25']) >>> s1.update(s2) >>> s1 IPSet(['192.0.2.0/24']) >>> s1.update(['192.0.0.0/24', '192.0.1.0/24', '192.0.3.0/24']) >>> s1 IPSet(['192.0.0.0/22']) }}} Removing IP addresses from an IPSet. {{{ >>> s1 = IPSet(['0.0.0.0/0']) >>> s1 IPSet(['0.0.0.0/0']) >>> s1.remove('255.255.255.255') >>> s1 IPSet(['0.0.0.0/1', '128.0.0.0/2', ..., '255.255.255.252/31', '255.255.255.254/32']) >>> list(s1.iter_cidrs()) [IPNetwork('0.0.0.0/1'), IPNetwork('128.0.0.0/2'), ..., IPNetwork('255.255.255.252/31'), IPNetwork('255.255.255.254/32')] >>> len(list(s1.iter_cidrs())) 32 >>> list(s1.iter_cidrs()) == cidr_exclude('0.0.0.0/0', '255.255.255.255') True >>> s1.remove('0.0.0.0') >>> s1 IPSet(['0.0.0.1/32', '0.0.0.2/31', ..., '255.255.255.252/31', '255.255.255.254/32']) >>> len(list(s1.iter_cidrs())) 62 }}} Adding IP address to an IPSet. {{{ >>> s1.add('255.255.255.255') >>> s1 IPSet(['0.0.0.1/32', '0.0.0.2/31', ..., '64.0.0.0/2', '128.0.0.0/1']) >>> list(s1.iter_cidrs()) [IPNetwork('0.0.0.1/32'), IPNetwork('0.0.0.2/31'), ..., IPNetwork('64.0.0.0/2'), IPNetwork('128.0.0.0/1')] >>> len(list(s1.iter_cidrs())) 32 >>> s1.add('0.0.0.0') >>> s1 IPSet(['0.0.0.0/0']) }}} Pickling of IPSet objects {{{ >>> import pickle >>> ip_data = IPSet(['10.0.0.0/16', 'fe80::/64']) >>> buf = pickle.dumps(ip_data) >>> ip_data_unpickled = pickle.loads(buf) >>> ip_data == ip_data_unpickled True }}}