Add some test cases for better unit test code coverage. Fix bug found by new TestCom...
[python-rwhoisd.git] / test / TestCidr.py
1 # This file is part of python-rwhoisd
2 #
3 # Copyright (C) 2008 David E. Blacka
4 #
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 # General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
18 # USA
19
20
21 import path
22 import Cidr, socket
23 import unittest, types
24
25 class CreateCidrTest(unittest.TestCase):
26     """Test basic creation of Cidr objects."""
27
28     known_good_v4_cidr = [ ("127.00.000.1/24",      0x7F000000, 0xFFFFFF00),
29                            (("127.0.0.1", 32),      0x7F000001, 0xFFFFFFFF),
30                            (("24.232.119.192", 26), 0x18E877C0, 0xFFFFFFC0),
31                            (("24.232.119.0", 24),   0x18E87700, 0xFFFFFF00),
32                            (("24.224.0.0", 11),     0x18E00000, 0xFFE00000),
33                            ("216.168.111.0/27",     0xD8A86F00, 0xFFFFFFE0),
34                            ("127.0.0.2/31",         0x7F000002, 0xFFFFFFFE),
35                            ("127.0.0.16/32",        0x7F000010, 0xFFFFFFFF) ]
36
37
38     def testCreateV4(self):
39         """createV4 should give known results with known input."""
40         for args, value, mask in self.known_good_v4_cidr:
41             if type(args) == types.TupleType:
42                 cidr = Cidr.CidrV4(args[0], args[1])
43             else:
44                 cidr = Cidr.CidrV4(args)
45             self.assertEquals(cidr.numaddr, value)
46             self.assertEquals(cidr.mask, mask)
47
48
49     known_good_v6_cidr = [ ("3ffe:4:201e:beef::0/64",
50                             0x3FFE0004201EBEEF0000000000000000L,
51                             0xFFFFFFFFFFFFFFFF0000000000000000L),
52                            ("2001:3c01::/32",
53                             0x20013C01000000000000000000000000L,
54                             0xFFFFFFFF000000000000000000000000L),
55                            (("3ffe:b03d:fc1e::2002:1010:deaC", 126),
56                             0x3FFEB03DFC1E0000000020021010DEACL,
57                             0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCL),
58                            ("3ffe:b03d:fc1e:2002:1010:2a2a:7:1",
59                             0x3FFEB03dFC1E200210102A2A00070001L,
60                             0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFL),
61                            ("3ffe:b03d:fc1e:2002:1010:2a2a:7:1/32",
62                             0x3FFEB03D000000000000000000000000L,
63                             0xFFFFFFFF000000000000000000000000L),
64                            ("3ffe:b03d::affd:127.0.0.1",
65                             0x3FFEB03D000000000000AFFD7F000001L,
66                             0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFL)]
67
68     def testCreateV6(self):
69         "createV6 should give known results with known input."""
70         for args, value, mask in self.known_good_v6_cidr:
71             if type(args) == types.TupleType:
72                 cidr = Cidr.CidrV6(args[0], args[1])
73             else:
74                 cidr = Cidr.CidrV6(args)
75             self.assertEquals(cidr.numaddr, value)
76             self.assertEquals(cidr.mask, mask)
77
78     def testCreate(self):
79         """create should give known results with known input."""
80         all_good = self.known_good_v4_cidr + self.known_good_v6_cidr
81         for args, value, mask in all_good:
82             if type(args) == types.TupleType:
83                 cidr = Cidr.new(args[0], args[1])
84             else:
85                 cidr = Cidr.new(args)
86             self.assertEquals(cidr.numaddr, value)
87             self.assertEquals(cidr.mask, mask)
88
89     def testClone(self):
90         cidr1 = Cidr.new("127.0.0.0/32")
91         cidr2 = cidr1.clone()
92         self.assertEquals(cidr1, cidr2)
93
94     known_bad_v4_cidr = [ ("24.261.119.0", 32), # 2nd octet too large
95                           "",                   # empty string
96                           "22.a.231.11/24",     # contains alpha
97                           "45.61.22.230.1/32",  # too many octets
98                           "70.140.81.0/34",     # length too long
99                           "3ffe:3c01:4::1/32"   # ipv6
100                           ]
101
102     def testCreateBadV4(self):
103         for c in self.known_bad_v4_cidr:
104             if type(c) == types.TupleType:
105                 self.assertRaises(socket.error, Cidr.CidrV4, c[0], c[1])
106             else:
107                 self.assertRaises(socket.error, Cidr.CidrV4, c)
108
109     known_bad_v6_cidr = [
110         ":/32",
111         ":::/64",
112         "1::2::3",
113         "::3::/128",
114         "12345::1",
115         "2001:100g::1/64",
116         "1:2:3:4:5:6:7:4.3.2.1",
117         "127.0.0.1/24"
118         ]
119
120     def testCreateBadV6(self):
121         for c in self.known_bad_v6_cidr:
122             self.assertRaises(socket.error, Cidr.CidrV6, c)
123
124     def testValidCidr(self):
125         for c in [ x[0] for x in self.known_good_v4_cidr ]:
126             if type(c) == types.TupleType:
127                 c = "%s/%d" % (c[0], c[1])
128             res = Cidr.valid_cidr(c)
129             self.assert_(isinstance(res, Cidr.Cidr))
130         for c in [ x[0] for x in self.known_good_v6_cidr ]:
131             if type(c) == types.TupleType:
132                 c = "%s/%d" % (c[0], c[1])
133             res = Cidr.valid_cidr(c)
134             self.assert_(isinstance(res, Cidr.Cidr))
135         for c in self.known_bad_v4_cidr:
136             if type(c) == types.TupleType:
137                 c = "%s/%d" % (c[0], c[1])
138             if ':' in c:
139                 continue
140             res = Cidr.valid_cidr(c)
141             self.assertEquals(res, False)
142         for c in self.known_bad_v6_cidr:
143             res = Cidr.valid_cidr(c)
144             if not ':' in c:
145                 continue
146             self.failIf(res)
147
148 class TestCidrMethods(unittest.TestCase):
149
150     data = [ "127.0.0.0/24", "127.0.0.1/32", "24.232.119.192/26",
151              "24.232.119.0/24", "24.224.0.0/11", "216.168.111.0/27",
152              "127.0.0.2/31", "127.0.0.16/32", "3ffe:4:201e:beef::/64",
153              "2001:3c01::/32", "3ffe:b03d:fc1e::2002:1010:deac/128",
154              "3ffe:b03d:fc1e:2002:1010:2a2a:7:1/128",
155              "3ffe:b03d::/32" ]
156
157     def teststr(self):
158         for a in self.data:
159             c = Cidr.valid_cidr(a)
160             self.assert_(c)
161             self.assertEquals(a, str(c))
162
163     def testrepr(self):
164         for a in self.data:
165             c = Cidr.valid_cidr(a)
166             self.assert_(c)
167             self.assertEquals("<" + a + ">", repr(c))
168
169     def testcmp(self):
170         a = Cidr.valid_cidr("127.0.0.0/24")
171         b = Cidr.valid_cidr("127.0.0.0/23")
172         self.assert_(a)
173         self.assert_(b)
174         self.assert_(a > b)
175         self.assert_(b < a)
176         c = Cidr.valid_cidr("127.0.0.100/24")
177         self.assert_(c)
178         self.assert_(a == c)
179         b.netlen = 24
180         b.calc()
181         self.assert_(b == a)
182         self.assertEquals(a.netmask(), "255.255.255.0")
183         self.assertEquals(a.length(), 256)
184         self.assertEquals(a.end(), "127.0.0.255")
185
186 class TestCidrSort(unittest.TestCase):
187
188     unsorted_list = [ "127.0.0.0/24",
189                       "127.0.0.0/23",
190                       "127.0.0.0/25",
191                       "80.32.23.71/32",
192                       "8.44.55.66/8",
193                       "2001:2c01::1/64",
194                       "3ffe:4::5",
195                       "1:2:3:4:5:6:7:8/127" ]
196     sorted_list = [ "8.44.55.66/8",
197                     "80.32.23.71/32",
198                     "127.0.0.0/23",
199                     "127.0.0.0/24",
200                     "127.0.0.0/25",
201                     "1:2:3:4:5:6:7:8/127",
202                     "2001:2c01::1/64",
203                     "3ffe:4::5" ]
204
205     def setUp(self):
206         self.unsorted_list = [ Cidr.new(x) for x in self.unsorted_list ]
207         self.sorted_list = [ Cidr.new(x) for x in self.sorted_list ]
208
209     def testSort(self):
210         self.unsorted_list.sort()
211         self.assertEquals(self.unsorted_list, self.sorted_list)
212
213
214 class TestCidrScope(unittest.TestCase):
215
216     def testScope(self):
217         data = [ ("127.0.0.1/24", "127.0.0.15/25"),
218                  ("127.0.0.0/23", "127.0.0.0/24"),
219                  ("224.45.0.0/16", "224.45.126.87"),
220                  ("0.0.0.0/0", "1.2.3.4/32"),
221                  ("2001:23c1::0/32", "2001:23c1:45:ffff::0/64"),
222                  ("2001:23c1::0/32", "2001:23c1::0/33") ]
223
224         for a, b in data:
225             a = Cidr.valid_cidr(a)
226             b = Cidr.valid_cidr(b)
227             self.assert_(a.is_supernet(b))
228             self.assert_(b.is_subnet(a))
229
230 class testNetblockConversion(unittest.TestCase):
231
232     data = [ ("192.168.10.0", "192.168.10.255", 256),
233              ("192.168.10.0", "192.168.10.63", 64),
234              ("172.16.0.0", "172.16.127.255", 32768),
235              ("24.33.41.22", "24.33.41.37", 16),
236              ("196.11.1.0", "196.11.30.255", 7680),
237              ("192.247.1.0", "192.247.10.255", 2560),
238              ("10.131.43.4", "10.131.44.7", 260),
239              ("3ffe:4:5::", "3ffe:4:5::ffff", 65536),
240              ("3ffe:4:5::", "3ffe:4:6::1", 1208925819614629174706178L) ]
241
242     def blocks_to_length(self, blocks):
243         l = 0;
244         for b in blocks:
245             l += b.length()
246         return l
247
248     def blocks_to_netblock(self, blocks):
249         start = blocks[0].to_netblock()[0]
250         end = blocks[-1].to_netblock()[1]
251         return (start, end)
252
253     def testNetblocks(self):
254         for start, end, length in self.data:
255             blocks = Cidr.netblock_to_cidr(start, end)
256             l = self.blocks_to_length(blocks)
257             self.assertEquals(l, length)
258             s, e = self.blocks_to_netblock(blocks)
259             self.assertEquals(start, s)
260             self.assertEquals(end, e)
261
262     def testBadnetblock(self):
263         res = Cidr.netblock_to_cidr("127.0.0.257", "127.0.0.10.0")
264         assert(res == None)
265         res = Cidr.netblock_to_cidr("127.0.0.1", "127.0.256.255")
266         assert(res == None)
267         res = Cidr.netblock_to_cidr("::1", "127.0.0.2")
268         assert(res == None)
269
270
271 if __name__ == "__main__":
272     unittest.main()