Exemple #1
0
    def test_request_and_wait(self):
        """Test that the external log area provider can checkout log areas.

        Approval criteria:
            - The external log area provider shall request an external provider and
              checkout log areas.

        Test steps::
            1. Initialize an external provider.
            2. Send a checkout request via the external log area provider.
            3. Verify that the provider returns a list of checked out log areas.
        """
        etos = ETOS("testing_etos", "testing_etos", "testing_etos")
        etos.config.set("WAIT_FOR_LOG_AREA_TIMEOUT", 10)
        jsontas = JsonTas()
        identity = PackageURL.from_string("pkg:testing/etos")
        jsontas.dataset.merge(
            {
                "identity": identity,
                "artifact_id": "artifactid",
                "artifact_created": "artifactcreated",
                "artifact_published": "artifactpublished",
                "tercc": "tercc",
                "dataset": {},
                "context": "context",
            }
        )
        start_id = "1"
        test_id = "logarea123"
        provider_id = "test_request_and_wait"
        # First request is 'start'.
        # Second request is 'status'.
        # Third request is 'stop' which should not be requested in this test.
        with FakeServer(
            ["ok", "ok", "no_content"],
            [
                {"id": start_id},
                {"log_areas": [{"test_id": test_id}], "status": "DONE"},
                {},
            ],
        ) as server:
            ruleset = {
                "id": provider_id,
                "status": {"host": server.host},
                "start": {"host": server.host},
                "stop": {"host": server.host},
            }
            self.logger.info("STEP: Initialize an external provider.")
            provider = Provider(etos, jsontas, ruleset)
            self.logger.info(
                "STEP: Send a checkout request via the external log area provider."
            )
            log_areas = provider.request_and_wait_for_log_areas()
            self.logger.info(
                "STEP: Verify that the provider returns a list of checked out log areas."
            )
            dict_log_areas = [log_area.as_dict for log_area in log_areas]
            test_log_areas = [LogArea(provider_id=provider_id, test_id=test_id).as_dict]
            self.assertEqual(dict_log_areas, test_log_areas)
Exemple #2
0
    def test_provider_stop_many(self):
        """Test that it is possible to checkin an external log area provider with many
           log areas.

        Approval criteria:
            - It shall be possible to send stop to an external log area provider
              with multiple log areas.

        Test steps::
            1. Initialize an external provider.
            2. Send a stop request for multiple log areas.
            3. Verify that the stop endpoint is called.
        """
        etos = ETOS("testing_etos", "testing_etos", "testing_etos")
        etos.config.set("WAIT_FOR_LOG_AREA_TIMEOUT", 1)
        jsontas = JsonTas()
        log_areas = [
            LogArea(test_log_area=1),
            LogArea(test_log_area=2),
        ]
        jsontas.dataset.merge(
            {
                "identity": PackageURL.from_string("pkg:testing/etos"),
                "artifact_id": "artifactid",
                "artifact_created": "artifactcreated",
                "artifact_published": "artifactpublished",
                "tercc": "tercc",
                "dataset": {},
                "context": "context",
                "logs": log_areas,
            }
        )
        dict_log_areas = [log_area.as_dict for log_area in log_areas]

        with FakeServer("no_content", {}) as server:
            ruleset = {"id": "test_provider_stop_many", "stop": {"host": server.host}}
            self.logger.info("STEP: Initialize an external provider.")
            provider = Provider(etos, jsontas, ruleset)
            self.logger.info("STEP: Send a stop request for multiple log areas.")
            provider.checkin_all()
            self.logger.info("STEP: Verify that the stop endpoint is called.")
            self.assertEqual(server.nbr_of_requests, 1)
            self.assertEqual(server.requests, [dict_log_areas])
    def build_log_areas(self, response):
        """Build log area objects from external log area provider response.

        :param response: The response from the external log area provider.
        :type response: dict
        :return: A list of log areas.
        :rtype: list
        """
        return [
            LogArea(provider_id=self.id, **log_area)
            for log_area in response.get("log_areas", [])
        ]
Exemple #4
0
    def test_provider_stop_timeout(self):
        """Test that the checkin method raises a TimeoutError when timed out.

        Approval criteria:
            - The checkin method shall raise TimeoutError when timed out.

        Test steps::
            1. Initialize an external provider.
            2. Send a stop request for log areas that times out.
            3. Verify that the checkin method raises a TimeoutError.
        """
        etos = ETOS("testing_etos", "testing_etos", "testing_etos")
        etos.config.set("WAIT_FOR_LOG_AREA_TIMEOUT", 1)
        jsontas = JsonTas()
        jsontas.dataset.merge(
            {
                "identity": PackageURL.from_string("pkg:testing/etos"),
                "artifact_id": "artifactid",
                "artifact_created": "artifactcreated",
                "artifact_published": "artifactpublished",
                "tercc": "tercc",
                "dataset": {},
                "context": "context",
            }
        )
        log_area = LogArea(test_log_area=1)
        with FakeServer("bad_request", {}) as server:
            ruleset = {
                "id": "test_provider_stop_timeout",
                "stop": {"host": server.host},
            }
            self.logger.info("STEP: Initialize an external provider.")
            provider = Provider(etos, jsontas, ruleset)
            self.logger.info("STEP: Send a stop request that fails.")
            with self.assertRaises(TimeoutError):
                self.logger.info(
                    "STEP: Verify that the checkin method raises a TimeoutError."
                )
                provider.checkin(log_area)
    def release(response, task_id):
        """Release an environment.

        :param response: Response object to edit and return.
        :type response: :obj:`falcon.response`
        :param task_id: Task to release.
        :type task_id: str
        """
        try:
            task_result = APP.AsyncResult(task_id)
            result = {
                "status": task_result.status,
            }
            response.status = falcon.HTTP_200
            if task_result.result:
                etos = ETOS(
                    "ETOS Environment Provider",
                    os.getenv("HOSTNAME"),
                    "Environment Provider",
                )
                jsontas = JsonTas()
                registry = ProviderRegistry(etos, jsontas)
                failure = None
                for suite in task_result.result.get("suites", []):
                    try:
                        iut = suite.get("iut")
                        ruleset = registry.get_iut_provider_by_id(
                            iut.get("provider_id"))
                        provider = IutProvider(etos, jsontas, ruleset["iut"])
                        provider.checkin(Iut(**iut))
                    except Exception as exception:  # pylint:disable=broad-except
                        failure = exception

                    try:
                        executor = suite.get("executor")
                        ruleset = registry.get_execution_space_provider_by_id(
                            executor.get("provider_id"))
                        provider = ExecutionSpaceProvider(
                            etos, jsontas, ruleset["execution_space"])
                        provider.checkin(ExecutionSpace(**executor))
                    except Exception as exception:  # pylint:disable=broad-except
                        failure = exception

                    try:
                        log_area = suite.get("log_area")
                        ruleset = registry.get_log_area_provider_by_id(
                            log_area.get("provider_id"))
                        provider = LogAreaProvider(etos, jsontas,
                                                   ruleset["log"])
                        provider.checkin(LogArea(**log_area))
                    except Exception as exception:  # pylint:disable=broad-except
                        failure = exception
                task_result.forget()
                if failure:
                    raise failure
                response.media = {**result}
            else:
                response.media = {
                    "warning": f"Nothing to release with task_id '{task_id}'",
                    **result,
                }
        except Exception as exception:  # pylint:disable=broad-except
            traceback.print_exc()
            response.media = {
                "error": str(exception),
                "details": traceback.format_exc(),
                **result,
            }
Exemple #6
0
def release_environment(etos, jsontas, provider_registry, task_result,
                        release_id):  # pylint:disable=too-many-locals
    """Release an already requested environment.

    :param etos: ETOS library instance.
    :type etos: :obj:`etos_lib.ETOS`
    :param jsontas: JSONTas instance.
    :type jsontas: :obj:`jsontas.jsontas.JsonTas`
    :param provider_registry: The provider registry to get environments from.
    :type provider_registry: :obj:`environment_provider.lib.registry.ProviderRegistry`
    :param celery_worker: The worker holding the task results.
    :type celery_worker: :obj:`celery.Celery`
    :param release_id: The environment ID to release.
    :type release_id: str
    :return: Whether or not the release was successful together with
             a message should the release not be successful.
    :rtype tuple
    """
    if task_result is None or not task_result.result:
        return False, f"Nothing to release with task_id {release_id}"
    failure = None
    for suite in task_result.result.get("suites", []):
        etos.config.set("SUITE_ID", suite.get("suite_id"))
        iut = suite.get("iut")
        iut_ruleset = provider_registry.get_iut_provider_by_id(
            iut.get("provider_id")).get("iut")
        executor = suite.get("executor")
        executor_ruleset = provider_registry.get_execution_space_provider_by_id(
            executor.get("provider_id")).get("execution_space")
        log_area = suite.get("log_area")
        log_area_ruleset = provider_registry.get_log_area_provider_by_id(
            log_area.get("provider_id")).get("log")

        if iut_ruleset.get("type", "jsontas") == "external":
            success, exception = checkin_provider(
                Iut(**iut), ExternalIutProvider(etos, jsontas, iut_ruleset))
        else:
            success, exception = checkin_provider(
                Iut(**iut), IutProvider(etos, jsontas, iut_ruleset))
        if not success:
            failure = exception

        success, exception = checkin_provider(
            LogArea(**log_area),
            LogAreaProvider(etos, jsontas, log_area_ruleset))
        if not success:
            failure = exception
        success, exception = checkin_provider(
            ExecutionSpace(**executor),
            ExecutionSpaceProvider(etos, jsontas, executor_ruleset),
        )
        if not success:
            failure = exception
    task_result.forget()
    if failure:
        # Return the traceback from exception stored in failure.
        return False, "".join(
            traceback.format_exception(failure,
                                       value=failure,
                                       tb=failure.__traceback__))
    return True, ""