blob: 243a0af10319523e7fe02bfb4404ba7e58f04dc5 [file] [log] [blame]
Benjamin Peterson90f5ba52010-03-11 22:53:45 +00001#! /usr/bin/env python3
Georg Brandl7f986ac2008-05-26 10:30:20 +00002"""Test script for the dbm.open function based on testdumbdbm.py"""
3
4import os
5import unittest
Georg Brandl7f986ac2008-05-26 10:30:20 +00006import glob
7import test.support
8
R. David Murraya21e4ca2009-03-31 23:16:50 +00009# Skip tests if dbm module doesn't exist.
10dbm = test.support.import_module('dbm')
11
Ezio Melottib08495b2013-07-07 13:15:08 +020012try:
13 from dbm import ndbm
14except ImportError:
15 ndbm = None
16
Georg Brandl7f986ac2008-05-26 10:30:20 +000017_fname = test.support.TESTFN
18
19#
20# Iterates over every database module supported by dbm currently available,
21# setting dbm to use each in turn, and yielding that module
22#
23def dbm_iterator():
Georg Brandlb17acad2008-05-28 08:43:17 +000024 for name in dbm._names:
25 try:
26 mod = __import__(name, fromlist=['open'])
27 except ImportError:
28 continue
29 dbm._modules[name] = mod
30 yield mod
Georg Brandl7f986ac2008-05-26 10:30:20 +000031
32#
33# Clean up all scratch databases we might have created during testing
34#
35def delete_files():
36 # we don't know the precise name the underlying database uses
37 # so we use glob to locate all names
38 for f in glob.glob(_fname + "*"):
39 test.support.unlink(f)
40
41
Ezio Melottif79493b2013-03-01 11:23:28 +020042class AnyDBMTestCase:
Georg Brandl7f986ac2008-05-26 10:30:20 +000043 _dict = {'0': b'',
44 'a': b'Python:',
45 'b': b'Programming',
46 'c': b'the',
47 'd': b'way',
48 'f': b'Guido',
49 'g': b'intended',
50 }
51
Georg Brandlb17acad2008-05-28 08:43:17 +000052 def init_db(self):
53 f = dbm.open(_fname, 'n')
54 for k in self._dict:
55 f[k.encode("ascii")] = self._dict[k]
56 f.close()
57
58 def keys_helper(self, f):
59 keys = sorted(k.decode("ascii") for k in f.keys())
60 dkeys = sorted(self._dict.keys())
61 self.assertEqual(keys, dkeys)
62 return keys
63
64 def test_error(self):
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000065 self.assertTrue(issubclass(self.module.error, IOError))
Georg Brandl7f986ac2008-05-26 10:30:20 +000066
Amaury Forgeot d'Arcb5cf3012008-09-25 22:27:43 +000067 def test_anydbm_not_existing(self):
68 self.assertRaises(dbm.error, dbm.open, _fname)
69
Georg Brandl7f986ac2008-05-26 10:30:20 +000070 def test_anydbm_creation(self):
71 f = dbm.open(_fname, 'c')
72 self.assertEqual(list(f.keys()), [])
73 for key in self._dict:
74 f[key.encode("ascii")] = self._dict[key]
75 self.read_helper(f)
76 f.close()
77
briancurtin525c25d2011-03-14 16:03:54 -040078 def test_anydbm_creation_n_file_exists_with_invalid_contents(self):
Victor Stinnerbf816222011-06-30 23:25:47 +020079 # create an empty file
80 test.support.create_empty_file(_fname)
briancurtin525c25d2011-03-14 16:03:54 -040081
82 f = dbm.open(_fname, 'n')
83 self.addCleanup(f.close)
84 self.assertEqual(len(f), 0)
85
Georg Brandl7f986ac2008-05-26 10:30:20 +000086 def test_anydbm_modification(self):
87 self.init_db()
88 f = dbm.open(_fname, 'c')
89 self._dict['g'] = f[b'g'] = b"indented"
90 self.read_helper(f)
91 f.close()
92
93 def test_anydbm_read(self):
94 self.init_db()
95 f = dbm.open(_fname, 'r')
96 self.read_helper(f)
97 f.close()
98
99 def test_anydbm_keys(self):
100 self.init_db()
101 f = dbm.open(_fname, 'r')
102 keys = self.keys_helper(f)
103 f.close()
104
105 def test_anydbm_access(self):
106 self.init_db()
107 f = dbm.open(_fname, 'r')
108 key = "a".encode("ascii")
Ezio Melottib58e0bd2010-01-23 15:40:09 +0000109 self.assertIn(key, f)
Georg Brandl7f986ac2008-05-26 10:30:20 +0000110 assert(f[key] == b"Python:")
111 f.close()
112
113 def read_helper(self, f):
114 keys = self.keys_helper(f)
115 for key in self._dict:
116 self.assertEqual(self._dict[key], f[key.encode("ascii")])
117
Georg Brandl7f986ac2008-05-26 10:30:20 +0000118 def tearDown(self):
119 delete_files()
120
121 def setUp(self):
Georg Brandlb17acad2008-05-28 08:43:17 +0000122 dbm._defaultmod = self.module
Georg Brandl7f986ac2008-05-26 10:30:20 +0000123 delete_files()
124
125
126class WhichDBTestCase(unittest.TestCase):
Georg Brandl7f986ac2008-05-26 10:30:20 +0000127 def test_whichdb(self):
128 for module in dbm_iterator():
129 # Check whether whichdb correctly guesses module name
130 # for databases opened with "module" module.
131 # Try with empty files first
132 name = module.__name__
133 if name == 'dbm.dumb':
134 continue # whichdb can't support dbm.dumb
Senthil Kumaran725c2b92011-02-26 07:11:27 +0000135 delete_files()
Georg Brandl7f986ac2008-05-26 10:30:20 +0000136 f = module.open(_fname, 'c')
137 f.close()
Ezio Melottib08495b2013-07-07 13:15:08 +0200138 self.assertEqual(name, self.dbm.whichdb(_fname))
Georg Brandl7f986ac2008-05-26 10:30:20 +0000139 # Now add a key
140 f = module.open(_fname, 'w')
141 f[b"1"] = b"1"
142 # and test that we can find it
Benjamin Peterson577473f2010-01-19 00:09:57 +0000143 self.assertIn(b"1", f)
Georg Brandl7f986ac2008-05-26 10:30:20 +0000144 # and read it
145 self.assertTrue(f[b"1"] == b"1")
146 f.close()
Ezio Melottib08495b2013-07-07 13:15:08 +0200147 self.assertEqual(name, self.dbm.whichdb(_fname))
148
149 @unittest.skipUnless(ndbm, reason='Test requires ndbm')
150 def test_whichdb_ndbm(self):
151 # Issue 17198: check that ndbm which is referenced in whichdb is defined
152 db_file = '{}_ndbm.db'.format(_fname)
153 with open(db_file, 'w'):
154 self.addCleanup(test.support.unlink, db_file)
155 self.assertIsNone(self.dbm.whichdb(db_file[:-3]))
Georg Brandl7f986ac2008-05-26 10:30:20 +0000156
157 def tearDown(self):
158 delete_files()
159
160 def setUp(self):
161 delete_files()
Benjamin Petersonf10a79a2008-10-11 00:49:57 +0000162 self.filename = test.support.TESTFN
163 self.d = dbm.open(self.filename, 'c')
164 self.d.close()
Ezio Melottib08495b2013-07-07 13:15:08 +0200165 self.dbm = test.support.import_fresh_module('dbm')
Benjamin Petersonf10a79a2008-10-11 00:49:57 +0000166
167 def test_keys(self):
168 self.d = dbm.open(self.filename, 'c')
169 self.assertEqual(self.d.keys(), [])
170 a = [(b'a', b'b'), (b'12345678910', b'019237410982340912840198242')]
171 for k, v in a:
172 self.d[k] = v
173 self.assertEqual(sorted(self.d.keys()), sorted(k for (k, v) in a))
174 for k, v in a:
Benjamin Peterson577473f2010-01-19 00:09:57 +0000175 self.assertIn(k, self.d)
Benjamin Petersonf10a79a2008-10-11 00:49:57 +0000176 self.assertEqual(self.d[k], v)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000177 self.assertNotIn(b'xxx', self.d)
Benjamin Peterson1bc15c22008-10-11 02:19:18 +0000178 self.assertRaises(KeyError, lambda: self.d[b'xxx'])
Benjamin Petersonf10a79a2008-10-11 00:49:57 +0000179 self.d.close()
Georg Brandl7f986ac2008-05-26 10:30:20 +0000180
181
Ezio Melottif79493b2013-03-01 11:23:28 +0200182def load_tests(loader, tests, pattern):
183 classes = []
Georg Brandlb17acad2008-05-28 08:43:17 +0000184 for mod in dbm_iterator():
Ezio Melottif79493b2013-03-01 11:23:28 +0200185 classes.append(type("TestCase-" + mod.__name__,
186 (AnyDBMTestCase, unittest.TestCase),
Georg Brandlb17acad2008-05-28 08:43:17 +0000187 {'module': mod}))
Ezio Melottif79493b2013-03-01 11:23:28 +0200188 suites = [unittest.makeSuite(c) for c in classes]
189
190 tests.addTests(suites)
191 return tests
Georg Brandl7f986ac2008-05-26 10:30:20 +0000192
193if __name__ == "__main__":
Ezio Melottif79493b2013-03-01 11:23:28 +0200194 unittest.main()