1 #! /usr/bin/env python2.2
3 __doc__ = """test case for samba.tdbkpack functions
5 tdbpack provides a means of pickling values into binary formats
6 compatible with that used by the samba tdbpack()/tdbunpack()
9 Numbers are always stored in little-endian format; strings are stored
10 in either DOS or Unix codepage as appropriate.
12 The format for any particular element is encoded as a short ASCII
13 string, with one character per field."""
15 # Copyright (C) 2002 Hewlett-Packard.
17 __author__ = 'Martin Pool <mbp@sourcefrog.net>'
23 both_unpackers = (samba.tdbpack.unpack, oldtdbutil.unpack)
24 both_packers = (samba.tdbpack.pack, oldtdbutil.pack)
26 class PackTests(unittest.TestCase):
27 symm_cases = [('B', ['hello' * 51], '\xff\0\0\0' + 'hello' * 51),
28 ('w', [42], '\x2a\0'),
29 ('www', [42, 2, 69], '\x2a\0\x02\0\x45\0'),
30 ('wd', [42, 256], '\x2a\0\0\x01\0\0'),
32 ('w', [255], '\xff\0'),
33 ('w', [256], '\0\x01'),
34 ('w', [0xdead], '\xad\xde'),
35 ('w', [0xffff], '\xff\xff'),
36 ('p', [0], '\0\0\0\0'),
37 ('p', [1], '\x01\0\0\0'),
38 ('d', [0x01020304], '\x04\x03\x02\x01'),
39 ('d', [0x7fffffff], '\xff\xff\xff\x7f'),
40 ('d', [0x80000000], '\x00\x00\x00\x80'),
41 ('d', [-1], '\xff\xff\xff\xff'),
42 ('d', [-255], '\x01\xff\xff\xff'),
43 ('d', [-256], '\x00\xff\xff\xff'),
44 ('ddd', [1, 10, 50], '\x01\0\0\0\x0a\0\0\0\x32\0\0\0'),
45 ('ff', ['hello', 'world'], 'hello\0world\0'),
46 ('fP', ['hello', 'world'], 'hello\0world\0'),
47 ('PP', ['hello', 'world'], 'hello\0world\0'),
48 ('B', [''], '\0\0\0\0'),
49 ('B', ['hello'], '\x05\0\0\0hello'),
50 ('BB', ['hello\0world', 'now'],
51 '\x0b\0\0\0hello\0world\x03\0\0\0now'),
52 ('pd', [1, 10], '\x01\0\0\0\x0a\0\0\0'),
53 ('BBB', ['hello', '', 'world'],
54 '\x05\0\0\0hello\0\0\0\0\x05\0\0\0world'),
56 # strings are sequences in Python, there's no getting away
58 ('ffff', 'evil', 'e\0v\0i\0l\0'),
67 # exercise some long strings
68 ('PP', ['hello' * 255, 'world' * 255],
69 'hello' * 255 + '\0' + 'world' * 255 + '\0'),
70 ('PP', ['hello' * 40000, 'world' * 50000],
71 'hello' * 40000 + '\0' + 'world' * 50000 + '\0'),
72 ('B', ['hello' * 51], '\xff\0\0\0' + 'hello' * 51),
73 ('BB', ['hello' * 40000, 'world' * 50000],
74 '\x40\x0d\x03\0' + 'hello' * 40000 + '\x90\xd0\x03\x00' + 'world' * 50000),
77 def test_symmetric(self):
78 """Cookbook of symmetric pack/unpack tests
80 for packer in both_packers:
81 for unpacker in both_unpackers:
82 for format, values, expected in self.symm_cases:
83 self.assertEquals(packer(format, values), expected)
84 out, rest = unpacker(format, expected)
85 self.assertEquals(rest, '')
86 self.assertEquals(list(values), list(out))
90 """Cookbook of expected pack values
92 These can't be used for the symmetric test because the unpacked value is
95 cases = [('w', (42,), '\x2a\0'),
96 ('p', [None], '\0\0\0\0'),
97 ('p', ['true'], '\x01\0\0\0'),
100 for packer in both_packers:
101 for format, values, expected in cases:
102 self.assertEquals(packer(format, values), expected)
104 def test_unpack_extra(self):
106 for unpacker in both_unpackers:
107 for format, values, packed in self.symm_cases:
108 out, rest = unpacker(format, packed + 'hello sailor!')
109 self.assertEquals(rest, 'hello sailor!')
110 self.assertEquals(list(values), list(out))
113 def test_unpack(self):
114 """Cookbook of tricky unpack tests"""
116 # Apparently I couldn't think of any tests that weren't
119 for unpacker in both_unpackers:
120 for format, values, expected in cases:
121 out, rest = unpacker(format, expected)
122 self.assertEquals(rest, '')
123 self.assertEquals(list(values), list(out))
126 def test_pack_failures(self):
127 """Expected errors for incorrect packing"""
135 ('wwwwwwwwwwww', []),
137 ('w', [0x60A15EC5L]),
139 ('w', xrange(10000)),
152 (['w', 'w'], [2, 2]),
158 for packer in both_packers:
159 for format, values in cases:
161 packer(format, values)
162 except StandardError:
165 raise AssertionError("didn't get exception: format %s, values %s, packer %s"
166 % (`format`, `values`, `packer`))
169 def test_unpack_failures(self):
170 """Expected errors for incorrect unpacking"""
171 cases = [('$', '', ValueError),
172 ('Q', '', ValueError),
173 ('Q$', '', ValueError),
174 ('f', '', IndexError),
175 ('d', '', IndexError),
176 ('d', '2', IndexError),
177 ('d', '22', IndexError),
178 ('d', '222', IndexError),
179 ('w', '', IndexError),
180 ('w', '2', IndexError),
181 ('f', 'hello', IndexError),
182 ('f', '', IndexError),
183 ('p', '\x01\0', IndexError),
184 ('B', '\xff\0\0\0hello', IndexError),
185 ('B', '\xff\0', IndexError),
186 ('B', '\x01\0\0\0', IndexError),
187 ('B', '\x05\0\0\0hell', IndexError),
188 ('B', '\xff\xff\xff\xff', ValueError),
189 ('B', 'foobar', IndexError),
190 ('BB', '\x01\0\0\0a\x01', IndexError),
193 for unpacker in both_unpackers:
194 for format, values, throwable_class in cases:
196 unpacker(format, values)
197 self.assertRaises(throwable_class, do_unpack)
201 if __name__ == '__main__':