[Twisted-Python] Testing with trial, adbapi questions
Brendon Colby
brendoncolby at gmail.com
Mon Jun 25 11:17:24 EDT 2007
Greetings,
I've begun moving an application I wrote from asynchat to twisted.
I've got basic functionality, I've converted my DB stuff to adbapi and
have begun writing unit tests. I have a few questions that I haven't
been able to get answered through the API docs, twisted.words protocol
code, mailing list posts etc. I'd be very grateful for some
assistance!
1. Right now I'm defining my dbPool in my factory init, and running a
method to load some data from the DB. I've copied the IRC
BasicServerFunctionalityTestCase and modified it for my use:
class BasicServerFunctionalityTestCase(unittest.TestCase):
def setUp(self):
self.f = StringIOWithoutClosing()
self.t = FileWrapperThatWorks(self.f) # I need this to return
an IPv4Address!
self.p = sserverd.SServerProtocol()
self.p.factory = sserverd.SServerFactory(self.p)
self.p.makeConnection(self.t)
self.p.factory.dbPool.start()
def tearDown(self):
self.p.factory.dbPool.close()
def check(self, s):
self.assertEquals(self.f.getvalue(), s)
def testSendDeveloperID(self):
self.p.lineReceived('{%s:"PG"}\0' % sserverson.base10toN(104))
self.check("test\0")
I've gotten past the database threads hanging open by running start()
and close() manually. Now, my database callbacks that load necessary
data appear to be getting called AFTER my test runs. I know they're
getting called, but when the above test runs, the required data
structure is empty. What am I missing here?
2. I'm having a bit of trouble wrapping my head around adbapi. Prior
to it, one thing I would do is gather data and return a row, as in,
the method "developerExists()" would check the DB and return row[0][0]
or something (a bool). Now it seems as though I have to preload this
data and check against that. Can I replicate this behavior with
adbapi? Is there a better way than having to preload ALL my data up
front? How can I get any data from the DB like this:
data = getSomethingFromDB()
I'm suspicious that I need to adopt a new paradigm here, but am having
difficulty seeing past the old way of doing things!
3. I have some methods (as I pointed out in #1) that load data. With
adbapi, it appears that I have to do this:
def _loadDevelopers(self,results):
for result in results:
developerID = result[2]
...
self.addDeveloper(Developer(authHost,authUrl,developerID,self,rc4key,
postHost,postUrl))
def loadDevelopers(self):
self.dbPool.runQuery("select * from developers where active=1").addCallback(
self._loadDevelopers).addErrback(printError)
# Before, I would just load my data here!
Is this correct? i.e. a DB method that gets called, each having a
corresponding callback method that does the real work? (This seems
sort of a pain to me...) I feel as though I'm close to "getting it"
(twisted in general, adbapi) but feel that I have yet to connect some
key pieces of information.
4. I was digging through the adbapi code, and it appears that the only
type of result set I can get is a tuple (because only cursors are
used...). Is there a way I can get a dictionary returned, keys are
column names? i.e. a MySqlDB.fetch_row(how=1). I'm just not seeing how
I can do this with adbapi or, rather, how I can pass through to the
MySqlDB module to get this type of result set.
5. I've always run my application using DJB's daemontools
(http://cr.yp.to/daemontools.html). Is there an incredibly compelling
reason to switch to using twistd? It seems to have some pretty neat
features, but I'm just not 100% sure I want to give up daemontools
yet.
Thanks!
Brendon Colby
More information about the Twisted-Python
mailing list