[GLUE] Rsync SAMBA_3_0 SVN r25598 in order to create the v3-0-test branch.
[Samba.git] / source / python / examples / tdbpack / test_tdbpack.py
blob837600f789e0dd4b0cd49827912b1108287edd4d
1 #! /usr/bin/env python2.2
3 __doc__ = """test case for samba.tdbpack functions
5 tdbpack provides a means of pickling values into binary formats
6 compatible with that used by the samba tdbpack()/tdbunpack()
7 functions.
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>'
19 import unittest
20 import oldtdbutil
21 import samba.tdbpack
23 both_unpackers = (samba.tdbpack.unpack, oldtdbutil.unpack)
24 both_packers = (samba.tdbpack.pack, oldtdbutil.pack)
28 # # ('B', [10, 'hello'], '\x0a\0\0\0hello'),
29 # ('BB', [11, 'hello\0world', 3, 'now'],
30 # '\x0b\0\0\0hello\0world\x03\0\0\0now'),
31 # ('pd', [1, 10], '\x01\0\0\0\x0a\0\0\0'),
32 # ('BBB', [5, 'hello', 0, '', 5, 'world'],
33 # '\x05\0\0\0hello\0\0\0\0\x05\0\0\0world'),
35 # strings are sequences in Python, there's no getting away
36 # from it
37 # ('ffff', 'evil', 'e\0v\0i\0l\0'),
38 # ('BBBB', 'evil',
39 # '\x01\0\0\0e'
40 # '\x01\0\0\0v'
41 # '\x01\0\0\0i'
42 # '\x01\0\0\0l'),
44 # ('', [], ''),
46 # # exercise some long strings
47 # ('PP', ['hello' * 255, 'world' * 255],
48 # 'hello' * 255 + '\0' + 'world' * 255 + '\0'),
49 # ('PP', ['hello' * 40000, 'world' * 50000],
50 # 'hello' * 40000 + '\0' + 'world' * 50000 + '\0'),
51 # ('B', [(5*51), 'hello' * 51], '\xff\0\0\0' + 'hello' * 51),
52 # ('BB', [(5 * 40000), 'hello' * 40000,
53 # (5 * 50000), 'world' * 50000],
54 # '\x40\x0d\x03\0' + 'hello' * 40000 + '\x90\xd0\x03\x00' + 'world' * 50000),
57 class PackTests(unittest.TestCase):
58 symm_cases = [
59 ('w', [42], '\x2a\0'),
60 ('www', [42, 2, 69], '\x2a\0\x02\0\x45\0'),
61 ('wd', [42, 256], '\x2a\0\0\x01\0\0'),
62 ('w', [0], '\0\0'),
63 ('w', [255], '\xff\0'),
64 ('w', [256], '\0\x01'),
65 ('w', [0xdead], '\xad\xde'),
66 ('w', [0xffff], '\xff\xff'),
67 ('p', [0], '\0\0\0\0'),
68 ('p', [1], '\x01\0\0\0'),
69 ('d', [0x01020304], '\x04\x03\x02\x01'),
70 ('d', [0x7fffffff], '\xff\xff\xff\x7f'),
71 ('d', [0x80000000L], '\x00\x00\x00\x80'),
72 ('d', [0x80000069L], '\x69\x00\x00\x80'),
73 ('d', [0xffffffffL], '\xff\xff\xff\xff'),
74 ('d', [0xffffff00L], '\x00\xff\xff\xff'),
75 ('ddd', [1, 10, 50], '\x01\0\0\0\x0a\0\0\0\x32\0\0\0'),
76 ('ff', ['hello', 'world'], 'hello\0world\0'),
77 ('fP', ['hello', 'world'], 'hello\0world\0'),
78 ('PP', ['hello', 'world'], 'hello\0world\0'),
79 ('B', [0, ''], '\0\0\0\0'),
80 # old implementation is wierd when string is not the right length
81 # ('B', [2, 'hello'], '\x0a\0\0\0hello'),
82 ('B', [5, 'hello'], '\x05\0\0\0hello'),
85 def test_symmetric(self):
86 """Cookbook of symmetric pack/unpack tests
87 """
88 for packer in [samba.tdbpack.pack]: # both_packers:
89 for unpacker in both_unpackers:
90 for format, values, expected in self.symm_cases:
91 out_packed = packer(format, values)
92 self.assertEquals(out_packed, expected)
93 out, rest = unpacker(format, expected)
94 self.assertEquals(rest, '')
95 self.assertEquals(list(values), list(out))
97 def test_large(self):
98 """Test large pack/unpack strings"""
99 large_cases = [('w' * 1000, xrange(1000)), ]
100 for packer in both_packers:
101 for unpacker in both_unpackers:
102 for format, values in large_cases:
103 packed = packer(format, values)
104 out, rest = unpacker(format, packed)
105 self.assertEquals(rest, '')
106 self.assertEquals(list(values), list(out))
109 def test_pack(self):
110 """Cookbook of expected pack values
112 These can't be used for the symmetric test because the unpacked value is
113 not "canonical".
115 cases = [('w', (42,), '\x2a\0'),
118 for packer in both_packers:
119 for format, values, expected in cases:
120 self.assertEquals(packer(format, values), expected)
122 def test_unpack_extra(self):
123 # Test leftover data
124 for unpacker in both_unpackers:
125 for format, values, packed in self.symm_cases:
126 out, rest = unpacker(format, packed + 'hello sailor!')
127 self.assertEquals(rest, 'hello sailor!')
128 self.assertEquals(list(values), list(out))
131 def test_pack_extra(self):
132 """Leftover values when packing"""
133 cases = [
134 ('d', [10, 20], [10]),
135 ('d', [10, 'hello'], [10]),
136 ('ff', ['hello', 'world', 'sailor'], ['hello', 'world']),
138 for unpacker in both_unpackers:
139 for packer in both_packers:
140 for format, values, chopped in cases:
141 bin = packer(format, values)
142 out, rest = unpacker(format, bin)
143 self.assertEquals(list(out), list(chopped))
144 self.assertEquals(rest, '')
147 def test_unpack(self):
148 """Cookbook of tricky unpack tests"""
149 cases = [
150 # Apparently I couldn't think of any tests that weren't
151 # symmetric :-/
153 for unpacker in both_unpackers:
154 for format, values, expected in cases:
155 out, rest = unpacker(format, expected)
156 self.assertEquals(rest, '')
157 self.assertEquals(list(values), list(out))
160 def test_pack_failures(self):
161 """Expected errors for incorrect packing"""
162 cases = [('w', []),
163 # ('w', ()),
164 # ('w', {}),
165 ('ww', [2]),
166 ('w', 2),
167 # ('w', None),
168 ('wwwwwwwwwwww', []),
169 # ('w', [0x60A15EC5L]),
170 # ('w', [None]),
171 ('d', []),
172 ('p', []),
173 ('f', [2]),
174 ('P', [None]),
175 ('P', ()),
176 ('f', [hex]),
177 ('fw', ['hello']),
178 # ('f', [u'hello']),
179 ('B', [2]),
180 (None, [2, 3, 4]),
181 (ord('f'), [20]),
182 # old code doesn't distinguish string from seq-of-char
183 # (['w', 'w'], [2, 2]),
184 # old code just ignores invalid characters
185 # ('Q', [2]),
186 # ('fQ', ['2', 3]),
187 # ('fQ', ['2']),
188 (2, [2]),
189 # old code doesn't typecheck format
190 # ({}, {})
192 for packer in both_packers:
193 for format, values in cases:
194 try:
195 packer(format, values)
196 except StandardError:
197 pass
198 else:
199 raise AssertionError("didn't get exception: format %s, values %s, packer %s"
200 % (`format`, `values`, `packer`))
203 def test_unpack_failures(self):
204 """Expected errors for incorrect unpacking"""
205 cases = [
206 # This ought to be illegal, but the old code doesn't prohibit it
207 # ('$', '', ValueError),
208 # ('Q', '', ValueError),
209 # ('Q$', '', ValueError),
210 ('f', '', IndexError),
211 ('d', '', IndexError),
212 # This is an illegal packing, but the old code doesn't trap
213 # ('d', '2', IndexError),
214 # ('d', '22', IndexError),
215 # ('d', '222', IndexError),
216 # ('p', '\x01\0', IndexError),
217 # ('w', '2', IndexError),
218 # ('B', '\xff\0\0\0hello', IndexError),
219 # ('B', '\xff\0', IndexError),
220 ('w', '', IndexError),
221 ('f', 'hello', IndexError),
222 ('f', '', IndexError),
223 # ('B', '\x01\0\0\0', IndexError),
224 # ('B', '\x05\0\0\0hell', IndexError),
225 ('B', '\xff\xff\xff\xff', ValueError),
226 # ('B', 'foobar', IndexError),
227 # ('BB', '\x01\0\0\0a\x01', IndexError),
230 for unpacker in both_unpackers:
231 for format, values, throwable_class in cases:
232 try:
233 unpacker(format, values)
234 except StandardError:
235 pass
236 else:
237 raise AssertionError("didn't get exception: format %s, values %s, unpacker %s"
238 % (`format`, `values`, `unpacker`))
240 def test_unpack_repeated(self):
241 cases = [(('df$',
242 '\x00\x00\x00\x00HP C LaserJet 4500-PS\x00Windows 4.0\x00\\print$\\WIN40\\0\\PSCRIPT.DRV\x00\\print$\\WIN40\\0\\PSCRIPT.DRV\x00\\print$\\WIN40\\0\\PSCRIPT.DRV\x00\\print$\\WIN40\\0\\PSCRIPT.HLP\x00\x00RAW\x00\\print$\\WIN40\\0\\readme.wri\x00\\print$\\WIN40\\0\\pscript.drv\x00\\print$\\WIN40\\0\\pscript.hlp\x00'),
243 ([0L, 'HP C LaserJet 4500-PS', 'Windows 4.0', '\\print$\\WIN40\\0\\PSCRIPT.DRV', '\\print$\\WIN40\\0\\PSCRIPT.DRV', '\\print$\\WIN40\\0\\PSCRIPT.DRV', '\\print$\\WIN40\\0\\PSCRIPT.HLP', '', 'RAW', '\\print$\\WIN40\\0\\readme.wri', '\\print$\\WIN40\\0\\pscript.drv', '\\print$\\WIN40\\0\\pscript.hlp'], ''))]
244 for unpacker in both_unpackers:
245 for input, expected in cases:
246 result = apply(unpacker, input)
247 if result != expected:
248 raise AssertionError("%s:\n input: %s\n output: %s\n expected: %s" % (`unpacker`, `input`, `result`, `expected`))
251 if __name__ == '__main__':
252 unittest.main()