• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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        # bpo-33901: on macOS with gdbm 1.15, an empty database uses 16 MiB
66        # and adding an entry of 10,000 B has no effect on the file size.
67        # Add size0 bytes to make sure that the file size changes.
68        value_size = max(size0, 10000)
69        self.g['x'] = 'x' * value_size
70        size1 = os.path.getsize(filename)
71        self.assertGreater(size1, size0)
72
73        del self.g['x']
74        # 'size' is supposed to be the same even after deleting an entry.
75        self.assertEqual(os.path.getsize(filename), size1)
76
77        self.g.reorganize()
78        size2 = os.path.getsize(filename)
79        self.assertLess(size2, size1)
80        self.assertGreaterEqual(size2, size0)
81
82
83def test_main():
84    run_unittest(TestGdbm)
85
86if __name__ == '__main__':
87    test_main()
88