예제 #1
0
    def testCreatingInMemoryStoreUsingConfig(self):
        """Full test of `construct_eventstore(...)`."""
        config = configparser.ConfigParser()
        config.add_section("general")
        config.set("general", "storage-backend", "estoresection")
        config.add_section("estoresection")

        config.set("estoresection", "class",
                   "rewind.server.eventstores.InMemoryEventStore")

        estore = rconfig.construct_eventstore(config)

        self.assertIsInstance(estore, eventstores.InMemoryEventStore)
예제 #2
0
    def testCreatingInMemoryStoreUsingConfigWithGivenSection(self):
        """Test full test of `construct_eventstore(...)` given a section."""
        config = configparser.ConfigParser()
        config.add_section("estoresection")
        # The 'general' section need not to be defined here since a section is
        # given to `construct_eventstore(...)` below.

        config.set("estoresection", "class",
                   "rewind.server.eventstores.InMemoryEventStore")

        estore = rconfig.construct_eventstore(config, "estoresection")

        self.assertIsInstance(estore, eventstores.InMemoryEventStore)
예제 #3
0
    def testCreatingInMemoryStoreUsingConfigWithGivenSection(self):
        """Test full test of `construct_eventstore(...)` given a section."""
        config = configparser.ConfigParser()
        config.add_section("estoresection")
        # The 'general' section need not to be defined here since a section is
        # given to `construct_eventstore(...)` below.

        config.set("estoresection", "class",
                   "rewind.server.eventstores.InMemoryEventStore")

        estore = rconfig.construct_eventstore(config, "estoresection")

        self.assertIsInstance(estore, eventstores.InMemoryEventStore)
예제 #4
0
    def testCreatingInMemoryStoreUsingConfig(self):
        """Full test of `construct_eventstore(...)`."""
        config = configparser.ConfigParser()
        config.add_section("general")
        config.set("general", "storage-backend", "estoresection")
        config.add_section("estoresection")

        config.set("estoresection", "class",
                   "rewind.server.eventstores.InMemoryEventStore")

        estore = rconfig.construct_eventstore(config)

        self.assertIsInstance(estore, eventstores.InMemoryEventStore)
예제 #5
0
    def _testCreateCombinedRotatedLogFromConfig(self, defaults):
        """Creating combined rotated store from config.

        This class function is a helper for the actual tests.

        Parameters:
        defaults -- whether default values should be used or not for
                    `SyncedRotationEventStores` instantiation. Can be used to
                    toggle execution of different conditional branches to
                    improve coverage.

        """
        path = tempfile.mkdtemp()
        print("Using temporary directory:", path)

        config = configparser.ConfigParser()

        config.add_section("rotated_sqlite")
        config.set("rotated_sqlite", "class",
                   "rewind.server.eventstores.RotatedEventStore")
        config.set("rotated_sqlite", "realclass",
                   "rewind.server.eventstores.SQLiteEventStore")
        config.set("rotated_sqlite", "prefix", "sqlite")
        config.set("rotated_sqlite", "path", path)

        config.add_section("rotated_appendlog")
        config.set("rotated_appendlog", "class",
                   "rewind.server.eventstores.RotatedEventStore")
        config.set("rotated_appendlog", "realclass",
                   "rewind.server.eventstores.LogEventStore")
        config.set("rotated_appendlog", "prefix", "appendlog")
        config.set("rotated_appendlog", "path", path)

        config.add_section("synced_rotator")
        config.set("synced_rotator", "class",
                   "rewind.server.eventstores.SyncedRotationEventStores")
        config.set("synced_rotator", "storage-backends",
                   "rotated_sqlite rotated_appendlog")
        if not defaults:
            config.set("synced_rotator", "events_per_batch", "25000")

        # Random option to have coverage of logging of unknown options
        config.set("synced_rotator", "foo", "bar")

        estore = rconfig.construct_eventstore(config, "synced_rotator")

        self.assertIsInstance(estore, eventstores.SyncedRotationEventStores)

        shutil.rmtree(path)
예제 #6
0
    def testCreatingSyncedRotatedLogFromConfigFromConfig(self):
        """Create a `RotatedEventStore` from config."""
        path = tempfile.mkdtemp()
        print("Using temporary directory:", path)

        config = configparser.ConfigParser()

        config.add_section("rotated_sqlite")
        config.set("rotated_sqlite", "class",
                   "rewind.server.eventstores.RotatedEventStore")
        config.set("rotated_sqlite", "realclass",
                   "rewind.server.eventstores.SQLiteEventStore")
        config.set("rotated_sqlite", "prefix", "sqlite")
        config.set("rotated_sqlite", "path", path)

        estore = rconfig.construct_eventstore(config, "rotated_sqlite")

        self.assertIsInstance(estore, eventstores.RotatedEventStore)

        shutil.rmtree(path)
예제 #7
0
    def from_config(config, **options):
        """Instantiate an `SyncedRotationEventStores` from config.

        Parameters:
        config    -- the configuration file options read from file(s).
        **options -- various options given to the specific event store. Shall
                     not be used with this event store. Warning will be logged
                     for every extra non-recognized option. The only required
                     key to this function is 'path'.

        returns   -- a newly instantiated `SyncedRotationEventStores`.

        """
        required_args = ('storage-backends', )
        optional_args = {'events_per_batch': 25000}
        rconfig.check_config_options("SyncedRotationEventStores",
                                     required_args,
                                     tuple(optional_args.keys()), options)

        if "events_per_batch" in options:
            events_per_batch = int(options["events_per_batch"])
        else:
            events_per_batch = optional_args["events_per_batch"]

        estore = SyncedRotationEventStores(events_per_batch)

        for section in options['storage-backends'].split(' '):
            try:
                substore = rconfig.construct_eventstore(config, section)
                estore.add_rotated_store(substore)
            except Exception as e:
                _logger.exception(
                    'Could not instantiate substore from'
                    ' section %s', section)
                estore.close()
                raise

        return estore
예제 #8
0
    def from_config(config, **options):
        """Instantiate an `SyncedRotationEventStores` from config.

        Parameters:
        config    -- the configuration file options read from file(s).
        **options -- various options given to the specific event store. Shall
                     not be used with this event store. Warning will be logged
                     for every extra non-recognized option. The only required
                     key to this function is 'path'.

        returns   -- a newly instantiated `SyncedRotationEventStores`.

        """
        required_args = ('storage-backends',)
        optional_args = {'events_per_batch': 25000}
        rconfig.check_config_options("SyncedRotationEventStores",
                                     required_args,
                                     tuple(optional_args.keys()), options)

        if "events_per_batch" in options:
            events_per_batch = int(options["events_per_batch"])
        else:
            events_per_batch = optional_args["events_per_batch"]

        estore = SyncedRotationEventStores(events_per_batch)

        for section in options['storage-backends'].split(' '):
            try:
                substore = rconfig.construct_eventstore(config, section)
                estore.add_rotated_store(substore)
            except Exception as e:
                _logger.exception('Could not instantiate substore from'
                                  ' section %s', section)
                estore.close()
                raise

        return estore
예제 #9
0
 def testInMemoryFallback(self):
     """Test `construct_eventstore(...)` defaults to in-memory estore."""
     estore = rconfig.construct_eventstore(None)
     self.assertIsInstance(estore, eventstores.InMemoryEventStore)
예제 #10
0
 def testInMemoryFallback(self):
     """Test `construct_eventstore(...)` defaults to in-memory estore."""
     estore = rconfig.construct_eventstore(None)
     self.assertIsInstance(estore, eventstores.InMemoryEventStore)
예제 #11
0
def run(options, exit_codeword=None):
    """Actually execute the program.

    Calling this method can be done from tests to simulate executing the
    application from command line.

    Parameters:
    options       -- `optionparser` from config file.
    exit_codeword -- an optional exit_message that will shut down Rewind. Used
                     for testing.

    returns -- exit code for the application. Non-zero for errors.

    """
    QUERY_ENDP_OPT = 'query-bind-endpoint'
    STREAM_ENDP_OPT = 'streaming-bind-endpoint'
    ZMQ_NTHREADS = "zmq-nthreads"

    if not options.has_section(config.DEFAULT_SECTION):
        msg = "Missing default section, `{0}`."
        fmsg = msg.format(config.DEFAULT_SECTION)
        raise config.ConfigurationError(fmsg)

    if not options.has_option(config.DEFAULT_SECTION, QUERY_ENDP_OPT):
        msg = "Missing (query) bind endpoint in option file: {0}:{1}"
        fmsg = msg.format(config.DEFAULT_SECTION, QUERY_ENDP_OPT)
        raise config.ConfigurationError(fmsg)

    queryendp = options.get(config.DEFAULT_SECTION, QUERY_ENDP_OPT).split(",")
    streamendp = _get_with_fallback(options, config.DEFAULT_SECTION,
                                    STREAM_ENDP_OPT, '').split(",")
    queryendp = filter(lambda x: x.strip(), queryendp)
    streamendp = filter(lambda x: x.strip(), streamendp)

    try:
        eventstore = config.construct_eventstore(options)
    except config.ConfigurationError as e:
        _logger.exception("Could instantiate event store from config file.")
        raise

    zmq_nthreads = _get_with_fallback(options, config.DEFAULT_SECTION,
                                      ZMQ_NTHREADS, '3')
    try:
        zmq_nthreads = int(zmq_nthreads)
    except ValueError:
        msg = "{0}:{1} must be an integer".format(config.DEFAULT_SECTION,
                                                  ZMQ_NTHREADS)
        _logger.fatal(msg)
        return 1

    with _zmq_context_context(zmq_nthreads) as context, \
            _zmq_socket_context(context, zmq.REP, queryendp) as querysock, \
            _zmq_socket_context(context, zmq.PUB,
                                streamendp) as streamsock:
        # Executing the program in the context of ZeroMQ context as well as
        # ZeroMQ sockets. Using with here to make sure are correctly closing
        # things in the correct order, particularly also if we have an
        # exception or similar.

        runner = _RewindRunner(eventstore, querysock, streamsock,
                               (exit_codeword.encode()
                                if exit_codeword
                                else None))
        runner.run()

    return 0