blob: 50b8a192e55ca6cf2752cc2cea56db6b1bd6de7d [file] [log] [blame]
Kristján Valur Jónsson42a40c52009-04-01 11:28:47 +00001from test import support
2gdbm = support.import_module("dbm.gnu") #skip if not supported
Christian Heimesdd15f6c2008-03-16 00:07:10 +00003import unittest
4import os
Serhiy Storchaka6f600ff2018-02-26 16:02:22 +02005from test.support import TESTFN, TESTFN_NONASCII, unlink
Christian Heimesdd15f6c2008-03-16 00:07:10 +00006
Roger E. Massefab8ab81996-12-20 22:36:52 +00007
Guido van Rossumf35ad332006-08-25 23:40:32 +00008filename = TESTFN
Roger E. Masse62a017c1996-12-17 19:54:27 +00009
Christian Heimesdd15f6c2008-03-16 00:07:10 +000010class TestGdbm(unittest.TestCase):
11 def setUp(self):
12 self.g = None
Fred Drake004d5e62000-10-23 17:22:08 +000013
Christian Heimesdd15f6c2008-03-16 00:07:10 +000014 def tearDown(self):
15 if self.g is not None:
16 self.g.close()
17 unlink(filename)
Roger E. Masse62a017c1996-12-17 19:54:27 +000018
Christian Heimesdd15f6c2008-03-16 00:07:10 +000019 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'
Brett Cannon7317c1e2008-11-25 19:19:17 +000024 self.g[b'bytes'] = b'data'
Christian Heimesdd15f6c2008-03-16 00:07:10 +000025 key_set = set(self.g.keys())
Brett Cannon45dea652008-11-25 21:27:00 +000026 self.assertEqual(key_set, set([b'a', b'bytes', b'12345678910']))
Serhiy Storchaka7d6392c2013-10-25 00:06:52 +030027 self.assertIn('a', self.g)
Benjamin Peterson577473f2010-01-19 00:09:57 +000028 self.assertIn(b'a', self.g)
Brett Cannon7317c1e2008-11-25 19:19:17 +000029 self.assertEqual(self.g[b'bytes'], b'data')
Christian Heimesdd15f6c2008-03-16 00:07:10 +000030 key = self.g.firstkey()
31 while key:
Benjamin Peterson577473f2010-01-19 00:09:57 +000032 self.assertIn(key, key_set)
Christian Heimesdd15f6c2008-03-16 00:07:10 +000033 key_set.remove(key)
34 key = self.g.nextkey(key)
Georg Brandld9e833c2010-12-04 09:14:36 +000035 # get() and setdefault() work as in the dict interface
Serhiy Storchaka2e38cc32018-04-29 12:38:06 +030036 self.assertEqual(self.g.get(b'a'), b'b')
37 self.assertIsNone(self.g.get(b'xxx'))
Georg Brandld9e833c2010-12-04 09:14:36 +000038 self.assertEqual(self.g.get(b'xxx', b'foo'), b'foo')
Serhiy Storchaka2e38cc32018-04-29 12:38:06 +030039 with self.assertRaises(KeyError):
40 self.g['xxx']
Georg Brandld9e833c2010-12-04 09:14:36 +000041 self.assertEqual(self.g.setdefault(b'xxx', b'foo'), b'foo')
42 self.assertEqual(self.g[b'xxx'], b'foo')
Christian Heimesdd15f6c2008-03-16 00:07:10 +000043
44 def test_error_conditions(self):
45 # Try to open a non-existent database.
46 unlink(filename)
47 self.assertRaises(gdbm.error, gdbm.open, filename, 'r')
48 # Try to access a closed database.
49 self.g = gdbm.open(filename, 'c')
50 self.g.close()
51 self.assertRaises(gdbm.error, lambda: self.g['a'])
52 # try pass an invalid open flag
53 self.assertRaises(gdbm.error, lambda: gdbm.open(filename, 'rx').close())
54
55 def test_flags(self):
56 # Test the flag parameter open() by trying all supported flag modes.
57 all = set(gdbm.open_flags)
58 # Test standard flags (presumably "crwn").
59 modes = all - set('fsu')
Georg Brandl16684eb2012-02-20 22:48:06 +010060 for mode in sorted(modes): # put "c" mode first
Christian Heimesdd15f6c2008-03-16 00:07:10 +000061 self.g = gdbm.open(filename, mode)
62 self.g.close()
63
64 # Test additional flags (presumably "fsu").
65 flags = all - set('crwn')
66 for mode in modes:
67 for flag in flags:
68 self.g = gdbm.open(filename, mode + flag)
69 self.g.close()
70
71 def test_reorganize(self):
72 self.g = gdbm.open(filename, 'c')
73 size0 = os.path.getsize(filename)
74
75 self.g['x'] = 'x' * 10000
76 size1 = os.path.getsize(filename)
Serhiy Storchaka22525de2018-06-19 13:31:48 +030077 self.assertGreater(size1, size0)
Christian Heimesdd15f6c2008-03-16 00:07:10 +000078
79 del self.g['x']
80 # 'size' is supposed to be the same even after deleting an entry.
81 self.assertEqual(os.path.getsize(filename), size1)
82
83 self.g.reorganize()
84 size2 = os.path.getsize(filename)
Serhiy Storchaka22525de2018-06-19 13:31:48 +030085 self.assertLess(size2, size1)
86 self.assertGreaterEqual(size2, size0)
Christian Heimesdd15f6c2008-03-16 00:07:10 +000087
Nick Coghlanc610aba2013-11-17 15:59:51 +100088 def test_context_manager(self):
89 with gdbm.open(filename, 'c') as db:
90 db["gdbm context manager"] = "context manager"
91
92 with gdbm.open(filename, 'r') as db:
93 self.assertEqual(list(db.keys()), [b"gdbm context manager"])
94
95 with self.assertRaises(gdbm.error) as cm:
96 db.keys()
97 self.assertEqual(str(cm.exception),
98 "GDBM object has already been closed")
Christian Heimesdd15f6c2008-03-16 00:07:10 +000099
Serhiy Storchaka6f600ff2018-02-26 16:02:22 +0200100 def test_bytes(self):
101 with gdbm.open(filename, 'c') as db:
102 db[b'bytes key \xbd'] = b'bytes value \xbd'
103 with gdbm.open(filename, 'r') as db:
104 self.assertEqual(list(db.keys()), [b'bytes key \xbd'])
105 self.assertTrue(b'bytes key \xbd' in db)
106 self.assertEqual(db[b'bytes key \xbd'], b'bytes value \xbd')
107
108 def test_unicode(self):
109 with gdbm.open(filename, 'c') as db:
110 db['Unicode key \U0001f40d'] = 'Unicode value \U0001f40d'
111 with gdbm.open(filename, 'r') as db:
112 self.assertEqual(list(db.keys()), ['Unicode key \U0001f40d'.encode()])
113 self.assertTrue('Unicode key \U0001f40d'.encode() in db)
114 self.assertTrue('Unicode key \U0001f40d' in db)
115 self.assertEqual(db['Unicode key \U0001f40d'.encode()],
116 'Unicode value \U0001f40d'.encode())
117 self.assertEqual(db['Unicode key \U0001f40d'],
118 'Unicode value \U0001f40d'.encode())
119
120 @unittest.skipUnless(TESTFN_NONASCII,
121 'requires OS support of non-ASCII encodings')
122 def test_nonascii_filename(self):
123 filename = TESTFN_NONASCII
124 self.addCleanup(unlink, filename)
125 with gdbm.open(filename, 'c') as db:
126 db[b'key'] = b'value'
127 self.assertTrue(os.path.exists(filename))
128 with gdbm.open(filename, 'r') as db:
129 self.assertEqual(list(db.keys()), [b'key'])
130 self.assertTrue(b'key' in db)
131 self.assertEqual(db[b'key'], b'value')
132
133
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000134if __name__ == '__main__':
Ezio Melottif79493b2013-03-01 11:23:28 +0200135 unittest.main()