1"""Test script for the dbm.open function based on testdumbdbm.py""" 2 3import unittest 4import glob 5import test.support 6 7# Skip tests if dbm module doesn't exist. 8dbm = test.support.import_module('dbm') 9 10try: 11 from dbm import ndbm 12except ImportError: 13 ndbm = None 14 15_fname = test.support.TESTFN 16 17# 18# Iterates over every database module supported by dbm currently available, 19# setting dbm to use each in turn, and yielding that module 20# 21def dbm_iterator(): 22 for name in dbm._names: 23 try: 24 mod = __import__(name, fromlist=['open']) 25 except ImportError: 26 continue 27 dbm._modules[name] = mod 28 yield mod 29 30# 31# Clean up all scratch databases we might have created during testing 32# 33def delete_files(): 34 # we don't know the precise name the underlying database uses 35 # so we use glob to locate all names 36 for f in glob.glob(_fname + "*"): 37 test.support.unlink(f) 38 39 40class AnyDBMTestCase: 41 _dict = {'0': b'', 42 'a': b'Python:', 43 'b': b'Programming', 44 'c': b'the', 45 'd': b'way', 46 'f': b'Guido', 47 'g': b'intended', 48 } 49 50 def init_db(self): 51 f = dbm.open(_fname, 'n') 52 for k in self._dict: 53 f[k.encode("ascii")] = self._dict[k] 54 f.close() 55 56 def keys_helper(self, f): 57 keys = sorted(k.decode("ascii") for k in f.keys()) 58 dkeys = sorted(self._dict.keys()) 59 self.assertEqual(keys, dkeys) 60 return keys 61 62 def test_error(self): 63 self.assertTrue(issubclass(self.module.error, OSError)) 64 65 def test_anydbm_not_existing(self): 66 self.assertRaises(dbm.error, dbm.open, _fname) 67 68 def test_anydbm_creation(self): 69 f = dbm.open(_fname, 'c') 70 self.assertEqual(list(f.keys()), []) 71 for key in self._dict: 72 f[key.encode("ascii")] = self._dict[key] 73 self.read_helper(f) 74 f.close() 75 76 def test_anydbm_creation_n_file_exists_with_invalid_contents(self): 77 # create an empty file 78 test.support.create_empty_file(_fname) 79 80 f = dbm.open(_fname, 'n') 81 self.addCleanup(f.close) 82 self.assertEqual(len(f), 0) 83 84 def test_anydbm_modification(self): 85 self.init_db() 86 f = dbm.open(_fname, 'c') 87 self._dict['g'] = f[b'g'] = b"indented" 88 self.read_helper(f) 89 f.close() 90 91 def test_anydbm_read(self): 92 self.init_db() 93 f = dbm.open(_fname, 'r') 94 self.read_helper(f) 95 f.close() 96 97 def test_anydbm_keys(self): 98 self.init_db() 99 f = dbm.open(_fname, 'r') 100 keys = self.keys_helper(f) 101 f.close() 102 103 def test_anydbm_access(self): 104 self.init_db() 105 f = dbm.open(_fname, 'r') 106 key = "a".encode("ascii") 107 self.assertIn(key, f) 108 assert(f[key] == b"Python:") 109 f.close() 110 111 def read_helper(self, f): 112 keys = self.keys_helper(f) 113 for key in self._dict: 114 self.assertEqual(self._dict[key], f[key.encode("ascii")]) 115 116 def tearDown(self): 117 delete_files() 118 119 def setUp(self): 120 dbm._defaultmod = self.module 121 delete_files() 122 123 124class WhichDBTestCase(unittest.TestCase): 125 def test_whichdb(self): 126 for module in dbm_iterator(): 127 # Check whether whichdb correctly guesses module name 128 # for databases opened with "module" module. 129 # Try with empty files first 130 name = module.__name__ 131 if name == 'dbm.dumb': 132 continue # whichdb can't support dbm.dumb 133 delete_files() 134 f = module.open(_fname, 'c') 135 f.close() 136 self.assertEqual(name, self.dbm.whichdb(_fname)) 137 # Now add a key 138 f = module.open(_fname, 'w') 139 f[b"1"] = b"1" 140 # and test that we can find it 141 self.assertIn(b"1", f) 142 # and read it 143 self.assertTrue(f[b"1"] == b"1") 144 f.close() 145 self.assertEqual(name, self.dbm.whichdb(_fname)) 146 147 @unittest.skipUnless(ndbm, reason='Test requires ndbm') 148 def test_whichdb_ndbm(self): 149 # Issue 17198: check that ndbm which is referenced in whichdb is defined 150 db_file = '{}_ndbm.db'.format(_fname) 151 with open(db_file, 'w'): 152 self.addCleanup(test.support.unlink, db_file) 153 self.assertIsNone(self.dbm.whichdb(db_file[:-3])) 154 155 def tearDown(self): 156 delete_files() 157 158 def setUp(self): 159 delete_files() 160 self.filename = test.support.TESTFN 161 self.d = dbm.open(self.filename, 'c') 162 self.d.close() 163 self.dbm = test.support.import_fresh_module('dbm') 164 165 def test_keys(self): 166 self.d = dbm.open(self.filename, 'c') 167 self.assertEqual(self.d.keys(), []) 168 a = [(b'a', b'b'), (b'12345678910', b'019237410982340912840198242')] 169 for k, v in a: 170 self.d[k] = v 171 self.assertEqual(sorted(self.d.keys()), sorted(k for (k, v) in a)) 172 for k, v in a: 173 self.assertIn(k, self.d) 174 self.assertEqual(self.d[k], v) 175 self.assertNotIn(b'xxx', self.d) 176 self.assertRaises(KeyError, lambda: self.d[b'xxx']) 177 self.d.close() 178 179 180def load_tests(loader, tests, pattern): 181 classes = [] 182 for mod in dbm_iterator(): 183 classes.append(type("TestCase-" + mod.__name__, 184 (AnyDBMTestCase, unittest.TestCase), 185 {'module': mod})) 186 suites = [unittest.makeSuite(c) for c in classes] 187 188 tests.addTests(suites) 189 return tests 190 191if __name__ == "__main__": 192 unittest.main() 193