import unittest import ip import random class TestIPParsing(unittest.TestCase): def gen_ipv4(self): a, b, c, d = [random.randint(0, 255), random.randint(0, 255), random.randint(0, 255), random.randint(0, 255)] match random.randint(0, 20): case 0: # merge 2 octets adr_str = "{}.{}.{}".format(a, b, (c << 8) + d) case 1: # merge 3 octets adr_str = "{}.{}".format(a, (b << 16) + (c << 8) + d) case 2: # fully degenerated address adr_str = "{}".format((a << 24) + (b << 16) + (c << 8) + d) case _: adr_str = "{}.{}.{}.{}".format(a, b, c, d) return adr_str, [a, b, c, d] def gen_ipv6(self): o = [] for j in range(random.randint(4, 8)): # 4 to 8 octets with data o += [random.randint(0, 65535)] split = 0 if len(o) < 8: # fill remaining octets with 0 split = random.randint(0, len(o)) # prepare string with ellipsis h = [hex(v)[2:] for v in o[:split]] h += [""] h += [hex(v)[2:] for v in o[split:]] # if the ellipsis is at the start (or end) of an address, we need an extra ":" if split == 0: h = [""] + h if split == len(o): h += [""] o = o[:split] + [0] * (8 - len(o)) + o[split:] else: # or without h = [hex(v)[2:] for v in o] # create address string from hex octets adr_str = ":".join(h) return adr_str, o def test_ipv4(self): ip_obj = ip.ip() print("\nIPv4 random cases") for i in range(100000): adr_str, octs = self.gen_ipv4() ip_obj._parseV4(adr_str) self.assertEqual(ip_obj.octets, octs) print("IPv4 failure cases") with self.assertRaises(Exception): ip_obj._parseV4("192.168.2.260") with self.assertRaises(Exception): ip_obj._parseV4("192.168.2.20.23") with self.assertRaises(Exception): ip_obj._parseV4("192.168.2.-20") with self.assertRaises(Exception): ip_obj._parseV4("192.168.ab.0") print("IPv4 ok") def test_ipv6(self): ip_obj = ip.ip() print("\nIPv6 random cases") for i in range(10000): adr_str, octs = self.gen_ipv6() ip_obj._parseV6(adr_str) self.assertEqual(ip_obj.octets, octs) print("IPv6 special cases") ip_obj._parseV6("::") self.assertEqual(ip_obj.octets, [0]*8) ip_obj._parseV6("1::") self.assertEqual(ip_obj.octets, [1]+[0]*7) ip_obj._parseV6("::1") self.assertEqual(ip_obj.octets, [0]*7+[1]) print("IPv6 failure cases") with self.assertRaises(Exception): ip_obj._parseV6("192.168.2.20") with self.assertRaises(Exception): ip_obj._parseV6("ff80:12::23::") with self.assertRaises(Exception): ip_obj._parseV6("1:2:3:4:5:6:7:8:9") with self.assertRaises(Exception): ip_obj._parseV6("ff::1ffff") with self.assertRaises(Exception): ip_obj._parseV6("1:2:3:4:5:6:7") with self.assertRaises(Exception): ip_obj._parseV6("1:2:3:4:5:6:7:") with self.assertRaises(Exception): ip_obj._parseV6("3159:df6c:d506:60c3:9640:") print("IPv6 ok") def test_mixed(self): ip_obj = ip.ip() print("\nmixed random parsing") for i in range(10000): if random.random() < 0.5: adr_str, octs = self.gen_ipv4() type = 0 else: adr_str, octs = self.gen_ipv6() type = 1 ip_obj.parseAdrString(adr_str) self.assertEqual(ip_obj.octets, octs) self.assertEqual(ip_obj.type, type) print("mixed ok") if __name__ == '__main__': unittest.main()