| 1 |
# sAsync: |
|---|
| 2 |
# An enhancement to the SQLAlchemy package that provides persistent |
|---|
| 3 |
# dictionaries, text indexing and searching, and an access broker for |
|---|
| 4 |
# conveniently managing database access, table setup, and |
|---|
| 5 |
# transactions. Everything can be run in an asynchronous fashion using the |
|---|
| 6 |
# Twisted framework and its deferred processing capabilities. |
|---|
| 7 |
# |
|---|
| 8 |
# Copyright (C) 2006 by Edwin A. Suominen, http://www.eepatents.com |
|---|
| 9 |
# |
|---|
| 10 |
# This program is free software; you can redistribute it and/or modify it under |
|---|
| 11 |
# the terms of the GNU General Public License as published by the Free Software |
|---|
| 12 |
# Foundation; either version 2 of the License, or (at your option) any later |
|---|
| 13 |
# version. |
|---|
| 14 |
# |
|---|
| 15 |
# This program is distributed in the hope that it will be useful, but WITHOUT |
|---|
| 16 |
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
|---|
| 17 |
# FOR A PARTICULAR PURPOSE. See the file COPYING for more details. |
|---|
| 18 |
# |
|---|
| 19 |
# You should have received a copy of the GNU General Public License along with |
|---|
| 20 |
# this program; if not, write to the Free Software Foundation, Inc., 51 |
|---|
| 21 |
# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA |
|---|
| 22 |
|
|---|
| 23 |
""" |
|---|
| 24 |
Unit tests for sasync.pdict.py. |
|---|
| 25 |
""" |
|---|
| 26 |
|
|---|
| 27 |
import os |
|---|
| 28 |
from twisted.internet import defer, reactor |
|---|
| 29 |
from twisted.trial.unittest import TestCase |
|---|
| 30 |
|
|---|
| 31 |
import sqlalchemy as SA |
|---|
| 32 |
import sasync |
|---|
| 33 |
from sasync.pdict import PersistentDict |
|---|
| 34 |
from sasync.parray import PersistentArray |
|---|
| 35 |
|
|---|
| 36 |
ID = 341 |
|---|
| 37 |
VERBOSE = False |
|---|
| 38 |
|
|---|
| 39 |
|
|---|
| 40 |
db = '/tmp/pdict.db' |
|---|
| 41 |
URL = "sqlite:///%s" % db |
|---|
| 42 |
sasync.engine(URL) |
|---|
| 43 |
|
|---|
| 44 |
|
|---|
| 45 |
def itemsEqual(itemsA, itemsB): |
|---|
| 46 |
if VERBOSE: |
|---|
| 47 |
print "\n%s\n\tvs\n%s\n" % (str(itemsA), str(itemsB)) |
|---|
| 48 |
for item in itemsA: |
|---|
| 49 |
if not itemsB.count(item): |
|---|
| 50 |
print "Item '%s' of list A not in list B" % (item,) |
|---|
| 51 |
return False |
|---|
| 52 |
for item in itemsB: |
|---|
| 53 |
if not itemsA.count(item): |
|---|
| 54 |
print "Item '%s' of list B not in list A" % (item,) |
|---|
| 55 |
return False |
|---|
| 56 |
return True |
|---|
| 57 |
|
|---|
| 58 |
|
|---|
| 59 |
class TestPlayNice(TestCase): |
|---|
| 60 |
def testShutdown(self): |
|---|
| 61 |
def first(null): |
|---|
| 62 |
y = PersistentDict('alpha') |
|---|
| 63 |
d = y['eagle'] |
|---|
| 64 |
d.addCallback(self.failUnlessEqual, 'bald') |
|---|
| 65 |
return d |
|---|
| 66 |
|
|---|
| 67 |
x = PersistentDict('alpha') |
|---|
| 68 |
x['eagle'] = 'bald' |
|---|
| 69 |
d = x.shutdown() |
|---|
| 70 |
d.addCallback(first) |
|---|
| 71 |
return d |
|---|
| 72 |
|
|---|
| 73 |
def testSequentiallyStartedDicts(self): |
|---|
| 74 |
x = PersistentDict('alpha') |
|---|
| 75 |
y = PersistentDict('bravo') |
|---|
| 76 |
|
|---|
| 77 |
def first(): |
|---|
| 78 |
d = x.preload() |
|---|
| 79 |
d.addCallback(lambda _: y.preload()) |
|---|
| 80 |
return d |
|---|
| 81 |
|
|---|
| 82 |
def second(null): |
|---|
| 83 |
x['a'] = 1 |
|---|
| 84 |
y['a'] = 10 |
|---|
| 85 |
return defer.DeferredList([x.deferToWrites(), y.deferToWrites()]) |
|---|
| 86 |
|
|---|
| 87 |
def third(null): |
|---|
| 88 |
self.failUnlessEqual(x['a'], 1) |
|---|
| 89 |
self.failUnlessEqual(y['a'], 10) |
|---|
| 90 |
return defer.DeferredList([x.shutdown(), y.shutdown()]) |
|---|
| 91 |
|
|---|
| 92 |
d = first() |
|---|
| 93 |
d.addCallback(second) |
|---|
| 94 |
d.addCallback(third) |
|---|
| 95 |
return d |
|---|
| 96 |
|
|---|
| 97 |
def testThreeSeparateDicts(self): |
|---|
| 98 |
def first(): |
|---|
| 99 |
self.x['a'] = 1 |
|---|
| 100 |
self.y['a'] = 10 |
|---|
| 101 |
self.z['a'] = 100 |
|---|
| 102 |
return defer.DeferredList([ |
|---|
| 103 |
self.x.deferToWrites(), |
|---|
| 104 |
self.y.deferToWrites(), |
|---|
| 105 |
self.z.deferToWrites()]) |
|---|
| 106 |
|
|---|
| 107 |
def second(null): |
|---|
| 108 |
d = self.x['a'] |
|---|
| 109 |
d.addCallback(self.failUnlessEqual, 1) |
|---|
| 110 |
d.addCallback(lambda _: self.y['a']) |
|---|
| 111 |
d.addCallback(self.failUnlessEqual, 10) |
|---|
| 112 |
d.addCallback(lambda _: self.z['a']) |
|---|
| 113 |
d.addCallback(self.failUnlessEqual, 100) |
|---|
| 114 |
return d |
|---|
| 115 |
|
|---|
| 116 |
def third(null): |
|---|
| 117 |
def wait(): |
|---|
| 118 |
d = defer.Deferred() |
|---|
| 119 |
reactor.callLater(1.0, d.callback, None) |
|---|
| 120 |
return d |
|---|
| 121 |
|
|---|
| 122 |
def thisOneShutdown(null, objectName): |
|---|
| 123 |
print "Done shutting down PDict '%s'" % objectName |
|---|
| 124 |
|
|---|
| 125 |
dList = [] |
|---|
| 126 |
for objectName in ('x', 'y', 'z'): |
|---|
| 127 |
d1 = getattr(self, objectName).shutdown() |
|---|
| 128 |
if VERBOSE: |
|---|
| 129 |
print "\nAbout to shut down Pdict '%s'" % objectName |
|---|
| 130 |
d1.addCallback(thisOneShutdown, objectName) |
|---|
| 131 |
d2 = wait() |
|---|
| 132 |
dList.append(defer.DeferredList([d1,d2])) |
|---|
| 133 |
return defer.DeferredList(dList) |
|---|
| 134 |
|
|---|
| 135 |
self.x = PersistentDict('alpha') |
|---|
| 136 |
self.y = PersistentDict('bravo') |
|---|
| 137 |
self.z = PersistentDict('charlie') |
|---|
| 138 |
|
|---|
| 139 |
d = first() |
|---|
| 140 |
d.addCallback(second) |
|---|
| 141 |
d.addCallback(third) |
|---|
| 142 |
return d |
|---|
| 143 |
|
|---|
| 144 |
def testThreeSeparatePreloadedDicts(self): |
|---|
| 145 |
def first(): |
|---|
| 146 |
d1 = self.x.preload() |
|---|
| 147 |
d2 = self.y.preload() |
|---|
| 148 |
d3 = self.z.preload() |
|---|
| 149 |
d4 = defer.Deferred() |
|---|
| 150 |
reactor.callLater(0.5, d4.callback, None) |
|---|
| 151 |
return defer.DeferredList([d1,d2,d3,d4]) |
|---|
| 152 |
|
|---|
| 153 |
def second(null): |
|---|
| 154 |
self.x['a'] = 1 |
|---|
| 155 |
self.y['a'] = 10 |
|---|
| 156 |
self.z['a'] = 100 |
|---|
| 157 |
return defer.DeferredList([ |
|---|
| 158 |
self.x.deferToWrites(), |
|---|
| 159 |
self.y.deferToWrites(), |
|---|
| 160 |
self.z.deferToWrites()]) |
|---|
| 161 |
|
|---|
| 162 |
def third(null): |
|---|
| 163 |
self.failUnlessEqual(self.x['a'], 1) |
|---|
| 164 |
self.failUnlessEqual(self.y['a'], 10) |
|---|
| 165 |
self.failUnlessEqual(self.z['a'], 100) |
|---|
| 166 |
|
|---|
| 167 |
def fourth(null): |
|---|
| 168 |
def wait(): |
|---|
| 169 |
d = defer.Deferred() |
|---|
| 170 |
reactor.callLater(1.0, d.callback, None) |
|---|
| 171 |
return d |
|---|
| 172 |
|
|---|
| 173 |
def thisOneShutdown(null, objectName): |
|---|
| 174 |
print "Done shutting down PDict '%s'" % objectName |
|---|
| 175 |
|
|---|
| 176 |
dList = [] |
|---|
| 177 |
for objectName in ('x', 'y', 'z'): |
|---|
| 178 |
d1 = getattr(self, objectName).shutdown() |
|---|
| 179 |
if VERBOSE: |
|---|
| 180 |
print "\nAbout to shut down Pdict '%s'" % objectName |
|---|
| 181 |
d1.addCallback(thisOneShutdown, objectName) |
|---|
| 182 |
d2 = wait() |
|---|
| 183 |
dList.append(defer.DeferredList([d1,d2])) |
|---|
| 184 |
return defer.DeferredList(dList) |
|---|
| 185 |
|
|---|
| 186 |
self.x = PersistentDict('alpha') |
|---|
| 187 |
self.y = PersistentDict('bravo') |
|---|
| 188 |
self.z = PersistentDict('charlie') |
|---|
| 189 |
|
|---|
| 190 |
d = first() |
|---|
| 191 |
d.addCallback(second) |
|---|
| 192 |
d.addCallback(third) |
|---|
| 193 |
d.addCallback(fourth) |
|---|
| 194 |
return d |
|---|
| 195 |
|
|---|
| 196 |
def testOneDictWithParray(self): |
|---|
| 197 |
import sasync.parray as parray |
|---|
| 198 |
|
|---|
| 199 |
x = PersistentDict('foo') |
|---|
| 200 |
y = PersistentArray('bar') |
|---|
| 201 |
|
|---|
| 202 |
def first(): |
|---|
| 203 |
x['a'] = 1 |
|---|
| 204 |
return x.deferToWrites() |
|---|
| 205 |
|
|---|
| 206 |
def second(null): |
|---|
| 207 |
d = x['a'] |
|---|
| 208 |
d.addCallback(self.failUnlessEqual, 1) |
|---|
| 209 |
return d |
|---|
| 210 |
|
|---|
| 211 |
def third(null): |
|---|
| 212 |
return defer.DeferredList([x.shutdown(), y.shutdown()]) |
|---|
| 213 |
|
|---|
| 214 |
d = first() |
|---|
| 215 |
d.addCallback(second) |
|---|
| 216 |
d.addCallback(third) |
|---|
| 217 |
return d |
|---|
| 218 |
|
|---|
| 219 |
def testTwoDictsWithParray(self): |
|---|
| 220 |
import sasync.parray as parray |
|---|
| 221 |
|
|---|
| 222 |
x = PersistentDict('foo') |
|---|
| 223 |
y = PersistentDict('bar') |
|---|
| 224 |
z = PersistentArray('whatever') |
|---|
| 225 |
|
|---|
| 226 |
def first(): |
|---|
| 227 |
x['a'] = 1 |
|---|
| 228 |
y['a'] = 10 |
|---|
| 229 |
return defer.DeferredList([x.deferToWrites(), y.deferToWrites()]) |
|---|
| 230 |
|
|---|
| 231 |
def second(null): |
|---|
| 232 |
d = x['a'] |
|---|
| 233 |
d.addCallback(self.failUnlessEqual, 1) |
|---|
| 234 |
d.addCallback(lambda _: y['a']) |
|---|
| 235 |
d.addCallback(self.failUnlessEqual, 10) |
|---|
| 236 |
return d |
|---|
| 237 |
|
|---|
| 238 |
def third(null): |
|---|
| 239 |
return defer.DeferredList([ |
|---|
| 240 |
x.shutdown(), y.shutdown(), z.shutdown()]) |
|---|
| 241 |
|
|---|
| 242 |
d = first() |
|---|
| 243 |
d.addCallback(second) |
|---|
| 244 |
d.addCallback(third) |
|---|
| 245 |
return d |
|---|
| 246 |
|
|---|
| 247 |
|
|---|
| 248 |
class Pdict: |
|---|
| 249 |
def tearDown(self): |
|---|
| 250 |
return self.p.shutdown() |
|---|
| 251 |
|
|---|
| 252 |
def writeToDB(self, **items): |
|---|
| 253 |
def _writeToDB(insertionList): |
|---|
| 254 |
if VERBOSE: |
|---|
| 255 |
print "\nWRITE-TO-DB", insertionList, "\n\n" |
|---|
| 256 |
self.pit.sasync_items.insert().execute(*insertionList) |
|---|
| 257 |
|
|---|
| 258 |
insertionList = [] |
|---|
| 259 |
for name, value in items.iteritems(): |
|---|
| 260 |
insertionList.append({'group_id':ID, 'name':name, 'value':value}) |
|---|
| 261 |
return self.pit.deferToQueue(_writeToDB, insertionList) |
|---|
| 262 |
|
|---|
| 263 |
def clearDB(self): |
|---|
| 264 |
def _clearDB(): |
|---|
| 265 |
if VERBOSE: |
|---|
| 266 |
print "\nCLEAR-DB\n" |
|---|
| 267 |
self.pit.sasync_items.delete( |
|---|
| 268 |
self.pit.sasync_items.c.group_id == ID).execute() |
|---|
| 269 |
|
|---|
| 270 |
return self.pit.deferToQueue(_clearDB) |
|---|
| 271 |
|
|---|
| 272 |
|
|---|
| 273 |
class PdictNormal(Pdict): |
|---|
| 274 |
def setUp(self): |
|---|
| 275 |
def started(null): |
|---|
| 276 |
self.pit = self.p.i.t |
|---|
| 277 |
self.p.data.clear() |
|---|
| 278 |
return self.pit.deferToQueue(clear) |
|---|
| 279 |
|
|---|
| 280 |
def clear(): |
|---|
| 281 |
si = self.pit.sasync_items |
|---|
| 282 |
si.delete(si.c.group_id == ID).execute() |
|---|
| 283 |
|
|---|
| 284 |
self.p = PersistentDict(ID) |
|---|
| 285 |
d = self.p.i.t.startup() |
|---|
| 286 |
d.addCallback(started) |
|---|
| 287 |
return d |
|---|
| 288 |
|
|---|
| 289 |
|
|---|
| 290 |
class TestPdictNormalCore(PdictNormal, TestCase): |
|---|
| 291 |
def testSomeWriteSomeSet(self): |
|---|
| 292 |
def setStuff(null): |
|---|
| 293 |
self.p['b'] = 'beta' |
|---|
| 294 |
self.p['d'] = 'delta' |
|---|
| 295 |
d = self.p.deferToWrites() |
|---|
| 296 |
d.addCallback(lambda _: self.p.items()) |
|---|
| 297 |
d.addCallback( |
|---|
| 298 |
itemsEqual, |
|---|
| 299 |
[('a','alpha'), ('b','beta'), ('c','charlie'), ('d','delta')]) |
|---|
| 300 |
d.addCallback(self.failUnless, "Items not equal") |
|---|
| 301 |
return d |
|---|
| 302 |
|
|---|
| 303 |
d = self.writeToDB(a='alpha', b='bravo', c='charlie') |
|---|
| 304 |
d.addCallback(setStuff) |
|---|
| 305 |
return d |
|---|
| 306 |
|
|---|
| 307 |
def testWriteAndGet(self): |
|---|
| 308 |
d = self.writeToDB(a=100, b=200, c='foo') |
|---|
| 309 |
d.addCallback(lambda _: self.p['a']) |
|---|
| 310 |
d.addCallback(self.failUnlessEqual, 100) |
|---|
| 311 |
d.addCallback(lambda _: self.p['b']) |
|---|
| 312 |
d.addCallback(self.failUnlessEqual, 200) |
|---|
| 313 |
d.addCallback(lambda _: self.p['c']) |
|---|
| 314 |
d.addCallback(self.failUnlessEqual, 'foo') |
|---|
| 315 |
return d |
|---|
| 316 |
|
|---|
| 317 |
|
|---|
| 318 |
class TestPdictNormalMain(PdictNormal, TestCase): |
|---|
| 319 |
def testLoadAll(self): |
|---|
| 320 |
def checkItems(items): |
|---|
| 321 |
self.failUnlessEqual(items, {'a':1, 'b':2}) |
|---|
| 322 |
|
|---|
| 323 |
d = self.writeToDB(a=1, b=2) |
|---|
| 324 |
d.addCallback(lambda _: self.p.loadAll()) |
|---|
| 325 |
d.addCallback(checkItems) |
|---|
| 326 |
return d |
|---|
| 327 |
|
|---|
| 328 |
def testSetAndGet(self): |
|---|
| 329 |
self.p['a'] = 10 |
|---|
| 330 |
d = self.p.deferToWrites() |
|---|
| 331 |
d.addCallback(lambda _: self.p['a']) |
|---|
| 332 |
d.addCallback(self.failUnlessEqual, 10) |
|---|
| 333 |
return d |
|---|
| 334 |
|
|---|
| 335 |
def testSetAndLoadAll(self): |
|---|
| 336 |
self.p['a'] = 1 |
|---|
| 337 |
self.p['b'] = 2 |
|---|
| 338 |
|
|---|
| 339 |
d = self.p.deferToWrites() |
|---|
| 340 |
d.addCallback(lambda _: self.p.loadAll()) |
|---|
| 341 |
d.addCallback(self.failUnlessEqual, {'a':1, 'b':2}) |
|---|
| 342 |
return d |
|---|
| 343 |
|
|---|
| 344 |
def testSetdefaultEmpty(self): |
|---|
| 345 |
self.p['a'] = 1 |
|---|
| 346 |
self.p.writeTracker.put(self.p.setdefault('b', 2)) |
|---|
| 347 |
|
|---|
| 348 |
d = self.p.deferToWrites() |
|---|
| 349 |
d.addCallback(lambda _: self.p.loadAll()) |
|---|
| 350 |
d.addCallback(self.failUnlessEqual, {'a':1, 'b':2}) |
|---|
| 351 |
return d |
|---|
| 352 |
|
|---|
| 353 |
def testSetClearAndLoadAll(self): |
|---|
| 354 |
self.p['a'] = 1 |
|---|
| 355 |
self.p['b'] = 2 |
|---|
| 356 |
self.p.clear() |
|---|
| 357 |
d = self.p.deferToWrites() |
|---|
| 358 |
d.addCallback(lambda _: self.p.loadAll()) |
|---|
| 359 |
d.addCallback(self.failUnlessEqual, {}) |
|---|
| 360 |
return d |
|---|
| 361 |
|
|---|
| 362 |
def testSetdefaultSet(self): |
|---|
| 363 |
self.p['a'] = 1 |
|---|
| 364 |
self.p.writeTracker.put(self.p.setdefault('a', 2)) |
|---|
| 365 |
|
|---|
| 366 |
d = self.p.deferToWrites() |
|---|
| 367 |
d.addCallback(lambda _: self.p.items()) |
|---|
| 368 |
d.addCallback(self.failUnlessEqual, [('a',1)]) |
|---|
| 369 |
return d |
|---|
| 370 |
|
|---|
| 371 |
def testSetAndGetComplex(self): |
|---|
| 372 |
self.p['a'] = 1 |
|---|
| 373 |
self.p['b'] = 2 |
|---|
| 374 |
self.p.writeTracker.put(self.p.setdefault('b', 20)) |
|---|
| 375 |
self.p.writeTracker.put(self.p.setdefault('c', 3)) |
|---|
| 376 |
self.p.update({'d':4, 'e':5}) |
|---|
| 377 |
|
|---|
| 378 |
d = self.p.deferToWrites() |
|---|
| 379 |
d.addCallback(lambda _: self.p.items()) |
|---|
| 380 |
d.addCallback(itemsEqual, [('a',1), ('b',2), ('c',3), ('d',4), ('e',5)]) |
|---|
| 381 |
d.addCallback(self.failUnless, "Items not equal") |
|---|
| 382 |
return d |
|---|
| 383 |
|
|---|
| 384 |
def testKeys(self): |
|---|
| 385 |
d = self.writeToDB(a=1.1, b=1.2, c=1.3) |
|---|
| 386 |
d.addCallback(lambda _: self.p.keys()) |
|---|
| 387 |
d.addCallback(itemsEqual, ['a', 'b', 'c']) |
|---|
| 388 |
d.addCallback(self.failUnless) |
|---|
| 389 |
return d |
|---|
| 390 |
|
|---|
| 391 |
def testValues(self): |
|---|
| 392 |
d = self.writeToDB(a=1.1, b=1.2, c=1.3) |
|---|
| 393 |
d.addCallback(lambda _: self.p.values()) |
|---|
| 394 |
d.addCallback(itemsEqual, [1.1, 1.2, 1.3]) |
|---|
| 395 |
d.addCallback(self.failUnless) |
|---|
| 396 |
return d |
|---|
| 397 |
|
|---|
| 398 |
def testItems(self): |
|---|
| 399 |
d = self.writeToDB(a=2.1, b=2.2, c=2.3) |
|---|
| 400 |
d.addCallback(lambda _: self.p.items()) |
|---|
| 401 |
d.addCallback(itemsEqual, [('a',2.1), ('b',2.2), ('c',2.3)]) |
|---|
| 402 |
d.addCallback(self.failUnless) |
|---|
| 403 |
return d |
|---|
| 404 |
|
|---|
| 405 |
def testContains(self): |
|---|
| 406 |
def one(null): |
|---|
| 407 |
d = self.p.has_key('a') |
|---|
| 408 |
d.addCallback( |
|---|
| 409 |
self.failUnless, "Item 'a' should be in the dictionary") |
|---|
| 410 |
return d |
|---|
| 411 |
|
|---|
| 412 |
def another(null): |
|---|
| 413 |
d = self.p.has_key('d') |
|---|
| 414 |
d.addCallback(self.failIf, "Item 'd' shouldn't be in the dictionary") |
|---|
| 415 |
return d |
|---|
| 416 |
|
|---|
| 417 |
d = self.clearDB() |
|---|
| 418 |
d.addCallback(lambda _: self.writeToDB(a=1.1, b=1.2, c=1.3)) |
|---|
| 419 |
d.addCallback(one) |
|---|
| 420 |
d.addCallback(another) |
|---|
| 421 |
return d |
|---|
| 422 |
|
|---|
| 423 |
def testGetMethod(self): |
|---|
| 424 |
d = self.clearDB() |
|---|
| 425 |
d.addCallback(lambda _: self.writeToDB(a='present')) |
|---|
| 426 |
d.addCallback(lambda _: self.p.get('a', None)) |
|---|
| 427 |
d.addCallback(self.failUnlessEqual, 'present') |
|---|
| 428 |
d.addCallback(lambda _: self.p.get('b', None)) |
|---|
| 429 |
d.addCallback(self.failUnlessEqual, None) |
|---|
| 430 |
return d |
|---|
| 431 |
|
|---|
| 432 |
|
|---|
| 433 |
class PdictPreload(Pdict): |
|---|
| 434 |
def setUp(self): |
|---|
| 435 |
def started(null): |
|---|
| 436 |
self.pit = self.p.i.t |
|---|
| 437 |
self.p.data.clear() |
|---|
| 438 |
return self.pit.deferToQueue(clear) |
|---|
| 439 |
|
|---|
| 440 |
def clear(): |
|---|
| 441 |
si = self.pit.sasync_items |
|---|
| 442 |
si.delete(si.c.group_id == ID).execute() |
|---|
| 443 |
|
|---|
| 444 |
self.p = PersistentDict(ID) |
|---|
| 445 |
d = self.p.preload() |
|---|
| 446 |
d.addCallback(started) |
|---|
| 447 |
return d |
|---|
| 448 |
|
|---|
| 449 |
|
|---|
| 450 |
class TestPdictPreload(PdictPreload, TestCase): |
|---|
| 451 |
def testSetAndGet(self): |
|---|
| 452 |
self.p['a'] = 10 |
|---|
| 453 |
self.failUnlessEqual(self.p['a'], 10) |
|---|
| 454 |
|
|---|
| 455 |
def testSetActuallyWrites(self): |
|---|
| 456 |
def first(null): |
|---|
| 457 |
self.p['a'] = 'new' |
|---|
| 458 |
return self.p.deferToWrites() |
|---|
| 459 |
def second(null): |
|---|
| 460 |
def _second(): |
|---|
| 461 |
si = self.pit.sasync_items |
|---|
| 462 |
row = si.select( |
|---|
| 463 |
SA.and_( |
|---|
| 464 |
si.c.group_id==ID, si.c.name=='a')).execute().fetchone() |
|---|
| 465 |
return row['value'] |
|---|
| 466 |
return self.pit.deferToQueue(_second) |
|---|
| 467 |
d = self.clearDB() |
|---|
| 468 |
d.addCallback(first) |
|---|
| 469 |
d.addCallback(second) |
|---|
| 470 |
d.addCallback(self.failUnlessEqual, 'new') |
|---|
| 471 |
return d |
|---|