Beispiel #1
0
    async def test_apps_stats_app_not_found(self):
        async with HttpClientContext(app) as client:
            local_address = (
                f"http://{client._server.host}:{client._server.port}")
            with aioresponses(
                    passthrough=[local_address, settings.STATS_API_URL
                                 ]) as rsps:
                agent_id = "ead07ffb-5a61-42c9-9386-21b680597e6c-S0"
                build_mesos_cluster(rsps, agent_id)  # namespace=asgard-infra

                app_stats_datapoints = get_fixture(
                    f"agents/{agent_id}/app_stats.json")

                resp = await client.get(
                    f"/apps/asgard/api/not-exist/stats?account_id={ACCOUNT_DEV_ID}",
                    headers={
                        "Authorization":
                        f"Token {USER_WITH_MULTIPLE_ACCOUNTS_AUTH_KEY}"
                    },
                )
                self.assertEqual(HTTPStatus.OK, resp.status)
                data = await resp.json()
                self.assertEqual(
                    AppStats(cpu_pct="0", ram_pct="0", cpu_thr_pct="0").dict(),
                    data["stats"],
                )
    async def test_get_apps_stats_with_data(self):
        """
        Prepara um ElasticSearch com alguns dados e faz o cálculo
        agregado do uso de CPU e RAM
        """
        app_stats_datapoints = get_fixture(
            f"agents/ead07ffb-5a61-42c9-9386-21b680597e6c-S0/app_stats.json")
        app = MesosApp(id="infra/asgard/api")

        await self._load_app_stats_into_storage(self.INDEX_NAME, self.utc_now,
                                                app_stats_datapoints)

        backend = MarathonAppsBackend()
        user = User(**USER_WITH_MULTIPLE_ACCOUNTS_DICT)
        account = Account(**ACCOUNT_DEV_DICT)
        async with Elasticsearch([settings.STATS_API_URL]) as es:
            raw = await es.search(index=self.INDEX_NAME)
            cpu_pcts = [
                hit["_source"]["cpu_pct"] for hit in raw["hits"]["hits"]
            ]
            mem_pcts = [
                hit["_source"]["mem_pct"] for hit in raw["hits"]["hits"]
            ]
            self.assertEqual(5, len(cpu_pcts))
            self.assertEqual(5, len(mem_pcts))

        app_stats = await backend.get_app_stats(app, user, account)
        self.assertEqual(
            AppStats(cpu_pct="0.25", ram_pct="15.05", cpu_thr_pct="1.00"),
            app_stats,
        )
Beispiel #3
0
    async def test_apps_stats_with_avg_1_min(self):
        with aioresponses(passthrough=[
                TEST_LOCAL_AIOHTTP_ADDRESS, settings.STATS_API_URL
        ]) as rsps:
            agent_id = "ead07ffb-5a61-42c9-9386-21b680597e6c-S0"

            build_mesos_cluster(rsps, agent_id)  # namespace=asgard-infra

            app_stats_datapoints = get_fixture(
                f"agents/{agent_id}/app_stats.json")

            await self._load_app_stats_into_storage(self.INDEX_NAME,
                                                    self.utc_now,
                                                    app_stats_datapoints)
            resp = await self.client.get(
                f"/apps/infra/asgard/api/stats/avg-1min?account_id={ACCOUNT_DEV_ID}",
                headers={
                    "Authorization":
                    f"Token {USER_WITH_MULTIPLE_ACCOUNTS_AUTH_KEY}"
                },
            )
            self.assertEqual(HTTPStatus.OK, resp.status)
            data = await resp.json()
            self.assertEqual(
                AppStats(cpu_pct="0.25", ram_pct="15.05",
                         cpu_thr_pct="1.00").dict(),
                data["stats"],
            )
 async def test_get_app_stats_has_some_data(self):
     with aioresponses() as rsps:
         agent_id = "ead07ffb-5a61-42c9-9386-21b680597e6c-S0"
         build_mesos_cluster(rsps, agent_id)
         add_agent_task_stats(rsps,
                              agent_id,
                              index_name="asgard-app-stats-2019-03-29-*")
         stats = await self.apps_backend.get_app_stats(
             MesosApp(id="infra-asgard-api"), self.user, self.account)
         self.assertEqual(
             AppStats(cpu_pct="4.51", ram_pct="22.68", cpu_thr_pct="2.89"),
             stats,
         )
Beispiel #5
0
    async def get_app_stats(self, app: App, interval: Interval, user: User,
                            account: Account) -> AppStats:
        utc_now = datetime.utcnow().replace(tzinfo=timezone.utc)
        index_name = f"asgard-app-stats-{utc_now.strftime('%Y-%m-%d')}-*"

        bool_query = Q(
            "bool",
            must=[
                Q("term", appname__keyword=f"/{account.namespace}/{app.id}"),
                Q("range", timestamp={"gte": f"now-{interval}"}),
            ],
        )
        query = Search().query(bool_query).extra(size=2)
        query.aggs.bucket("avg_cpu_pct", A("avg", field="cpu_pct"))
        query.aggs.bucket("avg_mem_pct", A("avg", field="mem_pct"))
        query.aggs.bucket("avg_cpu_thr_pct", A("avg", field="cpu_thr_pct"))
        dict_query = query.to_dict()

        errors = {}
        raw_result = None
        try:
            async with Elasticsearch([settings.STATS_API_URL]) as es:
                raw_result = await es.search(index=index_name, body=dict_query)
        except Exception as e:
            errors["global"] = str(e)

        if raw_result and raw_result["hits"]["hits"]:
            app_stats_result = raw_result["aggregations"]
            cpu_pct = round_up(
                Decimal(str(app_stats_result["avg_cpu_pct"]["value"])))
            mem_pct = round_up(
                Decimal(str(app_stats_result["avg_mem_pct"]["value"])))
            cpu_thr_pct = round_up(
                Decimal(str(app_stats_result["avg_cpu_thr_pct"]["value"])))
        else:
            cpu_pct = Decimal(0)
            mem_pct = Decimal(0)
            cpu_thr_pct = Decimal(0)

        return AppStats(
            cpu_pct=str(cpu_pct),
            ram_pct=str(mem_pct),
            cpu_thr_pct=str(cpu_thr_pct),
            errors=errors,
        )
    async def test_get_apps_stats_no_data(self):
        """
        Prepara um ElasticSearch com alguns dados e faz o cálculo
        agregado do uso de CPU e RAM
        """
        app_stats_datapoints = get_fixture(
            f"agents/ead07ffb-5a61-42c9-9386-21b680597e6c-S0/app_stats.json")
        app = MesosApp(id="infra/app-does-not-exist")

        await self._load_app_stats_into_storage(self.INDEX_NAME, self.utc_now,
                                                app_stats_datapoints)

        backend = MarathonAppsBackend()
        user = User(**USER_WITH_MULTIPLE_ACCOUNTS_DICT)
        account = Account(**ACCOUNT_DEV_DICT)
        app_stats = await backend.get_app_stats(app, user, account)
        self.assertEqual(AppStats(cpu_pct="0", ram_pct="0", cpu_thr_pct="0"),
                         app_stats)
    async def test_get_app_stats_exception_on_search(self):
        """
        Returns AppStats with errors filled if any exception happend during ES query
        """
        with aioresponses() as rsps:
            agent_id = "ead07ffb-5a61-42c9-9386-21b680597e6c-S0"
            build_mesos_cluster(rsps, agent_id)

            index_name = "asgard-app-stats-2019-03-29-*"
            url = f"{settings.STATS_API_URL}/{index_name}/_search"
            rsps.get(url, exception=Exception("Connection error to ES"))

            stats = await self.apps_backend.get_app_stats(
                MesosApp(id="infra-asgard-api"), self.user, self.account)
            self.assertEqual(
                AppStats(
                    cpu_pct="0",
                    ram_pct="0",
                    cpu_thr_pct="0",
                    errors={"global": "Connection error to ES"},
                ),
                stats,
            )
Beispiel #8
0
    async def test_apps_stats_app_not_found(self):
        with aioresponses(passthrough=[
                TEST_LOCAL_AIOHTTP_ADDRESS, settings.STATS_API_URL
        ]) as rsps:
            agent_id = "ead07ffb-5a61-42c9-9386-21b680597e6c-S0"
            build_mesos_cluster(rsps, agent_id)  # namespace=asgard-infra

            app_stats_datapoints = get_fixture(
                f"agents/{agent_id}/app_stats.json")

            resp = await self.client.get(
                f"/apps/asgard/api/not-exist/stats?account_id={ACCOUNT_DEV_ID}",
                headers={
                    "Authorization":
                    f"Token {USER_WITH_MULTIPLE_ACCOUNTS_AUTH_KEY}"
                },
            )
            self.assertEqual(200, resp.status)
            data = await resp.json()
            self.assertEqual(
                AppStats(cpu_pct="0", ram_pct="0", cpu_thr_pct="0").dict(),
                data["stats"],
            )