From 31737ace97c3b614adb66a228157e20a43e31054 Mon Sep 17 00:00:00 2001 From: Martin Pool Date: Tue, 10 Sep 2002 08:36:55 +0000 Subject: [PATCH] Check in examples for tdb packer (This used to be commit e8f9fbd32b73f60db3683d23a979dc09e7204258) --- .../python/examples/tdbpack/tdbtimetrial.py | 12 ++ .../python/examples/tdbpack/test_tdbpack.py | 195 ++++++++++++++++++ 2 files changed, 207 insertions(+) create mode 100755 source3/python/examples/tdbpack/tdbtimetrial.py create mode 100755 source3/python/examples/tdbpack/test_tdbpack.py diff --git a/source3/python/examples/tdbpack/tdbtimetrial.py b/source3/python/examples/tdbpack/tdbtimetrial.py new file mode 100755 index 00000000000..be6404899d8 --- /dev/null +++ b/source3/python/examples/tdbpack/tdbtimetrial.py @@ -0,0 +1,12 @@ +#! /usr/bin/python2.2 + +def run_trial(): + # import tdbutil + from samba.tdbpack import pack + + for i in xrange(500000): + pack("ddffd", (10, 2, "mbp", "martin", 0)) + #s = "\n\0\0\0" + "\x02\0\0\0" + "mbp\0" + "martin\0" + "\0\0\0\0" + +if __name__ == '__main__': + run_trial() diff --git a/source3/python/examples/tdbpack/test_tdbpack.py b/source3/python/examples/tdbpack/test_tdbpack.py new file mode 100755 index 00000000000..36fed881e33 --- /dev/null +++ b/source3/python/examples/tdbpack/test_tdbpack.py @@ -0,0 +1,195 @@ +#! /usr/bin/env python2.2 + +__doc__ = """test case for samba.tdbkpack functions + +tdbpack provides a means of pickling values into binary formats +compatible with that used by the samba tdbpack()/tdbunpack() +functions. + +Numbers are always stored in little-endian format; strings are stored +in either DOS or Unix codepage as appropriate. + +The format for any particular element is encoded as a short ASCII +string, with one character per field.""" + +# Copyright (C) 2002 Hewlett-Packard. + +__author__ = 'Martin Pool ' + +import unittest +# import tdbutil +import samba.tdbpack + +packer = samba.tdbpack.pack +unpacker = samba.tdbpack.unpack + + +class PackTests(unittest.TestCase): + symm_cases = [('B', ['hello' * 51], '\xff\0\0\0' + 'hello' * 51), + ('w', [42], '\x2a\0'), + ('www', [42, 2, 69], '\x2a\0\x02\0\x45\0'), + ('wd', [42, 256], '\x2a\0\0\x01\0\0'), + ('w', [0], '\0\0'), + ('w', [255], '\xff\0'), + ('w', [256], '\0\x01'), + ('w', [0xdead], '\xad\xde'), + ('w', [0xffff], '\xff\xff'), + ('p', [0], '\0\0\0\0'), + ('p', [1], '\x01\0\0\0'), + ('d', [0x01020304], '\x04\x03\x02\x01'), + ('d', [0x7fffffff], '\xff\xff\xff\x7f'), + ('d', [0x80000000], '\x00\x00\x00\x80'), + ('d', [-1], '\xff\xff\xff\xff'), + ('d', [-255], '\x01\xff\xff\xff'), + ('d', [-256], '\x00\xff\xff\xff'), + ('ddd', [1, 10, 50], '\x01\0\0\0\x0a\0\0\0\x32\0\0\0'), + ('ff', ['hello', 'world'], 'hello\0world\0'), + ('fP', ['hello', 'world'], 'hello\0world\0'), + ('PP', ['hello', 'world'], 'hello\0world\0'), + ('B', [''], '\0\0\0\0'), + ('B', ['hello'], '\x05\0\0\0hello'), + ('BB', ['hello\0world', 'now'], + '\x0b\0\0\0hello\0world\x03\0\0\0now'), + ('pd', [1, 10], '\x01\0\0\0\x0a\0\0\0'), + ('BBB', ['hello', '', 'world'], + '\x05\0\0\0hello\0\0\0\0\x05\0\0\0world'), + + # strings are sequences in Python, there's no getting away + # from it + ('ffff', 'evil', 'e\0v\0i\0l\0'), + ('BBBB', 'evil', + '\x01\0\0\0e' + '\x01\0\0\0v' + '\x01\0\0\0i' + '\x01\0\0\0l'), + + ('', [], ''), + + # exercise some long strings + ('PP', ['hello' * 255, 'world' * 255], + 'hello' * 255 + '\0' + 'world' * 255 + '\0'), + ('PP', ['hello' * 40000, 'world' * 50000], + 'hello' * 40000 + '\0' + 'world' * 50000 + '\0'), + ('B', ['hello' * 51], '\xff\0\0\0' + 'hello' * 51), + ('BB', ['hello' * 40000, 'world' * 50000], + '\x40\x0d\x03\0' + 'hello' * 40000 + '\x90\xd0\x03\x00' + 'world' * 50000), + ] + + def test_symmetric(self): + """Cookbook of symmetric pack/unpack tests + """ + for format, values, expected in self.symm_cases: + self.assertEquals(packer(format, values), expected) + out, rest = unpacker(format, expected) + self.assertEquals(rest, '') + self.assertEquals(list(values), list(out)) + + + def test_pack(self): + """Cookbook of expected pack values + + These can't be used for the symmetric test because the unpacked value is + not "canonical". + """ + cases = [('w', (42,), '\x2a\0'), + ('p', [None], '\0\0\0\0'), + ('p', ['true'], '\x01\0\0\0'), + + ('w', {1: 'fruit'}, '\x01\0'), + # passing a dictionary is dodgy, but it gets coerced to keys + # as if you called list() + ] + + for format, values, expected in cases: + self.assertEquals(packer(format, values), expected) + + def test_unpack_extra(self): + # Test leftover data + for format, values, packed in self.symm_cases: + out, rest = unpacker(format, packed + 'hello sailor!') + self.assertEquals(rest, 'hello sailor!') + self.assertEquals(list(values), list(out)) + + + def test_unpack(self): + """Cookbook of tricky unpack tests""" + cases = [ + ] + for format, values, expected in cases: + out, rest = unpacker(format, expected) + self.assertEquals(rest, '') + self.assertEquals(list(values), list(out)) + + + def test_pack_failures(self): + """Expected errors for incorrect packing""" + cases = [('w', [], IndexError), + ('w', (), IndexError), + ('w', {}, IndexError), + ('ww', [2], IndexError), + ('w', 2, TypeError), + ('', [1, 2, 3], IndexError), + ('w', None, TypeError), + ('wwwwwwwwwwww', [], IndexError), + ('w', [2, 3], IndexError), + ('w', [0x60A15EC5L], TypeError), + ('w', [None], TypeError), + ('w', xrange(10000), IndexError), + ('d', [], IndexError), + ('d', [0L], TypeError), + ('p', [], IndexError), + ('f', [2], TypeError), + ('P', [None], TypeError), + ('P', (), IndexError), + ('f', [packer], TypeError), + ('fw', ['hello'], IndexError), + ('f', [u'hello'], TypeError), + ('B', [2], TypeError), + (None, [2, 3, 4], TypeError), + (ord('f'), [20], TypeError), + (['w', 'w'], [2, 2], TypeError), + ('Q', [2], ValueError), + ('fQ', ['2', 3], ValueError), + ('fQ', ['2'], IndexError), + (2, [2], TypeError), + ({}, {}, TypeError)] + for format, values, throwable_class in cases: + def do_pack(): + packer(format, values) + self.assertRaises(throwable_class, do_pack) + + + def test_unpack_failures(self): + """Expected errors for incorrect unpacking""" + cases = [('$', '', ValueError), + ('Q', '', ValueError), + ('Q$', '', ValueError), + ('f', '', IndexError), + ('d', '', IndexError), + ('d', '2', IndexError), + ('d', '22', IndexError), + ('d', '222', IndexError), + ('w', '', IndexError), + ('w', '2', IndexError), + ('f', 'hello', IndexError), + ('f', '', IndexError), + ('p', '\x01\0', IndexError), + ('B', '\xff\0\0\0hello', IndexError), + ('B', '\xff\0', IndexError), + ('B', '\x01\0\0\0', IndexError), + ('B', '\x05\0\0\0hell', IndexError), + ('B', '\xff\xff\xff\xff', ValueError), + ('B', 'foobar', IndexError), + ('BB', '\x01\0\0\0a\x01', IndexError), + ] + + for format, values, throwable_class in cases: + def do_unpack(): + unpacker(format, values) + self.assertRaises(throwable_class, do_unpack) + + + +if __name__ == '__main__': + unittest.main() + -- 2.34.1