async def apps(self) -> List[MesosApp]: self_address = f"http://{self.hostname}:{self.port}" containers_url = f"{self_address}/containers" apps = [] async with http_client.get(containers_url) as response: data = await response.json() all_apps: Set[str] = set() for container_info in data: app_id = MesosApp.transform_to_asgard_app_id( container_info["executor_id"]) if app_id not in all_apps: apps.append(MesosApp(**{"id": app_id})) all_apps.add(app_id) return apps
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, )
async def test_calls_backend_with_correct_parameters(self): orchestrator = CoroutineMock(spec=Orchestrator) app_id = "infra/app/nodes" app = MesosApp(id=app_id) await AppsService.get_app_stats(app_id, self.user, self.account, orchestrator) orchestrator.get_app_stats.assert_awaited_with(app, self.user, self.account)
async def get_app_stats(app_id: str, user: User, account: Account, orchestrator: Orchestrator) -> AppStats: """ Retorna estatísticas de uso de CPU/RAM/CPU thr de uma app. O Cálculo considera todas as instâncias dessa app. Retorna um objeto :py:class:`AppStats <asgard.models.app.AppStats>` """ app = MesosApp(id=app_id) return await orchestrator.get_app_stats(app, user, account)
async def test_get_app_stats_calls_backend_with_correct_parameters(self): app = MesosApp(id="my-app") interval = Interval.ONE_HOUR apps_backend_mock = mock.CoroutineMock( get_app_stats=mock.CoroutineMock()) mesos_orchestrator = MesosOrchestrator(MesosAgentsBackend(), apps_backend_mock) await mesos_orchestrator.get_app_stats(app, self.user, interval, self.account) apps_backend_mock.get_app_stats.assert_awaited_with( app, self.user, interval, self.account)
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, )
def test_it_instantiates_a_agentsresource_using_agents_instances(self): apps = [ MesosApp(**dict( id= "sieve_infra_asgard_async-api.7e5d20eb-248a-11e9-91ea-024286d5b96a", source= "sieve_infra_asgard_async-api.7e5d20eb-248a-11e9-91ea-024286d5b96a", framework_id="27b52920-3899-4b90-a1d6-bf83a87f3612-0000", )) ] resource = AppsResource(apps=apps) self.assertIsInstance(resource, AppsResource) for agent in resource.apps: self.assertIsInstance(agent, MesosApp)
async def tasks(self, app_id: str) -> List[MesosTask]: self_address = f"http://{self.hostname}:{self.port}" containers_url = f"{self_address}/containers" async with http_client.get(containers_url) as response: data = await response.json() tasks_per_app: Dict[str, List[MesosTask]] = defaultdict(list) for container_info in data: app_id_ = MesosApp.transform_to_asgard_app_id( container_info["executor_id"]) tasks_per_app[app_id_].append( MesosTask( **{ "name": MesosTask.transform_to_asgard_task_id( container_info["executor_id"]) })) return tasks_per_app[app_id]
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, )