Code

61c08a669c861b9112db963006c3c33af3ad7a01
[roundup.git] / test / test_db.py
1 #
2 # Copyright (c) 2001 Bizar Software Pty Ltd (http://www.bizarsoftware.com.au/)
3 # This module is free software, and you may redistribute it and/or modify
4 # under the same terms as Python, so long as this copyright message and
5 # disclaimer are retained in their original form.
6 #
7 # IN NO EVENT SHALL BIZAR SOFTWARE PTY LTD BE LIABLE TO ANY PARTY FOR
8 # DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING
9 # OUT OF THE USE OF THIS CODE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE
10 # POSSIBILITY OF SUCH DAMAGE.
11 #
12 # BIZAR SOFTWARE PTY LTD SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
13 # BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
14 # FOR A PARTICULAR PURPOSE.  THE CODE PROVIDED HEREUNDER IS ON AN "AS IS"
15 # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
16 # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
17
18 # $Id: test_db.py,v 1.9 2001-12-02 05:06:16 richard Exp $ 
20 import unittest, os, shutil
22 from roundup.hyperdb import String, Password, Link, Multilink, Date, \
23     Interval, Class, DatabaseError
25 def setupSchema(db, create):
26     status = Class(db, "status", name=String())
27     status.setkey("name")
28     if create:
29         status.create(name="unread")
30         status.create(name="in-progress")
31         status.create(name="testing")
32         status.create(name="resolved")
33     Class(db, "user", username=String(), password=Password())
34     Class(db, "issue", title=String(), status=Link("status"),
35         nosy=Multilink("user"))
37 #class MyTestResult(unittest._TestResult):
38 #    def addError(self, test, err):
39 #        print `err`
40 #        TestResult.addError(self, test, err)
41 #        if self.showAll:
42 #            self.stream.writeln("ERROR")
43 #        elif self.dots:
44 #            self.stream.write('E')
45 #        if err[0] is KeyboardInterrupt:
46 #            self.shouldStop = 1
48 class MyTestCase(unittest.TestCase):
49 #    def defaultTestResult(self):
50 #        return MyTestResult()
51     def tearDown(self):
52         if self.db is not None:
53             shutil.rmtree('_test_dir')
54     
55 class DBTestCase(MyTestCase):
56     def setUp(self):
57         from roundup.backends import anydbm
58         # remove previous test, ignore errors
59         if os.path.exists('_test_dir'):
60             shutil.rmtree('_test_dir')
61         os.mkdir('_test_dir')
62         self.db = anydbm.Database('_test_dir', 'test')
63         setupSchema(self.db, 1)
65     def testChanges(self):
66         self.db.issue.create(title="spam", status='1')
67         self.db.issue.create(title="eggs", status='2')
68         self.db.issue.create(title="ham", status='4')
69         self.db.issue.create(title="arguments", status='2')
70         self.db.issue.create(title="abuse", status='1')
71         self.db.issue.addprop(fixer=Link("user"))
72         props = self.db.issue.getprops()
73         keys = props.keys()
74         keys.sort()
75         self.assertEqual(keys, ['fixer', 'id', 'nosy', 'status', 'title'])
76         self.db.issue.set('5', status='2')
77         self.db.issue.get('5', "status")
78         self.db.status.get('2', "name")
79         self.db.issue.get('5', "title")
80         self.db.issue.find(status = self.db.status.lookup("in-progress"))
81         self.db.issue.history('5')
82         self.db.status.history('1')
83         self.db.status.history('2')
85     def testExceptions(self):
86         # this tests the exceptions that should be raised
87         ar = self.assertRaises
89         #
90         # class create
91         #
92         # string property
93         ar(TypeError, self.db.status.create, name=1)
94         # invalid property name
95         ar(KeyError, self.db.status.create, foo='foo')
96         # key name clash
97         ar(ValueError, self.db.status.create, name='unread')
98         # invalid link index
99         ar(IndexError, self.db.issue.create, title='foo', status='bar')
100         # invalid link value
101         ar(ValueError, self.db.issue.create, title='foo', status=1)
102         # invalid multilink type
103         ar(TypeError, self.db.issue.create, title='foo', status='1',
104             nosy='hello')
105         # invalid multilink index type
106         ar(ValueError, self.db.issue.create, title='foo', status='1',
107             nosy=[1])
108         # invalid multilink index
109         ar(IndexError, self.db.issue.create, title='foo', status='1',
110             nosy=['10'])
112         #
113         # class get
114         #
115         # invalid node id
116         ar(IndexError, self.db.status.get, '10', 'name')
117         # invalid property name
118         ar(KeyError, self.db.status.get, '2', 'foo')
120         #
121         # class set
122         #
123         # invalid node id
124         ar(IndexError, self.db.issue.set, '1', name='foo')
125         # invalid property name
126         ar(KeyError, self.db.status.set, '1', foo='foo')
127         # string property
128         ar(TypeError, self.db.status.set, '1', name=1)
129         # key name clash
130         ar(ValueError, self.db.status.set, '2', name='unread')
131         # set up a valid issue for me to work on
132         self.db.issue.create(title="spam", status='1')
133         # invalid link index
134         ar(IndexError, self.db.issue.set, '1', title='foo', status='bar')
135         # invalid link value
136         ar(ValueError, self.db.issue.set, '1', title='foo', status=1)
137         # invalid multilink type
138         ar(TypeError, self.db.issue.set, '1', title='foo', status='1',
139             nosy='hello')
140         # invalid multilink index type
141         ar(ValueError, self.db.issue.set, '1', title='foo', status='1',
142             nosy=[1])
143         # invalid multilink index
144         ar(IndexError, self.db.issue.set, '1', title='foo', status='1',
145             nosy=['10'])
147     def testRetire(self):
148         pass
151 class ReadOnlyDBTestCase(MyTestCase):
152     def setUp(self):
153         from roundup.backends import anydbm
154         # remove previous test, ignore errors
155         if os.path.exists('_test_dir'):
156             shutil.rmtree('_test_dir')
157         os.mkdir('_test_dir')
158         db = anydbm.Database('_test_dir', 'test')
159         setupSchema(db, 1)
160         self.db = anydbm.Database('_test_dir')
161         setupSchema(self.db, 0)
163     def testExceptions(self):
164         # this tests the exceptions that should be raised
165         ar = self.assertRaises
167         # this tests the exceptions that should be raised
168         ar(DatabaseError, self.db.status.create, name="foo")
169         ar(DatabaseError, self.db.status.set, '1', name="foo")
170         ar(DatabaseError, self.db.status.retire, '1')
173 class bsddbDBTestCase(DBTestCase):
174     def setUp(self):
175         from roundup.backends import bsddb
176         # remove previous test, ignore errors
177         if os.path.exists('_test_dir'):
178             shutil.rmtree('_test_dir')
179         os.mkdir('_test_dir')
180         self.db = bsddb.Database('_test_dir', 'test')
181         setupSchema(self.db, 1)
183 class bsddbReadOnlyDBTestCase(ReadOnlyDBTestCase):
184     def setUp(self):
185         from roundup.backends import bsddb
186         # remove previous test, ignore errors
187         if os.path.exists('_test_dir'):
188             shutil.rmtree('_test_dir')
189         os.mkdir('_test_dir')
190         db = bsddb.Database('_test_dir', 'test')
191         setupSchema(db, 1)
192         self.db = bsddb.Database('_test_dir')
193         setupSchema(self.db, 0)
196 class bsddb3DBTestCase(DBTestCase):
197     def setUp(self):
198         from roundup.backends import bsddb3
199         # remove previous test, ignore errors
200         if os.path.exists('_test_dir'):
201             shutil.rmtree('_test_dir')
202         os.mkdir('_test_dir')
203         self.db = bsddb3.Database('_test_dir', 'test')
204         setupSchema(self.db, 1)
206 class bsddb3ReadOnlyDBTestCase(ReadOnlyDBTestCase):
207     def setUp(self):
208         from roundup.backends import bsddb3
209         # remove previous test, ignore errors
210         if os.path.exists('_test_dir'):
211             shutil.rmtree('_test_dir')
212         os.mkdir('_test_dir')
213         db = bsddb3.Database('_test_dir', 'test')
214         setupSchema(db, 1)
215         self.db = bsddb3.Database('_test_dir')
216         setupSchema(self.db, 0)
219 def suite():
220     l = [unittest.makeSuite(DBTestCase, 'test'),
221          unittest.makeSuite(ReadOnlyDBTestCase, 'test')]
223     try:
224         import bsddb
225         l.append(unittest.makeSuite(bsddbDBTestCase, 'test'))
226         l.append(unittest.makeSuite(bsddbReadOnlyDBTestCase, 'test'))
227     except:
228         print 'bsddb module not found, skipping bsddb DBTestCase'
230 #    try:
231 #        import bsddb3
232 #        l.append(unittest.makeSuite(bsddb3DBTestCase, 'test'))
233 #        l.append(unittest.makeSuite(bsddb3ReadOnlyDBTestCase, 'test'))
234 #    except:
235 #        print 'bsddb3 module not found, skipping bsddb3 DBTestCase'
237     return unittest.TestSuite(l)
240 # $Log: not supported by cvs2svn $
241 # Revision 1.8  2001/10/09 07:25:59  richard
242 # Added the Password property type. See "pydoc roundup.password" for
243 # implementation details. Have updated some of the documentation too.
245 # Revision 1.7  2001/08/29 06:23:59  richard
246 # Disabled the bsddb3 module entirely in the unit testing. See CHANGES for
247 # details.
249 # Revision 1.6  2001/08/07 00:24:43  richard
250 # stupid typo
252 # Revision 1.5  2001/08/07 00:15:51  richard
253 # Added the copyright/license notice to (nearly) all files at request of
254 # Bizar Software.
256 # Revision 1.4  2001/07/30 03:45:56  richard
257 # Added more DB to test_db. Can skip tests where imports fail.
259 # Revision 1.3  2001/07/29 07:01:39  richard
260 # Added vim command to all source so that we don't get no steenkin' tabs :)
262 # Revision 1.2  2001/07/29 04:09:20  richard
263 # Added the fabricated property "id" to all hyperdb classes.
265 # Revision 1.1  2001/07/27 06:55:07  richard
266 # moving tests -> test
268 # Revision 1.7  2001/07/27 06:26:43  richard
269 # oops - wasn't deleting the test dir after the read-only tests
271 # Revision 1.6  2001/07/27 06:23:59  richard
272 # consistency
274 # Revision 1.5  2001/07/27 06:23:09  richard
275 # Added some new hyperdb tests to make sure we raise the right exceptions.
277 # Revision 1.4  2001/07/25 04:34:31  richard
278 # Added id and log to tests files...
281 # vim: set filetype=python ts=4 sw=4 et si