def buildConnectionPool(testCase, schemaText="", dialect=SQLITE_DIALECT): """ Build a L{ConnectionPool} for testing purposes, with the given C{testCase}. @param testCase: the test case to attach the resulting L{ConnectionPool} to. @type testCase: L{twisted.trial.unittest.TestCase} @param schemaText: The text of the schema with which to initialize the database. @type schemaText: L{str} @return: a L{ConnectionPool} service whose C{startService} method has already been invoked. @rtype: L{ConnectionPool} """ sqlitename = testCase.mktemp() seqs = {} def connectionFactory(label=testCase.id()): conn = sqlite3.connect(sqlitename, isolation_level=None) def nextval(seq): result = seqs[seq] = seqs.get(seq, 0) + 1 return result conn.create_function("nextval", 1, nextval) return conn con = connectionFactory() con.executescript(schemaText) con.commit() pool = ConnectionPool(connectionFactory, paramstyle="numeric", dialect=SQLITE_DIALECT) pool.startService() testCase.addCleanup(pool.stopService) return pool
def makeAndCleanStore(self, testCase, notifierFactory, directoryService, attachmentRoot, enableJobProcessing=True): """ Create a L{CommonDataStore} specific to the given L{TestCase}. This also creates a L{ConnectionPool} that gets stopped when the test finishes, to make sure that any test which fails will terminate cleanly. @return: a L{Deferred} that fires with a L{CommonDataStore} """ # Always clean-out old attachments if attachmentRoot.exists(): attachmentRoot.remove() attachmentRoot.createDirectory() currentTestID = testCase.id() cp = ConnectionPool(self.sharedService.produceConnection, maxConnections=4) quota = deriveQuota(testCase) store = CommonDataStore( cp.connection, {"push": notifierFactory} if notifierFactory is not None else {}, directoryService, attachmentRoot, "https://example.com/calendars/__uids__/%(home)s/attachments/%(name)s", quota=quota) store.label = currentTestID cp.startService() @inlineCallbacks def stopIt(): txn = store.newTransaction() jobs = yield JobItem.all(txn) yield txn.commit() if len(jobs): print("Jobs left in job queue {}: {}".format( testCase, ",".join([job.workType for job in jobs]))) if enableJobProcessing: yield pool.stopService() # active transactions should have been shut down. wasBusy = len(cp._busy) busyText = repr(cp._busy) result = yield cp.stopService() if deriveValue(testCase, _SPECIAL_TXN_CLEAN, lambda tc: False): if wasBusy: testCase.fail("Outstanding Transactions: " + busyText) returnValue(result) returnValue(result) testCase.addCleanup(stopIt) yield self.cleanStore(testCase, store) # Start the job queue after store is up and cleaned if enableJobProcessing: pool = PeerConnectionPool(reactor, store.newTransaction, None) store.queuer = store.queuer.transferProposalCallbacks(pool) pool.startService() returnValue(store)