Contact: fumanchu@aminus.org

Log in as guest/dejavu to create tickets

I think I've seen this ORM somewhere before...

root/trunk/storage/zoo_fixture.py

Revision 47 (checked in by fumanchu, 8 years ago)

1. AdapterToSQL now separates bool constants from bool expressions.
2. storage.db now has automatic connection pooling.
3. Fixed storeado against SQL Server (MSDE).
4. Added multithreading tests to zoo_fixture.

Line 
1 """Unit tests for Storage Managers.
2
3 Don't run this directly; call run_tests() from a script for a specific
4 Storage Manager, setting up and tearing down that SM as needed.
5 See test_store*.py in this directory.
6 """
7
8 import time
9 import unittest
10 import threading
11 import datetime
12 import dejavu
13 from dejavu import logic, zoo
14
15
16 class ZooTests(unittest.TestCase):
17    
18     def test_0_populate(self):
19         box = zoo.arena.new_sandbox()
20        
21         # Notice this also tests that: a Unit which is only
22         # dirtied via __init__ is still saved.
23         WAP = zoo.Zoo(Name = 'Wild Animal Park',
24                       Founded = datetime.date(2000, 1, 1),
25                       # 59 can give rounding errors with divmod, which
26                       # AdapterFromADO needs to correct.
27                       Opens = datetime.time(8, 15, 59),
28                       LastEscape = datetime.datetime(2004, 7, 29, 5, 6, 7),
29                       Admission = "4.95",
30                       )
31         box.memorize(WAP)
32        
33         SDZ = zoo.Zoo(Name = 'San Diego Zoo',
34                       # This early date should play havoc with a number
35                       # of implementations.
36                       Founded = datetime.date(1835, 9, 13),
37                       Opens = datetime.time(9, 0, 0),
38                       Admission = "0",
39                       )
40         box.memorize(SDZ)
41        
42         Biodome = zoo.Zoo(Name = u'Montr\xe9al Biod\xf4me',
43                           Founded = datetime.date(1992, 6, 19),
44                           Opens = datetime.time(9, 0, 0),
45                           Admission = "11.75",
46                           )
47        
48         leopard = zoo.Animal(Name='Leopard', Legs=4)
49         self.assertEqual(leopard.PreviousZoos, None)
50         box.memorize(leopard)
51         leopard.add(WAP)
52         leopard.LastEscape = datetime.datetime(2004, 12, 21, 8, 15, 0)
53        
54         box.memorize(zoo.Animal(Name='Slug', Legs=1))
55         box.memorize(zoo.Animal(Name='Tiger', Legs=4))
56         box.memorize(zoo.Animal(Name='Lion', Legs=4))
57         box.memorize(zoo.Animal(Name='Bear', Legs=4))
58         # Notice that ostrich.PreviousZoos is [], whereas leopard is None.
59         box.memorize(zoo.Animal(Name='Ostrich', Legs=2, PreviousZoos=[]))
60         box.memorize(zoo.Animal(Name='Centipede', Legs=100))
61        
62         millipede = zoo.Animal(Name='Millipede', Legs=1000000)
63         millipede.add(SDZ)
64         millipede.PreviousZoos = [WAP.ID]
65         box.memorize(millipede)
66        
67         box.flush_all()
68    
69     def test_1_Object_Properties(self):
70         box = zoo.arena.new_sandbox()
71        
72         WAP = box.unit(zoo.Zoo, Name='Wild Animal Park')
73         self.assertNotEqual(WAP, None)
74         self.assertEqual(WAP.Founded, datetime.date(2000, 1, 1))
75         self.assertEqual(WAP.Opens, datetime.time(8, 15, 59))
76         # This should have been updated when leopard.LastEscape was set.
77         self.assertEqual(WAP.LastEscape,
78                          datetime.datetime(2004, 12, 21, 8, 15, 0))
79         self.assertEqual(str(WAP.Admission), "4.95")
80        
81         SDZ = box.unit(zoo.Zoo, Founded=datetime.date(1835, 9, 13))
82         self.assertNotEqual(SDZ, None)
83         self.assertEqual(SDZ.Founded, datetime.date(1835, 9, 13))
84         self.assertEqual(SDZ.Opens, datetime.time(9, 0, 0))
85         self.assertEqual(SDZ.LastEscape, None)
86         self.assertEqual(float(SDZ.Admission), 0)
87        
88         leopard = box.unit(zoo.Animal, Name='Leopard')
89         self.assertEqual(leopard.Name, 'Leopard')
90         self.assertEqual(leopard.Legs, 4)
91         self.assertEqual(leopard.ZooID, WAP.ID)
92         self.assertEqual(leopard.PreviousZoos, None)
93         self.assertEqual(leopard.LastEscape,
94                          datetime.datetime(2004, 12, 21, 8, 15, 0))
95        
96         ostrich = box.unit(zoo.Animal, Name='Ostrich')
97         self.assertEqual(ostrich.Name, 'Ostrich')
98         self.assertEqual(ostrich.Legs, 2)
99         self.assertEqual(ostrich.ZooID, None)
100         self.assertEqual(ostrich.PreviousZoos, [])
101         self.assertEqual(ostrich.LastEscape, None)
102        
103         millipede = box.unit(zoo.Animal, Legs=1000000)
104         self.assertEqual(millipede.Name, 'Millipede')
105         self.assertEqual(millipede.Legs, 1000000)
106         self.assertEqual(millipede.ZooID, SDZ.ID)
107         self.assertEqual(millipede.PreviousZoos, [WAP.ID])
108         self.assertEqual(millipede.LastEscape, None)
109         box.flush_all()
110    
111     def test_2_Expressions(self):
112         box = zoo.arena.new_sandbox()
113        
114         def matches(lam):
115             # We flush_all to ensure a DB hit each time.
116             box.flush_all()
117             units = box.recall(zoo.Animal, logic.Expression(lam))
118             return len([x for x in units])
119        
120         zoos = [x for x in box.recall(zoo.Zoo)]
121         self.assertEqual(zoos[0].dirty(), False)
122         self.assertEqual(len(zoos), 2)
123         self.assertEqual(matches(lambda x: True), 8)
124         self.assertEqual(matches(lambda x: x.Legs == 4), 4)
125         self.assertEqual(matches(lambda x: x.Legs == 2), 1)
126         self.assertEqual(matches(lambda x: x.Legs >= 2 and x.Legs < 20), 5)
127         self.assertEqual(matches(lambda x: x.Legs > 10), 2)
128         self.assertEqual(matches(lambda x: x.Name.startswith('L')), 2)
129         self.assertEqual(matches(lambda x: x.Name.endswith('pede')), 2)
130         self.assertEqual(matches(lambda x: x.LastEscape != None), 1)
131         self.assertEqual(matches(lambda x: None == x.LastEscape), 7)
132 ##        self.assertRaises(ValueError, matches, lambda x: None is x.LastEscape)
133        
134         # In operator (containedby)
135         self.assertEqual(matches(lambda x: 'pede' in x.Name), 2)
136         self.assertEqual(matches(lambda x: x.Name in ('Lion', 'Tiger', 'Bear')), 3)
137        
138         # Try In with cell references
139         class thing(object): pass
140         pet, pet2 = thing(), thing()
141         pet.Name, pet2.Name = 'Slug', 'Ostrich'
142         self.assertEqual(matches(lambda x: x.Name in (pet.Name, pet2.Name)), 2)
143        
144         # logic and other functions
145         self.assertEqual(matches(lambda x: dejavu.ieq(x.Name, 'slug')), 1)
146         self.assertEqual(matches(lambda x: dejavu.icontains(x.Name, 'PEDE')), 2)
147         self.assertEqual(matches(lambda x: dejavu.icontains(('Lion', 'Banana'), x.Name)), 1)
148         self.assertEqual(matches(lambda x: dejavu.icontainedby(x.Name, ('Lion', 'Bear', 'Leopard'))), 3)
149         name = 'Lion'
150         self.assertEqual(matches(lambda x: len(x.Name) == len(name)), 3)
151        
152         # This broke sometime in 2004. Rev 32 seems to have fixed it.
153         self.assertEqual(matches(lambda x: 'i' in x.Name), 5)
154        
155         # Test now(), today(), year()
156         self.assertEqual(matches(lambda x: x.LastEscape != None
157                                  and x.LastEscape < dejavu.today()), 1)
158         self.assertEqual(matches(lambda x: x.LastEscape == dejavu.now()), 0)
159         self.assertEqual(matches(lambda x: dejavu.year(x.LastEscape) == 2004), 1)
160        
161         # Test AND, OR with cannot_represent.
162         # Notice that we reference a method ('count') which no
163         # known SM handles, so it will default back to Expr.eval().
164         self.assertEqual(matches(lambda x: 'p' in x.Name
165                                  and x.Name.count('e') > 1), 2)
166    
167     def test_3_Aggregates(self):
168         box = zoo.arena.new_sandbox()
169         legs = box.distinct(zoo.Animal, ['Legs'])
170         legs.sort()
171         self.assertEqual(legs, [1, 2, 4, 100, 1000000])
172    
173     def test_4_Multithreading(self):
174         f = logic.Expression(lambda x: x.Legs == 4)
175         def thread_recall():
176             # Notice we only do reads in this thread, not writes, since
177             # the order of thread execution can not be guaranteed.
178             box = zoo.arena.new_sandbox()
179             quadrupeds = [x for x in box.recall(zoo.Animal, f)]
180             self.assertEqual(len(quadrupeds), 4)
181        
182         ts = []
183         # PostgreSQL, for example, has a default max_connections of 100.
184         for x in range(99):
185             t = threading.Thread(target=thread_recall)
186             t.start()
187             ts.append(t)
188         for t in ts:
189             t.join()
190
191
192 def setup_SM(SM_class, opts):
193     """main(SM_class, PreviousZoos) -> Set up the arena and SM for Zoo."""
194     if isinstance(SM_class, basestring):
195         import xray
196         SM_class = xray.classes(SM_class)
197     testSM = SM_class("test", zoo.arena, opts)
198     zoo.arena.add_store('testSM', testSM)
199    
200     for cls in (zoo.Animal, zoo.Zoo, zoo.Exhibit):
201         zoo.arena.create_storage(cls)
202
203 def teardown():
204     zoo.arena.shutdown()
205     for store in zoo.arena.stores.values():
206         try:
207             store.drop_database()
208         except NotImplementedError:
209             pass
210
211 def run_tests(SM_class, opts):
212     import traceback
213     try:
214         try:
215             setup_SM(SM_class, opts)
216             unittest.main(__name__)
217         except SystemExit:
218             # unittest.main normally raises SystemExit when complete.
219             pass
220         except:
221             traceback.print_exc()
222             print
223     finally:
224         teardown()
225
Note: See TracBrowser for help on using the browser.