コード例 #1
0
    def _check_services(self, timeout, initial_retry_delay=0.01, max_delay=1):
        """Check that all Localstack services are running and accessible.

        Does exponential backoff up to `max_delay`.

        Args:
            timeout (float): Number of seconds to wait for services to
                be available.
            initial_retry_delay (float, optional): Initial retry delay value
                in seconds. Will be multiplied by `2^n` for each retry.
                Default: 0.01
            max_delay (float, optional): Max time in seconds to wait between
                checking service availability. Default: 1

        Returns:
            None

        Raises:
            pytest_localstack.exceptions.TimeoutError: If not all services
                started before `timeout` was reached.

        """
        services = set(self.services)
        num_retries = 0
        start_time = time.time()
        while services and (time.time() - start_time) < timeout:
            for service_name in list(
                    services
            ):  # list() because set may change during iteration
                try:
                    service_checks.SERVICE_CHECKS[service_name](self)
                    services.discard(service_name)
                except exceptions.ServiceError as e:
                    if (time.time() - start_time) >= timeout:
                        six.raise_from(
                            exceptions.TimeoutError(
                                "Localstack service not started: {0}".format(
                                    service_name)),
                            e,
                        )
            if services:
                delay = (2**num_retries) * initial_retry_delay
                if delay > max_delay:
                    delay = max_delay
                    time.sleep(delay)
                    num_retries += 1
コード例 #2
0
ファイル: session.py プロジェクト: mintel/pytest-localstack
    def start(self, timeout=60):
        """Start the Localstack container.

        Args:
            timeout (float, optional): Wait at most this many seconds
                for the Localstack services to start. Default is 1 minute.

        Raises:
            pytest_localstack.exceptions.TimeoutError:
                If *timeout* was reached before all Localstack
                services were available.
            docker.errors.APIError: If the Docker daemon returns an error.

        """
        if self._container is not None:
            raise exceptions.ContainerAlreadyStartedError(self)

        logger.debug("Starting Localstack container %s", self.container_name)
        logger.debug("%r running starting hooks", self)
        plugin.manager.hook.session_starting(session=self)

        image_name = self.image_name + ":" + self.localstack_version
        if self.pull_image:
            logger.debug("Pulling docker image %r", image_name)
            self.docker_client.images.pull(image_name)

        start_time = time.time()

        services = ",".join("%s:%s" % pair for pair in self.services.items())
        kinesis_error_probability = "%f" % self.kinesis_error_probability
        dynamodb_error_probability = "%f" % self.dynamodb_error_probability
        use_ssl = str(self.use_ssl).lower()
        self._container = self.docker_client.containers.run(
            image_name,
            name=self.container_name,
            detach=True,
            auto_remove=self.auto_remove,
            environment={
                "DEFAULT_REGION": self.region_name,
                "SERVICES": services,
                "KINESIS_ERROR_PROBABILITY": kinesis_error_probability,
                "DYNAMODB_ERROR_PROBABILITY": dynamodb_error_probability,
                "USE_SSL": use_ssl,
            },
            ports={port: None
                   for port in self.services.values()},
        )
        logger.debug(
            "Started Localstack container %s (id: %s)",
            self.container_name,
            self._container.short_id,
        )

        # Tail container logs
        container_logger = logger.getChild("containers.%s" %
                                           self._container.short_id)
        self._stdout_tailer = container.DockerLogTailer(
            self._container,
            container_logger.getChild("stdout"),
            self.container_log_level,
            stdout=True,
            stderr=False,
        )
        self._stdout_tailer.start()
        self._stderr_tailer = container.DockerLogTailer(
            self._container,
            container_logger.getChild("stderr"),
            self.container_log_level,
            stdout=False,
            stderr=True,
        )
        self._stderr_tailer.start()

        try:
            timeout_remaining = timeout - (time.time() - start_time)
            if timeout_remaining <= 0:
                raise exceptions.TimeoutError(
                    "Container took too long to start.")

            self._check_services(timeout_remaining)

            logger.debug("%r running started hooks", self)
            plugin.manager.hook.session_started(session=self)
            logger.debug("%r finished started hooks", self)
        except exceptions.TimeoutError:
            if self._container is not None:
                self.stop(0.1)
            raise