def test_startService_withDumpFile(self): """ Assuming a properly configured environment ($PATH points at an 'initdb' and 'postgres', $PYTHONPATH includes pgdb), starting a L{PostgresService} will start the service passed to it, after importing an existing dump file. """ test = self class SimpleService1(Service): instances = [] ready = Deferred() def __init__(self, connectionFactory, storageService): self.connection = connectionFactory() test.addCleanup(self.connection.close) self.instances.append(self) def startService(self): cursor = self.connection.cursor() try: cursor.execute( "insert into import_test_table values ('value2')" ) except: self.ready.errback() else: self.ready.callback(None) finally: cursor.close() # The SQL in importFile.sql will get executed, including the insertion of "value1" importFileName = CachingFilePath(__file__).parent().child("importFile.sql").path svc = PostgresService( CachingFilePath("postgres_3.pgdb"), SimpleService1, "", databaseName="dummy_db", testMode=True, importFileName=importFileName ) svc.startService() self.addCleanup(svc.stopService) yield SimpleService1.ready connection = SimpleService1.instances[0].connection cursor = connection.cursor() cursor.execute("select * from import_test_table") values = cursor.fetchall() self.assertEquals(values, [["value1"], ["value2"]])
def test_startService_Socket(self): """ Assuming a properly configured environment ($PATH points at an 'initdb' and 'postgres', $PYTHONPATH includes pgdb), starting a L{PostgresService} will start the service passed to it, after executing the schema. """ test = self class SimpleService2(Service): instances = [] ready = Deferred() def __init__(self, connectionFactory, storageService): self.connection = connectionFactory() test.addCleanup(self.connection.close) self.instances.append(self) def startService(self): cursor = self.connection.cursor() try: cursor.execute( "insert into test_dummy_table values ('dummy')" ) except: self.ready.errback() else: self.ready.callback(None) finally: cursor.close() svc = PostgresService( CachingFilePath("postgres_2.pgdb"), SimpleService2, "create table TEST_DUMMY_TABLE (stub varchar)", databaseName="dummy_db", listenAddresses=['127.0.0.1', ], testMode=True ) svc.startService() self.addCleanup(svc.stopService) yield SimpleService2.ready connection = SimpleService2.instances[0].connection cursor = connection.cursor() cursor.execute("select * from test_dummy_table") values = cursor.fetchall() self.assertEquals(map(list, values), [["dummy"]])
def test_startDatabaseRunning(self): """ Ensure that if we can connect to postgres we don't spawn pg_ctl """ self.cursorHistory = [] class DummyCursor(object): def __init__(self, historyHolder): self.historyHolder = historyHolder def execute(self, *args): self.historyHolder.cursorHistory.append(args) def close(self): pass class DummyConnection(object): def __init__(self, historyHolder): self.historyHolder = historyHolder def cursor(self): return DummyCursor(self.historyHolder) def commit(self): pass def close(self): pass def produceConnection(*args): return DummyConnection(self) dummyReactor = DummyProcessReactor() svc = PostgresService( FilePath("postgres_4.pgdb"), lambda x : Service(), "", reactor=dummyReactor, ) svc.produceConnection = produceConnection svc.env = {} svc.startDatabase() self.assertEquals( self.cursorHistory, [ ('commit',), ("create database subpostgres with encoding 'UTF8'",), ('',) ] ) self.assertEquals(dummyReactor.spawnedProcesses, [])
def createService(self, serviceFactory): """ Create a L{PostgresService} to use for building a store. """ dbRoot = FilePath(self.sharedDBPath) if DB_TYPE[0] == POSTGRES_DIALECT: return PostgresService(dbRoot, serviceFactory, current_sql_schema, resetSchema=True, databaseName="caldav", options=[ "-c log_lock_waits=TRUE", "-c log_statement=all", "-c log_line_prefix='%p.%x '", "-c fsync=FALSE", "-c synchronous_commit=off", "-c full_page_writes=FALSE", "-c client-min-messages=warning", ], testMode=True) elif DB_TYPE[0] == ORACLE_DIALECT: return OracleService( dbRoot, serviceFactory, testMode=True, dsnUser=self.options.get("dsnUser"), )
def test_startDatabaseNotRunning(self): """ Ensure that if we can't connect to postgres we spawn pg_ctl """ def produceConnection(*args): raise pgdb.DatabaseError dummyReactor = DummyProcessReactor() svc = PostgresService( FilePath("postgres_4.pgdb"), lambda x : Service(), "", reactor=dummyReactor, ) svc.produceConnection = produceConnection svc.env = {} svc.startDatabase() self.assertEquals(len(dummyReactor.spawnedProcesses), 1) self.assertTrue(dummyReactor.spawnedProcesses[0]._executable.endswith("pg_ctl"))
def buildStore(self, testCase, notifierFactory): """ Do the necessary work to build a store for a particular test case. @return: a L{Deferred} which fires with an L{IDataStore}. """ currentTestID = testCase.id() dbRoot = CachingFilePath(self.SHARED_DB_PATH) if self.sharedService is None: ready = Deferred() def getReady(connectionFactory): attachmentRoot = dbRoot.child("attachments") try: attachmentRoot.createDirectory() except OSError: pass try: self.store = CommonDataStore( lambda label=None: connectionFactory( label or currentTestID ), notifierFactory, attachmentRoot ) except: ready.errback() raise else: self.cleanDatabase(testCase) ready.callback(self.store) return self.store self.sharedService = PostgresService( dbRoot, getReady, v1_schema, "caldav", resetSchema=True, testMode=True ) self.sharedService.startService() def startStopping(): log.msg("Starting stopping.") self.sharedService.unpauseMonitor() return self.sharedService.stopService() reactor.addSystemEventTrigger(#@UndefinedVariable "before", "shutdown", startStopping) result = ready else: self.store.notifierFactory = notifierFactory self.cleanDatabase(testCase) result = succeed(self.store) def cleanUp(): # FIXME: clean up any leaked connections and report them with an # immediate test failure. def stopit(): self.sharedService.pauseMonitor() return deferLater(reactor, 0.1, stopit) testCase.addCleanup(cleanUp) return result
def createService(self, serviceFactory): """ Create a L{PostgresService} to use for building a store. """ dbRoot = FilePath(self.sharedDBPath) return PostgresService(dbRoot, serviceFactory, current_sql_schema, resetSchema=True, databaseName="caldav", options=[ "-c log_lock_waits=TRUE", "-c log_statement=all", "-c log_line_prefix='%p.%x '", "-c fsync=FALSE", "-c synchronous_commit=off", "-c full_page_writes=FALSE", ], testMode=True)
def pgServiceFromConfig(config, subServiceFactory, uid=None, gid=None): """ Construct a L{PostgresService} from a given configuration and subservice. @param config: the configuration to derive postgres configuration parameters from. @param subServiceFactory: A factory for the service to start once the L{PostgresService} has been initialized. @param uid: The user-ID to run the PostgreSQL server as. @param gid: The group-ID to run the PostgreSQL server as. @return: a service which can start postgres. @rtype: L{PostgresService} """ dbRoot = CachingFilePath(config.DatabaseRoot) # Construct a PostgresService exactly as the parent would, so that we # can establish connection information. return PostgresService( dbRoot, subServiceFactory, current_sql_schema, databaseName=config.Postgres.DatabaseName, clusterName=config.Postgres.ClusterName, logFile=config.Postgres.LogFile, logDirectory=config.LogRoot if config.Postgres.LogRotation else "", socketDir=config.Postgres.SocketDirectory, listenAddresses=config.Postgres.ListenAddresses, sharedBuffers=config.Postgres.SharedBuffers, maxConnections=config.Postgres.MaxConnections, options=config.Postgres.Options, uid=uid, gid=gid, spawnedDBUser=config.SpawnedDBUser, importFileName=config.DBImportFile, pgCtl=config.Postgres.Ctl, initDB=config.Postgres.Init, )
class SQLStoreBuilder(object): """ Test-fixture-builder which can construct a PostgresStore. """ sharedService = None currentTestID = None SHARED_DB_PATH = "../_test_sql_db" def buildStore(self, testCase, notifierFactory): """ Do the necessary work to build a store for a particular test case. @return: a L{Deferred} which fires with an L{IDataStore}. """ currentTestID = testCase.id() dbRoot = CachingFilePath(self.SHARED_DB_PATH) if self.sharedService is None: ready = Deferred() def getReady(connectionFactory): attachmentRoot = dbRoot.child("attachments") try: attachmentRoot.createDirectory() except OSError: pass try: self.store = CommonDataStore( lambda label=None: connectionFactory( label or currentTestID ), notifierFactory, attachmentRoot ) except: ready.errback() raise else: self.cleanDatabase(testCase) ready.callback(self.store) return self.store self.sharedService = PostgresService( dbRoot, getReady, v1_schema, "caldav", resetSchema=True, testMode=True ) self.sharedService.startService() def startStopping(): log.msg("Starting stopping.") self.sharedService.unpauseMonitor() return self.sharedService.stopService() reactor.addSystemEventTrigger(#@UndefinedVariable "before", "shutdown", startStopping) result = ready else: self.store.notifierFactory = notifierFactory self.cleanDatabase(testCase) result = succeed(self.store) def cleanUp(): # FIXME: clean up any leaked connections and report them with an # immediate test failure. def stopit(): self.sharedService.pauseMonitor() return deferLater(reactor, 0.1, stopit) testCase.addCleanup(cleanUp) return result def cleanDatabase(self, testCase): cleanupConn = self.store.connectionFactory( "%s schema-cleanup" % (testCase.id(),) ) cursor = cleanupConn.cursor() tables = ['INVITE', 'RESOURCE_PROPERTY', 'ATTACHMENT', 'ADDRESSBOOK_OBJECT', 'CALENDAR_OBJECT', 'CALENDAR_BIND', 'ADDRESSBOOK_BIND', 'CALENDAR', 'ADDRESSBOOK', 'CALENDAR_HOME', 'ADDRESSBOOK_HOME', 'NOTIFICATION', 'NOTIFICATION_HOME'] for table in tables: try: cursor.execute("delete from "+table) except: log.err() cleanupConn.commit() cleanupConn.close()