1import unittest
2import os
3from test.test_support import TESTFN, run_unittest, unlink, import_module
4gdbm = import_module('gdbm')
5
6
7filename = TESTFN
8
9class TestGdbm(unittest.TestCase):
10
11    def setUp(self):
12        self.g = None
13
14    def tearDown(self):
15        if self.g is not None:
16            self.g.close()
17        unlink(filename)
18
19    def test_key_methods(self):
20        self.g = gdbm.open(filename, 'c')
21        self.assertEqual(self.g.keys(), [])
22        self.g['a'] = 'b'
23        self.g['12345678910'] = '019237410982340912840198242'
24        key_set = set(self.g.keys())
25        self.assertEqual(key_set, frozenset(['a', '12345678910']))
26        self.assertTrue(self.g.has_key('a'))
27        key = self.g.firstkey()
28        while key:
29            self.assertIn(key, key_set)
30            key_set.remove(key)
31            key = self.g.nextkey(key)
32        self.assertRaises(KeyError, lambda: self.g['xxx'])
33
34    def test_error_conditions(self):
35        # Try to open a non-existent database.
36        unlink(filename)
37        self.assertRaises(gdbm.error, gdbm.open, filename, 'r')
38        # Try to access a closed database.
39        self.g = gdbm.open(filename, 'c')
40        self.g.close()
41        self.assertRaises(gdbm.error, lambda: self.g['a'])
42        # try pass an invalid open flag
43        self.assertRaises(gdbm.error, lambda: gdbm.open(filename, 'rx').close())
44
45    def test_flags(self):
46        # Test the flag parameter open() by trying all supported flag modes.
47        all = set(gdbm.open_flags)
48        # Test standard flags (presumably "crwn").
49        modes = all - set('fsu')
50        for mode in sorted(modes):
51            self.g = gdbm.open(filename, mode)
52            self.g.close()
53
54        # Test additional flags (presumably "fsu").
55        flags = all - set('crwn')
56        for mode in modes:
57            for flag in flags:
58                self.g = gdbm.open(filename, mode + flag)
59                self.g.close()
60
61    def test_reorganize(self):
62        self.g = gdbm.open(filename, 'c')
63        size0 = os.path.getsize(filename)
64
65        self.g['x'] = 'x' * 10000
66        size1 = os.path.getsize(filename)
67        self.assertTrue(size0 < size1)
68
69        del self.g['x']
70        # 'size' is supposed to be the same even after deleting an entry.
71        self.assertEqual(os.path.getsize(filename), size1)
72
73        self.g.reorganize()
74        size2 = os.path.getsize(filename)
75        self.assertTrue(size1 > size2 >= size0)
76
77
78def test_main():
79    run_unittest(TestGdbm)
80
81if __name__ == '__main__':
82    test_main()
83