示例#1
0
    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_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 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"]])
示例#6
0
 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"))
示例#8
0
    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
示例#9
0
 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)
示例#10
0
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,
    )
示例#11
0
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()