blob: 623d9929d58f78cb325145738330dcedf8de0c18 [file] [log] [blame]
Georg Brandl7f986ac2008-05-26 10:30:20 +00001"""Test script for the dbm.open function based on testdumbdbm.py"""
2
3import os
4import unittest
Georg Brandl7f986ac2008-05-26 10:30:20 +00005import glob
6import test.support
7
R. David Murraya21e4ca2009-03-31 23:16:50 +00008# Skip tests if dbm module doesn't exist.
9dbm = test.support.import_module('dbm')
10
Ezio Melottib08495b2013-07-07 13:15:08 +020011try:
12 from dbm import ndbm
13except ImportError:
14 ndbm = None
15
Georg Brandl7f986ac2008-05-26 10:30:20 +000016_fname = test.support.TESTFN
17
18#
19# Iterates over every database module supported by dbm currently available,
20# setting dbm to use each in turn, and yielding that module
21#
22def dbm_iterator():
Georg Brandlb17acad2008-05-28 08:43:17 +000023 for name in dbm._names:
24 try:
25 mod = __import__(name, fromlist=['open'])
26 except ImportError:
27 continue
28 dbm._modules[name] = mod
29 yield mod
Georg Brandl7f986ac2008-05-26 10:30:20 +000030
31#
32# Clean up all scratch databases we might have created during testing
33#
34def delete_files():
35 # we don't know the precise name the underlying database uses
36 # so we use glob to locate all names
37 for f in glob.glob(_fname + "*"):
38 test.support.unlink(f)
39
40
Ezio Melottif79493b2013-03-01 11:23:28 +020041class AnyDBMTestCase:
Georg Brandl7f986ac2008-05-26 10:30:20 +000042 _dict = {'0': b'',
43 'a': b'Python:',
44 'b': b'Programming',
45 'c': b'the',
46 'd': b'way',
47 'f': b'Guido',
48 'g': b'intended',
49 }
50
Georg Brandlb17acad2008-05-28 08:43:17 +000051 def init_db(self):
52 f = dbm.open(_fname, 'n')
53 for k in self._dict:
54 f[k.encode("ascii")] = self._dict[k]
55 f.close()
56
57 def keys_helper(self, f):
58 keys = sorted(k.decode("ascii") for k in f.keys())
59 dkeys = sorted(self._dict.keys())
60 self.assertEqual(keys, dkeys)
61 return keys
62
63 def test_error(self):
Andrew Svetlovf7a17b42012-12-25 16:47:37 +020064 self.assertTrue(issubclass(self.module.error, OSError))
Georg Brandl7f986ac2008-05-26 10:30:20 +000065
Amaury Forgeot d'Arcb5cf3012008-09-25 22:27:43 +000066 def test_anydbm_not_existing(self):
67 self.assertRaises(dbm.error, dbm.open, _fname)
68
Georg Brandl7f986ac2008-05-26 10:30:20 +000069 def test_anydbm_creation(self):
70 f = dbm.open(_fname, 'c')
71 self.assertEqual(list(f.keys()), [])
72 for key in self._dict:
73 f[key.encode("ascii")] = self._dict[key]
74 self.read_helper(f)
75 f.close()
76
briancurtin525c25d2011-03-14 16:03:54 -040077 def test_anydbm_creation_n_file_exists_with_invalid_contents(self):
Victor Stinnerbf816222011-06-30 23:25:47 +020078 # create an empty file
79 test.support.create_empty_file(_fname)
briancurtin525c25d2011-03-14 16:03:54 -040080
81 f = dbm.open(_fname, 'n')
82 self.addCleanup(f.close)
83 self.assertEqual(len(f), 0)
84
Georg Brandl7f986ac2008-05-26 10:30:20 +000085 def test_anydbm_modification(self):
86 self.init_db()
87 f = dbm.open(_fname, 'c')
88 self._dict['g'] = f[b'g'] = b"indented"
89 self.read_helper(f)
90 f.close()
91
92 def test_anydbm_read(self):
93 self.init_db()
94 f = dbm.open(_fname, 'r')
95 self.read_helper(f)
96 f.close()
97
98 def test_anydbm_keys(self):
99 self.init_db()
100 f = dbm.open(_fname, 'r')
101 keys = self.keys_helper(f)
102 f.close()
103
104 def test_anydbm_access(self):
105 self.init_db()
106 f = dbm.open(_fname, 'r')
107 key = "a".encode("ascii")
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000108 self.assertIn(key, f)
Georg Brandl7f986ac2008-05-26 10:30:20 +0000109 assert(f[key] == b"Python:")
110 f.close()
111
112 def read_helper(self, f):
113 keys = self.keys_helper(f)
114 for key in self._dict:
115 self.assertEqual(self._dict[key], f[key.encode("ascii")])
116
Georg Brandl7f986ac2008-05-26 10:30:20 +0000117 def tearDown(self):
118 delete_files()
119
120 def setUp(self):
Georg Brandlb17acad2008-05-28 08:43:17 +0000121 dbm._defaultmod = self.module
Georg Brandl7f986ac2008-05-26 10:30:20 +0000122 delete_files()
123
124
125class WhichDBTestCase(unittest.TestCase):
Georg Brandl7f986ac2008-05-26 10:30:20 +0000126 def test_whichdb(self):
127 for module in dbm_iterator():
128 # Check whether whichdb correctly guesses module name
129 # for databases opened with "module" module.
130 # Try with empty files first
131 name = module.__name__
132 if name == 'dbm.dumb':
133 continue # whichdb can't support dbm.dumb
Senthil Kumaran725c2b92011-02-26 07:11:27 +0000134 delete_files()
Georg Brandl7f986ac2008-05-26 10:30:20 +0000135 f = module.open(_fname, 'c')
136 f.close()
Ezio Melottib08495b2013-07-07 13:15:08 +0200137 self.assertEqual(name, self.dbm.whichdb(_fname))
Georg Brandl7f986ac2008-05-26 10:30:20 +0000138 # Now add a key
139 f = module.open(_fname, 'w')
140 f[b"1"] = b"1"
141 # and test that we can find it
Benjamin Peterson577473f2010-01-19 00:09:57 +0000142 self.assertIn(b"1", f)
Georg Brandl7f986ac2008-05-26 10:30:20 +0000143 # and read it
144 self.assertTrue(f[b"1"] == b"1")
145 f.close()
Ezio Melottib08495b2013-07-07 13:15:08 +0200146 self.assertEqual(name, self.dbm.whichdb(_fname))
147
148 @unittest.skipUnless(ndbm, reason='Test requires ndbm')
149 def test_whichdb_ndbm(self):
150 # Issue 17198: check that ndbm which is referenced in whichdb is defined
151 db_file = '{}_ndbm.db'.format(_fname)
152 with open(db_file, 'w'):
153 self.addCleanup(test.support.unlink, db_file)
154 self.assertIsNone(self.dbm.whichdb(db_file[:-3]))
Georg Brandl7f986ac2008-05-26 10:30:20 +0000155
156 def tearDown(self):
157 delete_files()
158
159 def setUp(self):
160 delete_files()
Benjamin Petersonf10a79a2008-10-11 00:49:57 +0000161 self.filename = test.support.TESTFN
162 self.d = dbm.open(self.filename, 'c')
163 self.d.close()
Ezio Melottib08495b2013-07-07 13:15:08 +0200164 self.dbm = test.support.import_fresh_module('dbm')
Benjamin Petersonf10a79a2008-10-11 00:49:57 +0000165
166 def test_keys(self):
167 self.d = dbm.open(self.filename, 'c')
168 self.assertEqual(self.d.keys(), [])
169 a = [(b'a', b'b'), (b'12345678910', b'019237410982340912840198242')]
170 for k, v in a:
171 self.d[k] = v
172 self.assertEqual(sorted(self.d.keys()), sorted(k for (k, v) in a))
173 for k, v in a:
Benjamin Peterson577473f2010-01-19 00:09:57 +0000174 self.assertIn(k, self.d)
Benjamin Petersonf10a79a2008-10-11 00:49:57 +0000175 self.assertEqual(self.d[k], v)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000176 self.assertNotIn(b'xxx', self.d)
Benjamin Peterson1bc15c22008-10-11 02:19:18 +0000177 self.assertRaises(KeyError, lambda: self.d[b'xxx'])
Benjamin Petersonf10a79a2008-10-11 00:49:57 +0000178 self.d.close()
Georg Brandl7f986ac2008-05-26 10:30:20 +0000179
180
Ezio Melottif79493b2013-03-01 11:23:28 +0200181def load_tests(loader, tests, pattern):
182 classes = []
Georg Brandlb17acad2008-05-28 08:43:17 +0000183 for mod in dbm_iterator():
Ezio Melottif79493b2013-03-01 11:23:28 +0200184 classes.append(type("TestCase-" + mod.__name__,
185 (AnyDBMTestCase, unittest.TestCase),
Georg Brandlb17acad2008-05-28 08:43:17 +0000186 {'module': mod}))
Ezio Melottif79493b2013-03-01 11:23:28 +0200187 suites = [unittest.makeSuite(c) for c in classes]
188
189 tests.addTests(suites)
190 return tests
Georg Brandl7f986ac2008-05-26 10:30:20 +0000191
192if __name__ == "__main__":
Ezio Melottif79493b2013-03-01 11:23:28 +0200193 unittest.main()