blob: d96df92848063cbc2a8cf0d122bb9e7c6347f7c5 [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)
35 self.assertRaises(KeyError, lambda: self.g['xxx'])
Georg Brandld9e833c2010-12-04 09:14:36 +000036 # get() and setdefault() work as in the dict interface
37 self.assertEqual(self.g.get(b'xxx', b'foo'), b'foo')
38 self.assertEqual(self.g.setdefault(b'xxx', b'foo'), b'foo')
39 self.assertEqual(self.g[b'xxx'], b'foo')
Christian Heimesdd15f6c2008-03-16 00:07:10 +000040
41 def test_error_conditions(self):
42 # Try to open a non-existent database.
43 unlink(filename)
44 self.assertRaises(gdbm.error, gdbm.open, filename, 'r')
45 # Try to access a closed database.
46 self.g = gdbm.open(filename, 'c')
47 self.g.close()
48 self.assertRaises(gdbm.error, lambda: self.g['a'])
49 # try pass an invalid open flag
50 self.assertRaises(gdbm.error, lambda: gdbm.open(filename, 'rx').close())
51
52 def test_flags(self):
53 # Test the flag parameter open() by trying all supported flag modes.
54 all = set(gdbm.open_flags)
55 # Test standard flags (presumably "crwn").
56 modes = all - set('fsu')
Georg Brandl16684eb2012-02-20 22:48:06 +010057 for mode in sorted(modes): # put "c" mode first
Christian Heimesdd15f6c2008-03-16 00:07:10 +000058 self.g = gdbm.open(filename, mode)
59 self.g.close()
60
61 # Test additional flags (presumably "fsu").
62 flags = all - set('crwn')
63 for mode in modes:
64 for flag in flags:
65 self.g = gdbm.open(filename, mode + flag)
66 self.g.close()
67
68 def test_reorganize(self):
69 self.g = gdbm.open(filename, 'c')
70 size0 = os.path.getsize(filename)
71
72 self.g['x'] = 'x' * 10000
73 size1 = os.path.getsize(filename)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000074 self.assertTrue(size0 < size1)
Christian Heimesdd15f6c2008-03-16 00:07:10 +000075
76 del self.g['x']
77 # 'size' is supposed to be the same even after deleting an entry.
78 self.assertEqual(os.path.getsize(filename), size1)
79
80 self.g.reorganize()
81 size2 = os.path.getsize(filename)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000082 self.assertTrue(size1 > size2 >= size0)
Christian Heimesdd15f6c2008-03-16 00:07:10 +000083
Nick Coghlanc610aba2013-11-17 15:59:51 +100084 def test_context_manager(self):
85 with gdbm.open(filename, 'c') as db:
86 db["gdbm context manager"] = "context manager"
87
88 with gdbm.open(filename, 'r') as db:
89 self.assertEqual(list(db.keys()), [b"gdbm context manager"])
90
91 with self.assertRaises(gdbm.error) as cm:
92 db.keys()
93 self.assertEqual(str(cm.exception),
94 "GDBM object has already been closed")
Christian Heimesdd15f6c2008-03-16 00:07:10 +000095
Serhiy Storchaka6f600ff2018-02-26 16:02:22 +020096 def test_bytes(self):
97 with gdbm.open(filename, 'c') as db:
98 db[b'bytes key \xbd'] = b'bytes value \xbd'
99 with gdbm.open(filename, 'r') as db:
100 self.assertEqual(list(db.keys()), [b'bytes key \xbd'])
101 self.assertTrue(b'bytes key \xbd' in db)
102 self.assertEqual(db[b'bytes key \xbd'], b'bytes value \xbd')
103
104 def test_unicode(self):
105 with gdbm.open(filename, 'c') as db:
106 db['Unicode key \U0001f40d'] = 'Unicode value \U0001f40d'
107 with gdbm.open(filename, 'r') as db:
108 self.assertEqual(list(db.keys()), ['Unicode key \U0001f40d'.encode()])
109 self.assertTrue('Unicode key \U0001f40d'.encode() in db)
110 self.assertTrue('Unicode key \U0001f40d' in db)
111 self.assertEqual(db['Unicode key \U0001f40d'.encode()],
112 'Unicode value \U0001f40d'.encode())
113 self.assertEqual(db['Unicode key \U0001f40d'],
114 'Unicode value \U0001f40d'.encode())
115
116 @unittest.skipUnless(TESTFN_NONASCII,
117 'requires OS support of non-ASCII encodings')
118 def test_nonascii_filename(self):
119 filename = TESTFN_NONASCII
120 self.addCleanup(unlink, filename)
121 with gdbm.open(filename, 'c') as db:
122 db[b'key'] = b'value'
123 self.assertTrue(os.path.exists(filename))
124 with gdbm.open(filename, 'r') as db:
125 self.assertEqual(list(db.keys()), [b'key'])
126 self.assertTrue(b'key' in db)
127 self.assertEqual(db[b'key'], b'value')
128
129
Christian Heimesdd15f6c2008-03-16 00:07:10 +0000130if __name__ == '__main__':
Ezio Melottif79493b2013-03-01 11:23:28 +0200131 unittest.main()