Exemple #1
0
    def __init__(self, params):
        """Initialize.

        :param params: Parameter data storage for Tester APIs.
        :type params: :obj:`lib.params.Params`
        """
        self.params = params
        self.etos = ETOS("ETOS API", os.getenv("HOSTNAME"), "ETOS API")
        self.etos.config.rabbitmq_publisher_from_environment()
        self.etos.start_publisher()
Exemple #2
0
    def __init__(self):
        """Initialize ETOS library and start eiffel publisher."""
        self.etos = ETOS("ETOS Test Runner", os.getenv("HOSTNAME"), "ETOS Test Runner")
        self.etos.config.rabbitmq_publisher_from_environment()
        # ETR will print the entire environment just before executing.
        # Hide the password.
        os.environ["RABBITMQ_PASSWORD"] = "******"

        self.etos.start_publisher()
        self.tests_url = os.getenv("SUB_SUITE_URL")

        signal.signal(signal.SIGTERM, self.graceful_shutdown)
Exemple #3
0
    def __init__(self):
        """Initialize ESR by creating a rabbitmq publisher."""
        self.logger = logging.getLogger("ESR")
        self.etos = ETOS("ETOS Suite Runner", os.getenv("SOURCE_HOST"),
                         "ETOS Suite Runner")
        signal.signal(signal.SIGTERM, self.graceful_exit)
        self.params = ESRParameters(self.etos)

        self.etos.config.rabbitmq_publisher_from_environment()
        self.etos.start_publisher()
        self.etos.config.set(
            "WAIT_FOR_ENVIRONMENT_TIMEOUT",
            int(os.getenv("ESR_WAIT_FOR_ENVIRONMENT_TIMEOUT")),
        )
Exemple #4
0
    def __init__(self):
        """Initialize SuiteStarter by creating a rabbitmq publisher and subscriber."""
        self.etos = ETOS("ETOS Suite Starter", os.getenv("HOSTNAME"),
                         "ETOS Suite Starter")
        self._configure()

        self.etos.config.rabbitmq_subscriber_from_environment()
        self.etos.config.rabbitmq_publisher_from_environment()
        self.etos.start_subscriber()
        self.etos.start_publisher()

        self.etos.subscriber.subscribe(
            "EiffelTestExecutionRecipeCollectionCreatedEvent",
            self.suite_runner_callback,
            can_nack=True,
        )
Exemple #5
0
    def test_get_configuration_missing(self):
        """Test that if a configuration is missing, a partial result is returned.

        Approval criteria:
            - The configure backend shall return a partial configuration if configuration
              is missing.

        Test steps:
            1. Store a faulty configuration into the database.
            2. Verify that it is possible to get the partial configuration.
        """
        database = FakeDatabase()
        test_suite_id = "ca51601e-6c9a-4b5d-8038-7dc2561283d2"
        test_dataset = {"dataset": "test"}
        self.logger.info(
            "STEP: Store a faulty configuration into the database.")
        database.writer.hset(f"EnvironmentProvider:{test_suite_id}", "Dataset",
                             json.dumps(test_dataset))

        self.logger.info(
            "STEP: Verify that it is possible to get the partial configuration."
        )
        registry = ProviderRegistry(ETOS("", "", ""), JsonTas(), database)
        stored_configuration = get_configuration(registry, test_suite_id)
        self.assertDictEqual(
            stored_configuration,
            {
                "dataset": test_dataset,
                "iut_provider": None,
                "execution_space_provider": None,
                "log_area_provider": None,
            },
        )
Exemple #6
0
async def configure_environment_provider(
    environment: ConfigureEnvironmentProviderRequest, ):
    """Configure environment provider request.

    :param environment: Environment to configure.
    :type environment: :obj:`etos_api.routers.etos.schemas.ConfigureEnvironmentProviderRequest`
    """
    etos_library = ETOS("ETOS API", os.getenv("HOSTNAME"), "ETOS API")

    end_time = time.time() + etos_library.debug.default_http_timeout
    async with aiohttp.ClientSession() as session:
        while time.time() < end_time:
            try:
                async with session.post(
                        f"{etos_library.debug.environment_provider}/configure",
                        json=environment.dict(),
                        headers={
                            "Content-Type": "application/json",
                            "Accept": "application/json",
                        },
                ) as response:
                    assert 200 <= response.status < 400
                break
            except AssertionError:
                await asyncio.sleep(2)
        else:
            raise HTTPException(
                status_code=400,
                detail=
                f"Unable to configure environment provider with '{environment.json()}'",
            )
    def test_register_log_area_provider(self):
        """Test that the register backend can register log area providers.

        Approval criteria:
            - The register backend shall be able to register a log area provider.

        Test steps:
            1. Register a log area provider with the register backend.
            2. Verify that the log area provider was stored in the database.
        """
        fake_database = FakeDatabase()
        etos = ETOS("testing_etos", "testing_etos", "testing_etos")
        jsontas = JsonTas()
        provider = {
            "log": {
                "id": "log_area_provider_test",
                "list": {"available": [], "possible": []},
            }
        }
        provider_registry = ProviderRegistry(etos, jsontas, fake_database)
        self.logger.info(
            "STEP: Register a log area provider with the register backend."
        )
        response = register(provider_registry, log_area_provider=provider)

        self.logger.info(
            "STEP: Verify that the log area provider was stored in the database."
        )
        stored_provider = json.loads(
            fake_database.reader.hget(
                "EnvironmentProvider:LogAreaProviders", "log_area_provider_test"
            )
        )
        self.assertDictEqual(stored_provider, provider)
        self.assertTrue(response)
    def test_release_environment_no_task_result(self):
        """Test that it is not possible to release an environment without task results.

        Approval criteria:
            - The environment provider shall not attempt to release environments with results.

        Test steps:
            1. Attempt to release an environment without a task ID.
            2. Verify that the release fails.
        """
        database = FakeDatabase()
        test_release_id = "ce63f53e-1797-42bb-ae72-861a0b6b7ef6"
        worker = FakeCelery("thisdoesnotexist", "SUCCESS", {})
        jsontas = JsonTas()
        etos = ETOS("", "", "")
        registry = ProviderRegistry(etos, jsontas, database)
        self.logger.info(
            "STEP: Attempt to release an environment without a task ID.")
        success, _ = release_environment(
            etos,
            jsontas,
            registry,
            worker.AsyncResult(test_release_id),
            test_release_id,
        )

        self.logger.info("STEP: Verify that the release fails.")
        self.assertFalse(success)
Exemple #9
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 #10
0
    def test_provider_stop_many(self):
        """Test that it is possible to checkin an external execution space provider with many
           execution spaces.

        Approval criteria:
            - It shall be possible to send stop to an external execution space provider
              with multiple execution spaces.

        Test steps::
            1. Initialize an external provider.
            2. Send a stop request for multiple execution spaces.
            3. Verify that the stop endpoint is called.
        """
        etos = ETOS("testing_etos", "testing_etos", "testing_etos")
        etos.config.set("WAIT_FOR_EXECUTION_SPACE_TIMEOUT", 1)
        jsontas = JsonTas()
        execution_spaces = [
            ExecutionSpace(test_execution_space=1),
            ExecutionSpace(test_execution_space=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",
            "execution_spaces":
            execution_spaces,
        })
        dict_execution_spaces = [
            execution_space.as_dict for execution_space in execution_spaces
        ]

        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 execution spaces.")
            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_execution_spaces])
Exemple #11
0
async def start_etos(etos: StartEtosRequest):
    """Start ETOS execution on post.

    :param etos: ETOS pydantic model.
    :type etos: :obj:`etos_api.routers.etos.schemas.StartEtosRequest`
    :return: JSON dictionary with response.
    :rtype: dict
    """
    await SuiteValidator().validate(etos.test_suite_url)

    etos_library = ETOS("ETOS API", os.getenv("HOSTNAME"), "ETOS API")
    await sync_to_async(etos_library.config.rabbitmq_publisher_from_environment
                        )

    artifact = await wait_for_artifact_created(etos_library,
                                               etos.artifact_identity)
    if artifact is None:
        raise HTTPException(
            status_code=400,
            detail=
            f"Unable to find artifact with identity '{etos.artifact_identity}'",
        )
    # There are assumptions here. Since "edges" list is already tested
    # and we know that the return from GraphQL must be 'node'.'meta'.'id'
    # if there are "edges", this is fine.
    artifact_id = artifact[0]["node"]["meta"]["id"]

    links = {"CAUSE": artifact_id}
    data = {
        "selectionStrategy": {
            "tracker": "Suite Builder",
            "id": str(uuid4())
        },
        "batchesUri": etos.test_suite_url,
    }
    tercc = EiffelTestExecutionRecipeCollectionCreatedEvent()
    request = ConfigureEnvironmentProviderRequest(
        suite_id=tercc.meta.event_id,
        dataset=etos.dataset,
        execution_space_provider=etos.execution_space_provider,
        iut_provider=etos.iut_provider,
        log_area_provider=etos.log_area_provider,
    )
    await configure_environment_provider(request)

    await sync_to_async(etos_library.start_publisher)
    async with aclosing(etos_library.publisher):
        event = etos_library.events.send(tercc, links, data)

    return {
        "tercc": event.meta.event_id,
        "event_repository": etos_library.debug.graphql_server,
    }
Exemple #12
0
    def test_provider_status_http_exceptions(self):
        """Test that the wait method handles HTTP errors.

        Approvial criteria:
            - The wait method shall raise ExecutionSpaceNotAvailable on 404 errors.
            - The wait method shall raise RuntimeError on 400 errors.

        Test steps::
            1. For status [400, 404]:
                1.1 Initialize an external provider.
                1.2 Send a status request for a started execution space provider.
                1.3 Verify that the wait method raises the correct exception.
        """
        etos = ETOS("testing_etos", "testing_etos", "testing_etos")
        etos.config.set("WAIT_FOR_EXECUTION_SPACE_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",
        })
        self.logger.info("STEP: For status [400, 404]:")
        for status, exception in (
            ("bad_request", RuntimeError),
            ("not_found", ExecutionSpaceNotAvailable),
        ):
            with FakeServer(status, {"error": "failure"}) as server:
                ruleset = {
                    "id": "test_provider_status_http_exceptions",
                    "status": {
                        "host": server.host
                    },
                }
                self.logger.info("STEP: Initialize an external provider.")
                provider = Provider(etos, jsontas, ruleset)
                self.logger.info(
                    "STEP: Send a status request for a started execution space provider."
                )
                with self.assertRaises(exception):
                    self.logger.info(
                        "STEP: Verify that the wait method raises the correct exception."
                    )
                    provider.wait("1")
Exemple #13
0
    def test_provider_status_pending(self):
        """Test that the wait method waits on status PENDING.

        Approvial criteria:
            - The wait method shall call the status endpoint, waiting on PENDING.

        Test steps::
            1. Initialize an external provider.
            2. Send a status request for a started execution space provider.
            3. Verify that the wait method waits on PENDING.
        """
        etos = ETOS("testing_etos", "testing_etos", "testing_etos")
        etos.config.set("WAIT_FOR_EXECUTION_SPACE_TIMEOUT", 10)
        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",
        })
        responses = [{
            "status": "PENDING"
        }, {
            "status": "PENDING"
        }, {
            "status": "DONE"
        }]
        with FakeServer("ok", responses.copy()) as server:
            ruleset = {
                "id": "test_provider_status_pending",
                "status": {
                    "host": server.host
                },
            }
            self.logger.info("STEP: Initialize an external provider.")
            provider = Provider(etos, jsontas, ruleset)
            self.logger.info(
                "STEP: Send a status request for a started execution space provider."
            )
            provider.wait("1")
            self.logger.info(
                "STEP: Verify that the wait method waits on PENDING.")
            self.assertEqual(server.nbr_of_requests, len(responses))
Exemple #14
0
    def test_provider_status_failed(self):
        """Test that the wait method raises ExecutionSpaceCheckoutFailed on FAILED status.

        Approvial criteria:
            - The wait method shall raise ExecutionSpaceCheckoutFailed on a FAILED status.

        Test steps::
            1. Initialize an external provider.
            2. Send a status request for a started execution space provider.
            3. Verify that the wait method raises ExecutionSpaceCheckoutFailed.
        """
        etos = ETOS("testing_etos", "testing_etos", "testing_etos")
        etos.config.set("WAIT_FOR_EXECUTION_SPACE_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",
        })
        description = "something failed!"
        with FakeServer("ok", {
                "status": "FAILED",
                "description": description
        }) as server:
            ruleset = {
                "id": "test_provider_status_failed",
                "status": {
                    "host": server.host
                },
            }
            self.logger.info("STEP: Initialize an external provider.")
            provider = Provider(etos, jsontas, ruleset)
            self.logger.info(
                "STEP: Send a status request for a started execution space provider."
            )
            with self.assertRaises(ExecutionSpaceCheckoutFailed):
                self.logger.info(
                    "STEP: Verify that the wait method raises ExecutionSpaceCheckoutFailed."
                )
                provider.wait("1")
Exemple #15
0
    def test_provider_status(self):
        """Test that the wait method waits for status DONE and exits with response.

        Approvial criteria:
            - The wait method shall call the status endpoint and return on DONE.

        Test steps::
            1. Initialize an external provider.
            2. Send a status request for a started execution space provider.
            3. Verify that the wait method returns response on DONE.
        """
        etos = ETOS("testing_etos", "testing_etos", "testing_etos")
        etos.config.set("WAIT_FOR_EXECUTION_SPACE_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",
        })
        test_id = "123"
        with FakeServer("ok", {
                "status": "DONE",
                "test_id": test_id
        }) as server:
            ruleset = {
                "id": "test_provider_status",
                "status": {
                    "host": server.host
                }
            }
            self.logger.info("STEP: Initialize an external provider.")
            provider = Provider(etos, jsontas, ruleset)
            self.logger.info(
                "STEP: Send a status request for a started execution space provider."
            )
            response = provider.wait("1")
            self.logger.info(
                "STEP: Verify that the wait method return response on DONE.")
            self.assertEqual(response.get("test_id"), test_id)
Exemple #16
0
    def test_provider_start_http_exception(self):
        """Test that the start method tries again if there's an HTTP error.

        Approval criteria:
            - The start method shall try again on HTTP errors.

        Test steps::
            1. Initialize an external provider.
            2. Send a start request that fails.
            3. Verify that the start method tries again on HTTP errors.
        """
        etos = ETOS("testing_etos", "testing_etos", "testing_etos")
        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",
        })
        expected_start_id = "123"

        with FakeServer(["bad_request", "ok"], [{}, {
                "id": expected_start_id
        }]) as server:
            ruleset = {
                "id": "test_provider_start_http_exception",
                "start": {
                    "host": server.host
                },
            }
            self.logger.info("STEP: Initialize an external provider.")
            provider = Provider(etos, jsontas, ruleset)
            self.logger.info("STEP: Send a start request that fails.")
            start_id = provider.start(1, 2)
            self.logger.info(
                "STEP: Verify that the start method tries again on HTTP errors."
            )
            self.assertGreaterEqual(server.nbr_of_requests, 2)
            self.assertEqual(start_id, expected_start_id)
Exemple #17
0
    def test_provider_stop_failed(self):
        """Test that the checkin method raises an ExecutionSpaceCheckinFailed exception.

        Approval criteria:
            - The checkin method shall fail with an ExecutionSpaceCheckinFailed exception.

        Test steps::
            1. Initialize an external provider.
            2. Send a stop request that fails.
            3. Verify that the checkin method raises ExecutionSpaceCheckinFailed exception.
        """
        etos = ETOS("testing_etos", "testing_etos", "testing_etos")
        etos.config.set("WAIT_FOR_EXECUTION_SPACE_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",
        })
        execution_space = ExecutionSpace(test_execution_space=1)

        with FakeServer("bad_request", {"error": "no"}) as server:
            ruleset = {
                "id": "test_provider_stop_failed",
                "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(ExecutionSpaceCheckinFailed):
                self.logger.info(
                    "STEP: Verify that the checkin method raises ExecutionSpaceCheckinFailed "
                    "exception.")
                provider.checkin(execution_space)
Exemple #18
0
    def test_provider_start_timeout(self):
        """Test that the start method raises a TimeoutError.

        Approval criteria:
            - The start method shall raise TimeoutError if the timeout is reached.

        Test steps::
            1. Initialize an external provider.
            2. Send a start request which will never finish.
            3. Verify that the start method raises TimeoutError.
        """
        etos = ETOS("testing_etos", "testing_etos", "testing_etos")
        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",
        })
        os.environ["ETOS_DEFAULT_HTTP_TIMEOUT"] = "1"

        with FakeServer("bad_request", {}) as server:
            ruleset = {
                "id": "test_provider_start_timeout",
                "start": {
                    "host": server.host
                },
            }
            self.logger.info("STEP: Initialize an external provider.")
            provider = Provider(etos, jsontas, ruleset)
            self.logger.info(
                "STEP: Send a start request which will never finish.")

            with self.assertRaises(TimeoutError):
                self.logger.info(
                    "STEP: Verify that the start method raises TimeoutError.")
                provider.start(1, 2)
Exemple #19
0
    def test_provider_stop(self):
        """Test that it is possible to checkin an external IUT provider.

        Approval criteria:
            - It shall be possible to send stop to an external IUT provider.

        Test steps::
            1. Initialize an external provider.
            2. Send a stop request for a single IUT.
            3. Verify that the stop endpoint is called.
        """
        etos = ETOS("testing_etos", "testing_etos", "testing_etos")
        etos.config.set("WAIT_FOR_IUT_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",
        })
        iut = Iut(test_iut=1)

        with FakeServer("no_content", {}) as server:
            ruleset = {
                "id": "test_provider_stop",
                "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 a single IUT.")
            provider.checkin(iut)
            self.logger.info("STEP: Verify that the stop endpoint is called.")
            self.assertEqual(server.nbr_of_requests, 1)
            self.assertEqual(server.requests, [[iut.as_dict]])
Exemple #20
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 IUTs 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_IUT_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",
        })
        iut = Iut(test_iut=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(iut)
Exemple #21
0
    def test_provider_start(self):
        """Test that it is possible to start an external execution space provider.

        Approval criteria:
            - It shall be possible to send start to an external execution space provider.

        Test steps::
            1. Initialize an external provider.
            2. Send a start request.
            3. Verify that the ID from the start request is returned.
        """
        etos = ETOS("testing_etos", "testing_etos", "testing_etos")
        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",
        })
        expected_start_id = "123"

        with FakeServer("ok", {"id": expected_start_id}) as server:
            ruleset = {
                "id": "test_provider_start",
                "start": {
                    "host": server.host
                }
            }
            self.logger.info("STEP: Initialize an external provider.")
            provider = Provider(etos, jsontas, ruleset)
            self.logger.info("STEP: Send a start request.")
            start_id = provider.start(1, 2)
            self.logger.info(
                "STEP: Verify that the ID from the start request is returned.")
            self.assertEqual(start_id, expected_start_id)
Exemple #22
0
    def test_provider_status_timeout(self):
        """Test that the wait method raises TimeoutError when timed out.

        Approvial criteria:
            - The wait method shall raise TimeoutError when timed out.

        Test steps::
            1. Initialize an external provider.
            2. Send a status request that times out.
            3. Verify that the wait method raises TimeoutError.
        """
        etos = ETOS("testing_etos", "testing_etos", "testing_etos")
        etos.config.set("WAIT_FOR_EXECUTION_SPACE_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",
        })
        with FakeServer("internal_server_error", {}) as server:
            ruleset = {
                "id": "test_provider_status_timeout",
                "status": {
                    "host": server.host
                },
            }
            self.logger.info("STEP: Initialize an external provider.")
            provider = Provider(etos, jsontas, ruleset)
            self.logger.info("STEP: Send a status request that times out.")
            with self.assertRaises(TimeoutError):
                self.logger.info(
                    "STEP: Verify that the wait method raises TimeoutError.")
                provider.wait("1")
    def test_register_provider_none(self):
        """Test that the register backend return false if no provider is supplied.

        Approval criteria:
            - The register backend shall return False if no provider is supplied.

        Test steps:
            1. Register no provider with the register backend.
            2. Verify that the register backend return False.
        """
        fake_database = FakeDatabase()
        etos = ETOS("testing_etos", "testing_etos", "testing_etos")
        jsontas = JsonTas()
        provider_registry = ProviderRegistry(etos, jsontas, fake_database)

        self.logger.info("STEP: Register no provider with the register backend.")
        response = register(provider_registry)

        self.logger.info("STEP: Verify that the register backend return False.")
        self.assertFalse(response)
Exemple #24
0
async def configure_environment_provider(
    environment: ConfigureEnvironmentProviderRequest,
):
    """Configure environment provider request.

    :param environment: Environment to configure.
    :type environment: :obj:`etos_api.routers.etos.schemas.ConfigureEnvironmentProviderRequest`
    """
    LOGGER.identifier.set(environment.suite_id)
    LOGGER.info("Configuring environment provider using %r", environment)
    etos_library = ETOS("ETOS API", os.getenv("HOSTNAME"), "ETOS API")

    end_time = time.time() + etos_library.debug.default_http_timeout
    LOGGER.debug("HTTP Timeout: %r", etos_library.debug.default_http_timeout)
    async with aiohttp.ClientSession() as session:
        while time.time() < end_time:
            try:
                async with session.post(
                    f"{etos_library.debug.environment_provider}/configure",
                    json=environment.dict(),
                    headers={
                        "Content-Type": "application/json",
                        "Accept": "application/json",
                    },
                ) as response:
                    assert 200 <= response.status < 400
                break
            except AssertionError:
                LOGGER.warning(
                    "Configuration request failed: %r, %r",
                    response.status,
                    response.reason,
                )
                await asyncio.sleep(2)
        else:
            raise HTTPException(
                status_code=400,
                detail=f"Unable to configure environment provider with '{environment.json()}'",
            )
        await _wait_for_configuration(etos_library, environment)
Exemple #25
0
    def test_configure_missing_parameter(self):
        """Test that the configure backend does not configure if any parameter is missing.

        Approval criteria:
            - The configure backend shall return False and not configure if any parameter
              is missing.

        Test steps:
            1. Attempt to configure the environment provider without any parameters.
            2. Verify that False was returned and no configuration was made.
        """
        database = FakeDatabase()
        self.logger.info(
            "STEP: Attempt to configure the environment provider without any parameters."
        )
        registry = ProviderRegistry(ETOS("", "", ""), JsonTas(), database)
        success, _ = configure(registry, None, None, None, None, None)

        self.logger.info(
            "STEP: Verify that False was returned and no configuration was made."
        )
        self.assertFalse(success)
        self.assertDictEqual(database.db_dict, {})
    def test_register_execution_space_provider(self):
        """Test that the register backend can register execution space providers.

        Approval criteria:
            - The register backend shall be able to register an execution space provider.

        Test steps:
            1. Register an execution space provider with the register backend.
            2. Verify that the execution space provider was stored in the database.
        """
        fake_database = FakeDatabase()
        etos = ETOS("testing_etos", "testing_etos", "testing_etos")
        jsontas = JsonTas()
        provider = {
            "execution_space": {
                "id": "execution_space_provider_test",
                "list": {"available": [{"identifier": "123"}], "possible": []},
            }
        }
        provider_registry = ProviderRegistry(etos, jsontas, fake_database)
        self.logger.info(
            "STEP: Register an execution space provider with the register backend."
        )
        response = register(provider_registry, execution_space_provider=provider)

        self.logger.info(
            "STEP: Verify that the execution space provider was stored in the database."
        )
        stored_provider = json.loads(
            fake_database.reader.hget(
                "EnvironmentProvider:ExecutionSpaceProviders",
                "execution_space_provider_test",
            )
        )
        self.assertDictEqual(stored_provider, provider)
        self.assertTrue(response)
Exemple #27
0
class BaseTester:
    """Base tester API."""

    __artifact_id = None
    __gql_response = None

    def __init__(self, params):
        """Initialize.

        :param params: Parameter data storage for Tester APIs.
        :type params: :obj:`lib.params.Params`
        """
        self.params = params
        self.etos = ETOS("ETOS API", os.getenv("HOSTNAME"), "ETOS API")
        self.etos.config.rabbitmq_publisher_from_environment()
        self.etos.start_publisher()

    def configure_environment_provider(self, suite_id):
        """Configure the ETOS environment provider for a suite ID.

        :param suite_id: Suite ID to configure the environment provider for.
        :type suite_id: str
        """
        params = {
            "suite_id": suite_id,
            "iut_provider": self.params.iut_provider,
            "execution_space_provider": self.params.execution_space_provider,
            "log_area_provider": self.params.log_area_provider,
            "dataset": self.params.dataset,
        }
        generator = self.etos.http.retry(
            "POST",
            "{}/configure".format(self.etos.debug.environment_provider),
            as_json=False,
            json=params,
        )
        for response in generator:
            print(response)
            break
        else:
            raise Exception(
                "Could not configure the Environment Provider with %r" %
                params)

    def handle(self):  # pylint: disable=duplicate-code
        """Handle this tester."""
        raise NotImplementedError

    @property
    def gql_response(self):
        """GQL response for artifact created and published events."""
        if self.__gql_response is None:
            request = "search: \"{{'data.identity': {{'$regex': '{}'}}}}\"".format(
                self.params.artifact_identity)
            wait_generator = self.etos.utils.wait(self.etos.graphql.execute,
                                                  query=ARTIFACT_REQUEST %
                                                  request)
            for response in wait_generator:
                self.__gql_response = response
                break
        return self.__gql_response

    @property
    def artifact_id(self):
        """Figure out Artifact event ID from event storage."""
        if self.__artifact_id is None:
            try:
                artifact_node = self.gql_response["artifactCreated"]["edges"][
                    0]["node"]
                self.__artifact_id = artifact_node["meta"]["id"]
            except (KeyError, IndexError):
                pass
        return self.__artifact_id
    def test_register_all_providers(self):
        """Test that the register backend can register all providers.

        Approval criteria:
            - The register backend shall be able to register all providers.

        Test steps:
            1. Register one of each provider with the register backend.
            2. Verify that the providers were stored in the database.
        """
        fake_database = FakeDatabase()
        etos = ETOS("testing_etos", "testing_etos", "testing_etos")
        jsontas = JsonTas()
        test_iut_provider = {
            "iut": {
                "id": "iut_provider_test",
                "list": {"available": [], "possible": []},
            }
        }
        test_execution_space_provider = {
            "execution_space": {
                "id": "execution_space_provider_test",
                "list": {"available": [{"identifier": "123"}], "possible": []},
            }
        }
        test_log_area_provider = {
            "log": {
                "id": "log_area_provider_test",
                "list": {"available": [], "possible": []},
            }
        }
        provider_registry = ProviderRegistry(etos, jsontas, fake_database)
        self.logger.info(
            "STEP: Register one of each provider with the register backend."
        )
        response = register(
            provider_registry,
            iut_provider=test_iut_provider,
            log_area_provider=test_log_area_provider,
            execution_space_provider=test_execution_space_provider,
        )

        self.logger.info("STEP: Verify that the providers were stored in the database.")
        stored_execution_space_provider = json.loads(
            fake_database.reader.hget(
                "EnvironmentProvider:ExecutionSpaceProviders",
                "execution_space_provider_test",
            )
        )
        self.assertDictEqual(
            stored_execution_space_provider,
            test_execution_space_provider,
        )
        stored_log_area_provider = json.loads(
            fake_database.reader.hget(
                "EnvironmentProvider:LogAreaProviders", "log_area_provider_test"
            )
        )
        self.assertDictEqual(stored_log_area_provider, test_log_area_provider)
        stored_iut_provider = json.loads(
            fake_database.reader.hget(
                "EnvironmentProvider:IUTProviders", "iut_provider_test"
            )
        )
        self.assertDictEqual(stored_iut_provider, test_iut_provider)
        self.assertTrue(response)
Exemple #29
0
class ETR:
    """ETOS Test Runner."""

    context = None

    def __init__(self):
        """Initialize ETOS library and start eiffel publisher."""
        self.etos = ETOS("ETOS Test Runner", os.getenv("HOSTNAME"),
                         "ETOS Test Runner")
        self.etos.config.rabbitmq_publisher_from_environment()
        # ETR will print the entire environment just before executing.
        # Hide the password.
        os.environ["RABBITMQ_PASSWORD"] = "******"

        self.etos.start_publisher()
        self.tests_url = os.getenv("SUB_SUITE_URL")

        signal.signal(signal.SIGTERM, self.graceful_shutdown)

    @staticmethod
    def graceful_shutdown(*args):
        """Catch sigterm."""
        raise Exception("ETR has been terminated.")

    def download_and_load(self):
        """Download and load test json."""
        generator = self.etos.http.wait_for_request(self.tests_url)
        for response in generator:
            json_config = response
            break
        self.etos.config.set("test_config", json_config)
        self.etos.config.set("context", json_config.get("context"))
        self.etos.config.set("artifact", json_config.get("artifact"))

    def _run_tests(self):
        """Run tests in ETOS test runner.

        :return: Results of test runner execution.
        :rtype: bool
        """
        iut = Iut(self.etos.config.get("test_config").get("iut"))
        test_runner = TestRunner(iut, self.etos)
        return test_runner.execute()

    def run_etr(self):
        """Send activity events and run ETR.

        :return: Result of testrunner execution.
        :rtype: bool
        """
        _LOGGER.info("Starting ETR.")
        self.download_and_load()
        try:
            activity_name = self.etos.config.get("test_config").get("name")
            triggered = self.etos.events.send_activity_triggered(activity_name)
            self.etos.events.send_activity_started(triggered)
            result = self._run_tests()
        except Exception as exc:  # pylint:disable=broad-except
            self.etos.events.send_activity_finished(triggered, {
                "conclusion": "FAILED",
                "description": str(exc)
            })
            raise
        self.etos.events.send_activity_finished(triggered,
                                                {"conclusion": "SUCCESSFUL"})
        _LOGGER.info("ETR finished.")
        return result
Exemple #30
0
    def test_get_configuration(self):
        """Test that it is possible to get a stored configuration.

        Approval criteria:
            - It shall be possible to get a stored configuration.

        Test steps:
            1. Store a configuration into the database.
            2. Verify that it is possible to get the stored configuration.
        """
        database = FakeDatabase()
        test_suite_id = "8d9344e3-a246-43ec-92b4-fc81ea31067a"
        test_dataset = {"dataset": "test"}
        test_iut_provider = OrderedDict({
            "iut": {
                "id": "iut_provider_test",
                "list": {
                    "available": [],
                    "possible": []
                },
            }
        })
        test_execution_space_provider = OrderedDict({
            "execution_space": {
                "id": "execution_space_provider_test",
                "list": {
                    "available": [{
                        "identifier": "123"
                    }],
                    "possible": []
                },
            }
        })
        test_log_area_provider = OrderedDict({
            "log": {
                "id": "log_area_provider_test",
                "list": {
                    "available": [],
                    "possible": []
                },
            }
        })
        self.logger.info("STEP: Store a configuration into the database.")
        database.writer.hset(f"EnvironmentProvider:{test_suite_id}", "Dataset",
                             json.dumps(test_dataset))
        database.writer.hset(
            f"EnvironmentProvider:{test_suite_id}",
            "IUTProvider",
            json.dumps(test_iut_provider),
        )
        database.writer.hset(
            f"EnvironmentProvider:{test_suite_id}",
            "ExecutionSpaceProvider",
            json.dumps(test_execution_space_provider),
        )
        database.writer.hset(
            f"EnvironmentProvider:{test_suite_id}",
            "LogAreaProvider",
            json.dumps(test_log_area_provider),
        )

        self.logger.info(
            "STEP: Verify that it is possible to get the stored configuration."
        )
        registry = ProviderRegistry(ETOS("", "", ""), JsonTas(), database)
        stored_configuration = get_configuration(registry, test_suite_id)
        self.assertDictEqual(
            stored_configuration,
            {
                "iut_provider":
                test_iut_provider["iut"],
                "execution_space_provider":
                test_execution_space_provider["execution_space"],
                "log_area_provider":
                test_log_area_provider["log"],
                "dataset":
                test_dataset,
            },
        )