async def test_get_accounts_from_user_user_has_accounts(self): user = User(**USER_WITH_MULTIPLE_ACCOUNTS_DICT) accounts = await self.backend.get_accounts_from_user(user) self.assertCountEqual( [Account(**ACCOUNT_DEV_DICT), Account(**ACCOUNT_INFRA_DICT)], accounts, )
async def test_get_alternate_accounts_for_user(self): user = User(**USER_WITH_MULTIPLE_ACCOUNTS_DICT) current_account = Account(**ACCOUNT_DEV_DICT) accounts = await UsersBackend().get_alternate_accounts( user, current_account ) self.assertEqual(1, len(accounts)) self.assertEqual([Account(**ACCOUNT_INFRA_DICT)], accounts)
async def setUp(self): await super(AccountEndpointsTest, self).setUp() self.account_dev = Account(**ACCOUNT_DEV_DICT) self.account_infra = Account(**ACCOUNT_INFRA_DICT) self.user = User(**USER_WITH_MULTIPLE_ACCOUNTS_DICT) self.user_with_one_account = User(**USER_WITH_ONE_ACCOUNT_DICT)
async def setUp(self): self.user = User(**USER_WITH_MULTIPLE_ACCOUNTS_DICT) self.account = Account(**ACCOUNT_DEV_DICT) self.account.owner = "asgard" self.account_dev = Account(**ACCOUNT_DEV_DICT) self.mesos_backend = MesosOrchestrator(MesosAgentsBackend(), MarathonAppsBackend())
async def test_accounts_remove_from_account_user_already_in_account(self): account = Account(**ACCOUNT_DEV_DICT) user = User(**USER_WITH_ONE_ACCOUNT_DICT) self.assertTrue(await account.user_has_permission(user)) await self.backend.remove_user(user, account) self.assertFalse(await account.user_has_permission(user)) account2 = Account(**ACCOUNT_INFRA_DICT) self.assertTrue(await account2.user_has_permission( User(**USER_WITH_MULTIPLE_ACCOUNTS_DICT)))
async def test_create_job_force_owner_constraint_if_already_exist(self): """ Mesmo se o Job sendo criado já tiver a constraint `owner:LIKE:...` temos que substituir por `owner:LIKE:{account.owner}` """ user = User(**USER_WITH_MULTIPLE_ACCOUNTS_DICT) account = Account(**ACCOUNT_DEV_DICT) await _cleanup_chronos() self.asgard_job.add_constraint("owner:LIKE:other-value") returned_job = await self.backend.create_job( self.asgard_job, user, account ) stored_job = await self.backend.get_job_by_id( returned_job.id, user, account ) self.assertCountEqual( [ "hostname:LIKE:10.0.0.1", "workload:LIKE:general", f"owner:LIKE:{account.owner}", ], stored_job.constraints, )
async def test_list_jobs_do_not_include_jobs_from_alternate_account( self, dev_job_fixture, infra_job_fixture): """ Valida o parametro ?account_id= """ await _load_jobs_into_chronos(dev_job_fixture, infra_job_fixture) account = Account(**ACCOUNT_INFRA_DICT) resp = await self.client.get( "/jobs", headers={ "Authorization": f"Token {USER_WITH_MULTIPLE_ACCOUNTS_AUTH_KEY}" }, params={"account_id": ACCOUNT_INFRA_ID}, ) self.assertEqual(HTTPStatus.OK, resp.status) expected_asgard_jobs = [ ChronosScheduledJobConverter.to_asgard_model( ChronosJob(**infra_job_fixture)).remove_namespace(account) ] resp_data = await resp.json() self.assertEqual( ScheduledJobsListResource(jobs=expected_asgard_jobs).dict(), resp_data, )
async def test_create_job_validation_error(self, infra_job_fixture): """ Validamos que retornamos HTTPStatus.UNPROCESSABLE_ENTITY caso a entrada esteja incompleta """ account = Account(**ACCOUNT_DEV_DICT) asgard_job_no_namespace = ChronosScheduledJobConverter.to_asgard_model( ChronosJob(**infra_job_fixture)).remove_namespace(account) incomplete_asgard_job = asgard_job_no_namespace.dict() del incomplete_asgard_job["container"] resp = await self.client.post( "/jobs", headers={ "Authorization": f"Token {USER_WITH_MULTIPLE_ACCOUNTS_AUTH_KEY}" }, json=incomplete_asgard_job, ) self.assertEqual(HTTPStatus.UNPROCESSABLE_ENTITY, resp.status) resp_data = await resp.json() expected_error_msg = """1 validation error for ScheduledJob\ncontainer\n field required (type=value_error.missing)""" self.assertEqual( ErrorResource(errors=[ErrorDetail(msg=expected_error_msg)]).dict(), resp_data, )
async def test_create_job_name_has_namespace_from_another_account( self, infra_job_fixture): await _cleanup_chronos() account = Account(**ACCOUNT_DEV_DICT) asgard_job_no_namespace = ChronosScheduledJobConverter.to_asgard_model( ChronosJob(**infra_job_fixture)).remove_namespace(account) resp = await self.client.post( "/jobs", headers={ "Authorization": f"Token {USER_WITH_MULTIPLE_ACCOUNTS_AUTH_KEY}" }, json=asgard_job_no_namespace.dict(), ) self.assertEqual(HTTPStatus.CREATED, resp.status) resp_data = await resp.json() self.assertEqual( f"{asgard_job_no_namespace.id}", CreateScheduledJobResource(**resp_data).job.id, ) await asyncio.sleep(0.3) resp_created_job = await self.client.get( f"/jobs/{asgard_job_no_namespace.id}", headers={ "Authorization": f"Token {USER_WITH_MULTIPLE_ACCOUNTS_AUTH_KEY}" }, ) self.assertEqual(HTTPStatus.OK, resp_created_job.status)
async def test_list_jobs_return_ordered_by_name(self, dev_with_infra_fixture, dev_another_job_fixture): await _load_jobs_into_chronos(dev_another_job_fixture, dev_with_infra_fixture) account = Account(**ACCOUNT_DEV_DICT) resp = await self.client.get( "/jobs", headers={ "Authorization": f"Token {USER_WITH_MULTIPLE_ACCOUNTS_AUTH_KEY}" }, ) self.assertEqual(HTTPStatus.OK, resp.status) expected_asgard_jobs = [ ChronosScheduledJobConverter.to_asgard_model( ChronosJob( **dev_another_job_fixture)).remove_namespace(account), ChronosScheduledJobConverter.to_asgard_model( ChronosJob( **dev_with_infra_fixture)).remove_namespace(account), ] resp_data = await resp.json() self.assertEqual(expected_asgard_jobs[0], resp_data["jobs"][0]) self.assertEqual(expected_asgard_jobs[1], resp_data["jobs"][1])
async def test_update_job_change_root_fields(self): await _load_jobs_into_chronos(self.chronos_dev_job_fixture) user = User(**USER_WITH_MULTIPLE_ACCOUNTS_DICT) account = Account(**ACCOUNT_DEV_DICT) self.asgard_job._remove_constraint_by_name("owner") self.asgard_job.remove_namespace(account) self.asgard_job.cpus = 2 self.asgard_job.mem = 1024 self.asgard_job.description = "Minha description" self.asgard_job.retries = 4 updated_job = await self.backend.update_job( self.asgard_job, user, account ) stored_job = await self.backend.get_job_by_id( updated_job.id, user, account ) self.assertEqual(self.asgard_job.cpus, stored_job.cpus) self.assertEqual(self.asgard_job.mem, stored_job.mem) self.assertEqual(self.asgard_job.description, stored_job.description) self.assertEqual(self.asgard_job.retries, stored_job.retries)
def test_change_request_path_if_is_write_on_one_app(self, fixture): """ Quando fazemos WRITE em cima de uma app específica, devemos ajustar o request.path para que o `upstream_request` seja feito no endpoint correto. """ user = User(tx_name="User One", tx_email="*****@*****.**") user.current_account = Account(name="Dev", namespace="dev", owner="company") full_app_with_name_space = deepcopy(fixture) full_app_with_name_space["id"] = "/dev/foo" with application.test_request_context("/v2/apps//foo", method="PUT", data=json.dumps(fixture)) as ctx: with RequestsMock() as rsps: rsps.add( method="GET", url=conf.MARATHON_ADDRESSES[0] + "/v2/apps//dev/foo", body=json.dumps({"app": full_app_with_name_space}), status=200, ) ctx.request.user = user request_parser = Request(ctx.request) apps = list(request_parser.split()) request = request_parser.join(apps) self.assertIsInstance(request, HollowmanRequest) self.assertEqual("/v2/apps/dev/foo", request.path)
async def test_accounts_add_user_success(self): account = Account(**ACCOUNT_WITH_NO_USERS_DICT) user = User(**USER_WITH_ONE_ACCOUNT_DICT) self.assertFalse(await account.user_has_permission(user)) await self.backend.add_user(user, account) self.assertTrue(await account.user_has_permission(user))
async def test_accounts_remove_from_account_user_not_in_account(self): account = Account(**ACCOUNT_WITH_NO_USERS_DICT) user = User(**USER_WITH_ONE_ACCOUNT_DICT) self.assertFalse(await account.user_has_permission(user)) await self.backend.remove_user(user, account) self.assertFalse(await account.user_has_permission(user))
async def test_list_jobs_empty_result(self): user = User(**USER_WITH_MULTIPLE_ACCOUNTS_DICT) account = Account(**ACCOUNT_DEV_DICT) account.namespace = "namespace-does-not-have-any-jobs" jobs = await self.backend.list_jobs(user, account) self.assertCountEqual([], jobs)
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 setUp(self): await super(DeploymentsTests, self).setUp() token = jwt_encode( User(**USER_WITH_MULTIPLE_ACCOUNTS_DICT), Account(**ACCOUNT_DEV_DICT), ) self.auth_header = {"Authorization": f"JWT {token.decode('utf-8')}"}
async def test_remove_account_namespace_app_id_does_not_have_namespace( self): app = ScheduledJob(**self.required_fields_scheduled_job) account = Account(**ACCOUNT_DEV_DICT) self.assertEqual(self.required_fields_scheduled_job["id"], app.id) app.remove_namespace(account) self.assertEqual(self.required_fields_scheduled_job["id"], app.id)
async def test_change_account_does_not_exist(self): jwt_token = jwt_encode(User(**USER_WITH_ONE_ACCOUNT_DICT), Account(**ACCOUNT_DEV_DICT)) resp = await self.client.get( f"/accounts/8000/auth", headers={"Authorization": f"JWT {jwt_token.decode('utf-8')}"}, ) self.assertEqual(403, resp.status)
def setUp(self): self.empty_ok_response = FlaskResponse(response=b"{}", status=HTTPStatus.OK, headers={}) self.user = User(tx_name="User One", tx_email="*****@*****.**") self.user.current_account = Account(name="Dev", namespace="dev", owner="company")
async def test_update_job_job_does_not_exist(self): user = User(**USER_WITH_MULTIPLE_ACCOUNTS_DICT) account = Account(**ACCOUNT_DEV_DICT) await _cleanup_chronos() with self.assertRaises(NotFoundEntity): await self.backend.update_job(self.asgard_job, user, account)
async def test_get_accounts_from_user_user_with_accounts(self): resp = await self.client.get( f"/users/{USER_WITH_MULTIPLE_ACCOUNTS_ID}/accounts", headers={ "Authorization": f"Token {USER_WITH_MULTIPLE_ACCOUNTS_AUTH_KEY}" }, ) self.assertEqual(200, resp.status) accounts_data = await resp.json() self.assertEqual( UserAccountsResource(accounts=[ Account(**ACCOUNT_DEV_DICT), Account(**ACCOUNT_INFRA_DICT), ]).dict(), accounts_data, )
async def test_user_has_permission_permission_denied(self): """ Dado um objeto User e um objeto Account, account.user_has_permission(user) retorna True/False se o usuário tem ou não permissão para acessar essa conta. """ user = User(**USER_WITH_NO_ACCOUNTS_DICT) account = Account(**ACCOUNT_DEV_DICT) self.assertFalse(await account.user_has_permission(user))
def setUp(self): single_full_app_fixture = get_fixture("single_full_app.json") self.filter = AddOwnerConstraintFilter() self.request_app = AsgardApp.from_json(single_full_app_fixture) self.original_app = AsgardApp.from_json(single_full_app_fixture) self.user = UserDB() self.account_dev = Account(**ACCOUNT_DEV_DICT) self.user.current_account = self.account_dev
def setUp(self, single_full_app_fixture): self.filter = DefaultScaleFilter() self.request_app = AsgardApp.from_json(single_full_app_fixture) self.original_app = AsgardApp.from_json(single_full_app_fixture) self.account = Account(name="Dev Account", namespace="dev", owner="company") self.user = User(tx_email="*****@*****.**") self.user.current_account = self.account
async def test_remove_namepace_returns_self(self): account = Account(**ACCOUNT_DEV_DICT) self.required_fields_scheduled_job[ "id"] = f"my-app-with-{account.namespace}-ns" app = ScheduledJob(**self.required_fields_scheduled_job) returned_app = app.remove_namespace(account) self.assertTrue(app is returned_app)
async def test_remove_namespace_only_once(self): account = Account(**ACCOUNT_DEV_DICT) self.required_fields_scheduled_job[ "id"] = f"{account.namespace}-{account.namespace}-my-app-with-ns" app = ScheduledJob(**self.required_fields_scheduled_job) app.remove_namespace(account) expected_app_id = f"{account.namespace}-my-app-with-ns" self.assertEqual(expected_app_id, app.id)
async def test_add_account_namespace_to_name(self): app = ScheduledJob(**self.required_fields_scheduled_job) account = Account(**ACCOUNT_DEV_DICT) self.assertEqual(self.required_fields_scheduled_job["id"], app.id) app.add_namespace(account) expected_app_id = ( f"{account.namespace}-{self.required_fields_scheduled_job['id'] }") self.assertEqual(expected_app_id, app.id)
async def setUp(self): await super(AgentsServiceTest, self).setUp() self.mesos_orchestrator = MesosOrchestrator( agents_backend=MesosAgentsBackend(), apps_backend=MarathonAppsBackend(), ) self.user = User(**USER_WITH_MULTIPLE_ACCOUNTS_DICT) self.account = Account(**ACCOUNT_DEV_DICT) self.agents_service = AgentsService()
async def setUp(self): await super(AuthenticationTest, self).setUp() self.normal_user = UserDB( tx_email=USER_WITH_MULTIPLE_ACCOUNTS_EMAIL, tx_name=USER_WITH_MULTIPLE_ACCOUNTS_NAME, ) self.account = Account(**ACCOUNT_DEV_DICT) self.response_http_200 = Response(status=200)