def test_join_apps_read_empty_list(self): with application.test_request_context("/v2/apps", method="GET") as ctx: ctx.request.user = self.user request = Request(ctx.request) with RequestsMock() as rsps: rsps.add( method="GET", url=conf.MARATHON_ADDRESSES[0] + "/v2/groups//dev/", status=200, body=json.dumps({"apps": []}), ) apps = list(request.split()) joined_request = request.join(apps) self.assertEqual("/v2/apps", joined_request.path) self.assertEqual(b"", joined_request.data)
def test_join_group_read_root_group(self, group_dev_namespace_fixture): with application.test_request_context('/v2/groups', method='GET') as ctx: ctx.request.user = self.user request = Request(ctx.request) with RequestsMock() as rsps: rsps.add(method='GET', url=conf.MARATHON_ADDRESSES[0] + '/v2/groups//dev/', body=json.dumps(group_dev_namespace_fixture), status=200) apps = list(request.split()) joined_request = request.join(apps) self.assertEqual("/v2/groups/dev", joined_request.path) self.assertEqual(b"", joined_request.data)
def test_with_invalid_grant_request_no_json(token_cache, responses: RequestsMock, monkeypatch, browser_mock: BrowserMock): monkeypatch.setattr(requests_auth.authentication.os, "urandom", lambda x: b"1" * 63) auth = requests_auth.OAuth2AuthorizationCodePKCE( "http://provide_code?nonce=123456", "http://provide_access_token") tab = browser_mock.add_response( opened_url= "http://provide_code?response_type=code&state=163f0455b3e9cad3ca04254e5a0169553100d3aa0756c7964d897da316a695ffed5b4f46ef305094fd0a88cfe4b55ff257652015e4aa8f87b97513dba440f8de&redirect_uri=http%3A%2F%2Flocalhost%3A5000%2F&nonce=%5B%27123456%27%5D&code_challenge=5C_ph_KZ3DstYUc965SiqmKAA-ShvKF4Ut7daKd3fjc&code_challenge_method=S256", reply_url= "http://localhost:5000#code=SplxlOBeZQQYbYS6WxSbIA&state=163f0455b3e9cad3ca04254e5a0169553100d3aa0756c7964d897da316a695ffed5b4f46ef305094fd0a88cfe4b55ff257652015e4aa8f87b97513dba440f8de", ) responses.add(responses.POST, "http://provide_access_token", body="failure", status=400) with pytest.raises(requests_auth.InvalidGrantRequest) as exception_info: requests.get("http://authorized_only", auth=auth) assert str(exception_info.value) == "failure" tab.assert_success( "You are now authenticated on 163f0455b3e9cad3ca04254e5a0169553100d3aa0756c7964d897da316a695ffed5b4f46ef305094fd0a88cfe4b55ff257652015e4aa8f87b97513dba440f8de. You may close this tab." )
def test_oauth2_authorization_code_flow_uses_provided_session( token_cache, responses: RequestsMock, browser_mock: BrowserMock): session = requests.Session() session.headers.update({"x-test": "Test value"}) auth = requests_auth.OAuth2AuthorizationCode("http://provide_code", "http://provide_access_token", session=session) tab = browser_mock.add_response( opened_url= "http://provide_code?response_type=code&state=163f0455b3e9cad3ca04254e5a0169553100d3aa0756c7964d897da316a695ffed5b4f46ef305094fd0a88cfe4b55ff257652015e4aa8f87b97513dba440f8de&redirect_uri=http%3A%2F%2Flocalhost%3A5000%2F", reply_url= "http://localhost:5000#code=SplxlOBeZQQYbYS6WxSbIA&state=163f0455b3e9cad3ca04254e5a0169553100d3aa0756c7964d897da316a695ffed5b4f46ef305094fd0a88cfe4b55ff257652015e4aa8f87b97513dba440f8de", ) responses.add( responses.POST, "http://provide_access_token", json={ "access_token": "2YotnFZFEjr1zCsicMWpAA", "token_type": "example", "expires_in": 3600, "refresh_token": "tGzv3JOkF0XG5Qx2TlKWIA", "example_parameter": "example_value", }, ) assert (get_header( responses, auth).get("Authorization") == "Bearer 2YotnFZFEjr1zCsicMWpAA") request = get_request(responses, "http://provide_access_token/") assert ( request.body == "grant_type=authorization_code&redirect_uri=http%3A%2F%2Flocalhost%3A5000%2F&response_type=code&code=SplxlOBeZQQYbYS6WxSbIA" ) assert request.headers["x-test"] == "Test value" tab.assert_success( "You are now authenticated on 163f0455b3e9cad3ca04254e5a0169553100d3aa0756c7964d897da316a695ffed5b4f46ef305094fd0a88cfe4b55ff257652015e4aa8f87b97513dba440f8de. You may close this tab." )
def test_create_new_bookmark(test_app, client: FlaskClient, mocked_responses: RequestsMock): mocked_responses.add(GET, "https://example.com/", body="""<html> <head><title>Random</title></head><body><p> Lorem ipsum dolor sit amet, consectetur adipiscing elit </p></body></html> """) bookmark_data = { "url": "https://example.com", "tags": "testing,bookmark", "desc": "", "path": "not classified", "submit": "true" } resp = client.post("/bookmarks/new", data=bookmark_data) assert resp.status_code == 302 assert not b"invalid" in resp.data resp = client.post("/bookmarks/new", data=bookmark_data, follow_redirects=True) assert resp.status_code == 200 assert b"testing, bookmark" in resp.data assert b"https://example.com" in resp.data assert b"Random" in resp.data
def test_with_invalid_grant_request_invalid_client_error( token_cache, responses: RequestsMock): auth = requests_auth.OAuth2ResourceOwnerPasswordCredentials( "http://provide_access_token", username="******", password="******") responses.add( responses.POST, "http://provide_access_token", json={"error": "invalid_client"}, status=400, ) with pytest.raises(requests_auth.InvalidGrantRequest) as exception_info: requests.get("http://authorized_only", auth=auth) assert ( str(exception_info.value) == "invalid_client: Client authentication failed (e.g., unknown client, no " "client authentication included, or unsupported authentication method). The " "authorization server MAY return an HTTP 401 (Unauthorized) status code to " "indicate which HTTP authentication schemes are supported. If the client " 'attempted to authenticate via the "Authorization" request header field, the ' "authorization server MUST respond with an HTTP 401 (Unauthorized) status " 'code and include the "WWW-Authenticate" response header field matching the ' "authentication scheme used by the client.")
def test_oauth2_pkce_flow_get_code_is_sent_in_authorization_header_by_default( token_cache, responses: RequestsMock, monkeypatch, browser_mock: BrowserMock): monkeypatch.setattr(requests_auth.authentication.os, "urandom", lambda x: b"1" * 63) auth = requests_auth.OktaAuthorizationCodePKCE( "testserver.okta-emea.com", "54239d18-c68c-4c47-8bdd-ce71ea1d50cd") tab = browser_mock.add_response( opened_url= "https://testserver.okta-emea.com/oauth2/default/v1/authorize?client_id=54239d18-c68c-4c47-8bdd-ce71ea1d50cd&scope=openid&response_type=code&state=5264d11c8b268ccf911ce564ca42fd75cea68c4a3c1ec3ac1ab20243891ab7cd5250ad4c2d002017c6e8ac2ba34954293baa5e0e4fd00bb9ffd4a39c45f1960b&redirect_uri=http%3A%2F%2Flocalhost%3A5000%2F&code_challenge=5C_ph_KZ3DstYUc965SiqmKAA-ShvKF4Ut7daKd3fjc&code_challenge_method=S256", reply_url= "http://localhost:5000#code=SplxlOBeZQQYbYS6WxSbIA&state=5264d11c8b268ccf911ce564ca42fd75cea68c4a3c1ec3ac1ab20243891ab7cd5250ad4c2d002017c6e8ac2ba34954293baa5e0e4fd00bb9ffd4a39c45f1960b", ) responses.add( responses.POST, "https://testserver.okta-emea.com/oauth2/default/v1/token", json={ "access_token": "2YotnFZFEjr1zCsicMWpAA", "token_type": "example", "expires_in": 3600, "refresh_token": "tGzv3JOkF0XG5Qx2TlKWIA", "example_parameter": "example_value", }, ) assert (get_header( responses, auth).get("Authorization") == "Bearer 2YotnFZFEjr1zCsicMWpAA") assert ( get_request( responses, "https://testserver.okta-emea.com/oauth2/default/v1/token").body == "code_verifier=MTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTEx&grant_type=authorization_code&redirect_uri=http%3A%2F%2Flocalhost%3A5000%2F&client_id=54239d18-c68c-4c47-8bdd-ce71ea1d50cd&scope=openid&response_type=code&code=SplxlOBeZQQYbYS6WxSbIA" ) tab.assert_success( "You are now authenticated on 5264d11c8b268ccf911ce564ca42fd75cea68c4a3c1ec3ac1ab20243891ab7cd5250ad4c2d002017c6e8ac2ba34954293baa5e0e4fd00bb9ffd4a39c45f1960b. You may close this tab." )
def test_do_not_dispatch_response_pipeline_if_upstream_returns_404(self): auth_header = { "Authorization": "Token 69ed620926be4067a36402c3f7e9ddf0" } with application.test_client() as client: with RequestsMock() as rsps: rsps.add(method='GET', url=conf.MARATHON_ADDRESSES[0] + '/v2/apps//dev/foo', body=json.dumps({'message': "App /foo not found"}), status=404) rsps.add(method='GET', url=conf.MARATHON_ADDRESSES[0] + '/v2/apps/dev/foo', body=json.dumps({'message': "App /foo not found"}), status=404) response = client.get("/v2/apps/foo", headers=auth_header) self.assertEqual(404, response.status_code)
def test_remove_x_marathon_leader_header_from_upsream_response(self): marathon_addresses = ["http://127.0.0.1:8080"] with RequestsMock() as rsps, patch.multiple( hollowman.conf, MARATHON_ADDRESSES=marathon_addresses), patch.multiple( hollowman.conf, MARATHON_LEADER=marathon_addresses[0]): rsps.add( "GET", url=marathon_addresses[0] + "/v2/apps", status=200, body="OK", headers={"X-Marathon-Leader": marathon_addresses[0]}, ) response = _make_request("/v2/apps", "get") self.assertEqual(response.status_code, 200) self.assertTrue("x-marathon-leader" not in response.headers.keys())
def test_get_tasks_count_endpoint(self, master_tasks_fixture): client = self.application.test_client() with RequestsMock() as rsps: rsps.add(method='GET', url="http://10.0.0.1:5050/tasks?limit=-1", body=json.dumps(master_tasks_fixture), status=200, match_querystring=True) response = client.get("/metrics/tasks/count") self.assertEqual(200, response.status_code) response_data = json.loads(response.data) self.assertEqual(2, response_data['task_running']) self.assertEqual(1, response_data['task_failed']) self.assertEqual(2, response_data['task_finished']) self.assertEqual(1, response_data['task_killed']) self.assertEqual(6, response_data['total'])
def test_tasks_download_file(self, one_task_json_fixture, one_slave_json_fixture, slave_state_fixture): """ Certifica que a chamada ao endpoint de download popula o cache com os dados Teremos nos cache dados como: url, task_id, path do arquivo a ser baixado, etc. """ slave_id = "31fcae61-51a9-4ad1-8054-538503eb53a9-S5" slave_ip = one_slave_json_fixture['slaves'][0]['hostname'] task_id = "infra_mongodb_mongodb1.2580925d-0129-11e8-9a03-6e85ded2ca1e" sandbox_directory = "/tmp/mesos/slaves/31fcae61-51a9-4ad1-8054-538503eb53a9-S5/frameworks/27b52920-3899-4b90-a1d6-bf83a87f3612-0000/executors/dev_infra_mongodb_mongodb1.2580925d-0129-11e8-9a03-6e85ded2ca1e/runs/1ec0d0bf-0f11-49ba-8a03-2cf954ad1cfe" with application.test_client() as client: with RequestsMock() as rsps: rsps.add( method="GET", url= f"{DEFAULT_MESOS_ADDRESS}/tasks?task_id={self.user.current_account.namespace}_{task_id}", body=json.dumps(one_task_json_fixture), status=200, match_querystring=True) rsps.add( method="GET", url=f"{DEFAULT_MESOS_ADDRESS}/slaves?slave_id={slave_id}", body=json.dumps(one_slave_json_fixture), status=200, match_querystring=True) rsps.add(method="GET", url="http://127.0.0.1:5051/state", body=json.dumps(slave_state_fixture), status=200) download_id = "7094c8e5b131416a87ccdc3e7d3131a6" with unittest.mock.patch.object(cache, "set") as cache_set_mock, \ unittest.mock.patch.object(api.tasks, 'uuid4', return_value=unittest.mock.Mock(hex=download_id)) as uuid4_mock: resp = client.get( f"/tasks/{task_id}/files/download?path=/stdout&offset=0&length=42", headers=self.auth_header) self.assertEquals(HTTPStatus.OK, resp.status_code) resp_data = json.loads(resp.data) self.assertEqual( "tasks/downloads/7094c8e5b131416a87ccdc3e7d3131a6", resp_data["download_url"]) cache_set_mock.assert_called_with(f"downloads/{download_id}", { 'file_url': f"http://{slave_ip}:5051/files/download?path={sandbox_directory}/stdout", 'task_id': task_id, 'file_path': "/stdout" }, timeout=30)
def test_download_by_id_task_running(self, one_task_json_fixture, one_slave_json_fixture, slave_state_fixture): """ Retornamos o arquivo desejado """ task_file_download_fixture = get_raw_fixture( "../fixtures/api/tasks/task_file_download_response.txt") slave_ip = one_slave_json_fixture["slaves"][0]["hostname"] slave_id = "31fcae61-51a9-4ad1-8054-538503eb53a9-S5" task_id = "infra_mongodb_mongodb1.2580925d-0129-11e8-9a03-6e85ded2ca1e" sandbox_directory = "/tmp/mesos/slaves/31fcae61-51a9-4ad1-8054-538503eb53a9-S5/frameworks/27b52920-3899-4b90-a1d6-bf83a87f3612-0000/executors/dev_infra_mongodb_mongodb1.2580925d-0129-11e8-9a03-6e85ded2ca1e/runs/1ec0d0bf-0f11-49ba-8a03-2cf954ad1cfe" with application.test_client() as client: with RequestsMock() as rsps: rsps.add( method="GET", url= f"http://127.0.0.1:5051/files/download?path={sandbox_directory}/stdout", body=task_file_download_fixture, status=200, match_querystring=True, ) download_id = "7094c8e5b131416a87ccdc3e7d3131a6" cache_data = { "file_url": f"http://{slave_ip}:5051/files/download?path={sandbox_directory}/stdout", "task_id": task_id, "file_path": "/stdout", } with unittest.mock.patch.object( cache, "get", return_value=cache_data), unittest.mock.patch.object( api.tasks, "uuid4", return_value=unittest.mock.Mock(hex=download_id), ) as uuid4_mock: resp = client.get( f"/tasks/downloads/{download_id}", headers=self.auth_header, ) self.assertEquals(200, resp.status_code) self.assertEqual( bytes(task_file_download_fixture, "utf-8"), resp.data) self.assertEqual( resp.headers.get("Content-Disposition"), f"attachment; filename={task_id}_stdout.log", )
def test_split_group_nonroot_empty_group(self, non_root_group_empty_fixture): with application.test_request_context('/v2/groups/group-c', method='GET') as ctx: ctx.request.user = self.user request_parser = Request(ctx.request) with RequestsMock() as rsps: rsps.add(method='GET', url=conf.MARATHON_ADDRESSES[0] + '/v2/groups//dev/group-c', body=json.dumps(non_root_group_empty_fixture), status=200) apps = list(request_parser.split()) self.assertEqual(0, len(apps)) self.assertEqual([], apps)
def test_get_original_group_migrated(self): found_group = {"id": "/dev/foo", "apps": [], "groups": []} with application.test_request_context("/v2/groups//foo", method="GET") as ctx: with RequestsMock() as rsps: rsps.add( method="GET", url=conf.MARATHON_ADDRESSES[0] + "/v2/groups//dev/foo", body=json.dumps(found_group), status=200, ) ctx.request.user = self.user request = Request(ctx.request) group = request._get_original_group(self.user, "/foo") self.assertTrue(isinstance(group, AsgardAppGroup)) self.assertEqual(AsgardAppGroup.from_json(found_group), group)
def test_get_mesos_leader_ip(self): mesos_addresses = [ "http://10.0.2.1:5050", "http://10.0.2.3:5050", "http://10.0.2.2:5050" ] with mock.patch.dict(os.environ, {"HOLLOWMAN_MESOS_ADDRESS_0": mesos_addresses[0], "HOLLOWMAN_MESOS_ADDRESS_1": mesos_addresses[1], "HOLLOWMAN_MESOS_ADDRESS_2": mesos_addresses[2]}), \ RequestsMock() as rsps: rsps.add("GET", url=mesos_addresses[1] + "/redirect", status=307, body="", headers={"Location": "//10.0.2.2:5050"}) mesos_leader_ip = get_mesos_leader_address() self.assertEqual("http://10.0.2.2:5050", mesos_leader_ip)
def test_v2_deployments_delete(self, fixture): with application.test_client() as client, RequestsMock( ) as rsps, patch( "hollowman.request_handlers.Deployments._apply_response_filters" ) as _apply_response_filters: response_data = json.dumps(fixture) rsps.add( url=f"{conf.MARATHON_ADDRESSES[0]}/v2/deployments/foo", body=response_data, method="DELETE", status=200, ) response = client.delete("/v2/deployments/foo", headers=self.auth_header) self.assertFalse(_apply_response_filters.called) self.assertEqual(json.loads(response.data), fixture)
def test_split_groups_write_PUT_on_group(self): """ Atualmente, o único body que chega em um PUT em /v2/groups é: {"scaleBy": <N>} onde `<N>` é o fator que será multiplicado pelo atual número de TASK_RUNNING de cada app. O problema é que o Request.split() retorna uma lista de apps, e o Request.join() potencialmente vai reconstruir um body com essa lista de apps. O problema é que isso gera um request body *diferente* do orignal, já que agora temos um body contendo um APP_GROUP com todas suas apps (e sub apps). E se fazemos apenas isso, a informação do "scaleBy" se perdeu, pois se mandamos um request com o TASK_GROUP inteiro para o upstream, nada vai mudar já que as apps não foram modificadas. Uma ideia é o Core do hollowman decobrir essa ação de scaleBy e chamar o métoro "scale_by" dos filtros, já com a request_app tendo seu atributo "instances" multiplicado pelo fator. Opcionalmente o fator poderia ser passado como parametro para o filtro. Isso nos daria a possibilidade de "corrigir" um problema atual do scaleby que é: Quando damos scale_by = 2 em um app que está suspended, ela continua suspended já que 2 * 0 = 0. A ideia é que suspended apps também sejam ligadas considerando esse fator. O que faríamos no filtro seria, para toda app que instances = 0, consideramos instances = 1 e multiplicamos pelo fator. Enfim, apenas uma ideia. Temos que ver o que fazemos com esse teste aqui. """ with application.test_request_context('/v2/groups/group-b', method='PUT') as ctx: ctx.request.user = self.user request_parser = Request(ctx.request) with RequestsMock() as rsps: rsps.add(method='GET', url=conf.MARATHON_ADDRESSES[0] + '/v2/groups//dev/group-b', body=json.dumps(group_b_fixture), status=200) apps = list(request_parser.split()) self.assertEqual(2, len(apps)) expected_apps = [ (MarathonApp(), MarathonApp.from_json({"id": "/dev/group-b/appb0"})), (MarathonApp(), MarathonApp.from_json( {"id": "/dev/group-b/group-b0/app0"})), ] self.assertEqual(expected_apps, apps)
def test_tasks_returnn_404_if_task_does_not_exist(self): """ Se o mesos retornar que a task não existe, já retornamos 404 direto. """ task_id = "task_do_not_exist.2580925d-0129-11e8-9a03-6e85ded2ca1e" with application.test_client() as client: with RequestsMock() as rsps: rsps.add( method="GET", url= f"{DEFAULT_MESOS_ADDRESS}/tasks?task_id={self.user.current_account.namespace}_{task_id}", body=json.dumps({"tasks": []}), status=200, match_querystring=True) resp = client.get(f"/tasks/{task_id}/files", headers=self.auth_header) resp_data = json.loads(resp.data) self.assertEquals(404, resp.status_code)
def test_join_group_read_non_root_empty_group( self, non_root_group_empty_fixture): with application.test_request_context("/v2/groups/group-c", method="GET") as ctx: ctx.request.user = self.user request = Request(ctx.request) with RequestsMock() as rsps: rsps.add( method="GET", url=conf.MARATHON_ADDRESSES[0] + "/v2/groups//dev/group-c", body=json.dumps(non_root_group_empty_fixture), status=200, ) apps = list(request.split()) joined_request = request.join(apps) self.assertEqual("/v2/groups/dev/group-c", joined_request.path) self.assertEqual(b"", joined_request.data)
def test_split_group_nonroot_empty_group(self, group_dev_namespace_fixture): with application.test_request_context('/v2/groups/group-c', method='GET') as ctx: response = FlaskResponse( response=json.dumps(group_dev_namespace_fixture['groups'][2]), status=HTTPStatus.OK, headers={} ) with RequestsMock() as rsps: rsps.add(method='GET', url=conf.MARATHON_ADDRESSES[0] + '/v2/groups//dev/group-c', body=json.dumps(deepcopy(group_dev_namespace_fixture['groups'][2])), status=200) ctx.request.user = self.user response = Response(ctx.request, response) groups_tuple = list(response.split()) self.assertEqual(1, len(groups_tuple)) expected_groups = [AsgardAppGroup(g) for g in AsgardAppGroup(MarathonGroup.from_json(group_dev_namespace_fixture['groups'][2])).iterate_groups()] # Compara com os groups originais self.assertEqual(expected_groups, [g[1] for g in groups_tuple])
def test_queue_removes_queued_appps_from_other_namespaces(self, queue_get_fixture): """ Removemos todas as apps que não sejam do namespace atual. Esse teste tambéem confirma que o namespace é removido dos elementos que voltam no response. """ auth_header = {"Authorization": "Token 69ed620926be4067a36402c3f7e9ddf0"} with application.test_client() as client: with RequestsMock() as rsps: rsps.add(method='GET', url=conf.MARATHON_ADDRESSES[0] + '/v2/queue', status=200, json=queue_get_fixture) response = client.get("/v2/queue", headers=auth_header) self.assertEqual(200, response.status_code) response_data = json.loads(response.data) self.assertEqual(1, len(response_data['queue'])) self.assertEqual("/waiting", response_data['queue'][0]['app']['id'])
def test_make_request_update_new_marathon_leader(self): marathon_addresses = [ "http://172.29.0.1:8080", "http://172.30.0.1:8080", ] with RequestsMock() as rsps, patch.multiple( hollowman.conf, MARATHON_ADDRESSES=marathon_addresses), patch.multiple( hollowman.conf, MARATHON_LEADER=marathon_addresses[0]): rsps.add( "GET", url=marathon_addresses[0] + "/v2/apps", status=200, body="OK", headers={"X-Marathon-Leader": marathon_addresses[1]}, ) response = _make_request("/v2/apps", "get") self.assertEqual(hollowman.conf.MARATHON_LEADER, marathon_addresses[1])
def test_get_metrics_master_with_prefix(self, master_metrics_fixture): with self.application.test_client() as client: with RequestsMock() as rsps: rsps.add(method='GET', url="http://10.0.0.1:5050/metrics/snapshot", body=json.dumps(master_metrics_fixture), status=200) response = client.get("/metrics/master/10.0.0.1?prefix=sys") self.assertEqual(200, response.status_code) metrics_data = json.loads(response.data) self.assertEqual(6, len(metrics_data.keys())) self.assertEqual(8, metrics_data["system/cpus_total"]) self.assertEqual(0.1, metrics_data["system/load_15min"]) self.assertEqual(0.21, metrics_data["system/load_1min"]) self.assertEqual(0.14, metrics_data["system/load_5min"]) self.assertEqual(269631488, metrics_data["system/mem_free_bytes"]) self.assertEqual(20935741440, metrics_data["system/mem_total_bytes"])
def test_get_original_group_not_found(self): """ Tenta buscar um grupo que não existe. """ with application.test_request_context('/v2/groups//not-found', method='GET') as ctx: with RequestsMock() as rsps: rsps.add(method='GET', url=conf.MARATHON_ADDRESSES[0] + '/v2/groups//dev/not-found', status=404) ctx.request.user = self.user request = Request(ctx.request) group = request._get_original_group(self.user, "/not-found") self.assertEqual( AsgardAppGroup( MarathonGroup.from_json({"id": "/dev/not-found"})), group)
def test_a_request_for_write_operation_with_appid_in_url_path_returns_a_tuple_of_marathonapp( self, fixture): scale_up = {'instances': 10} with application.test_request_context( '/v2/apps/foo', method='PUT', data=json.dumps(scale_up)) as ctx: ctx.request.user = self.user request_parser = Request(ctx.request) with RequestsMock() as rsps: rsps.add(method='GET', url=conf.MARATHON_ADDRESSES[0] + '/v2/apps//dev/foo', body=json.dumps({'app': fixture}), status=200) apps = list(request_parser.split()) original_app = MarathonApp.from_json(fixture) expected_apps = (request_parser.merge_marathon_apps( MarathonApp.from_json(scale_up), original_app), original_app) self.assertEqual(apps, [expected_apps])
def test_tasks__browse_files_task_is_completed(self, task_browse_file_fixture, one_task_json_fixture, one_slave_json_fixture, slave_state_fixture): """ Se tentamos pegar os arquivos de uma task que não está mais rodando, temos que procurá-la no array `completed_tasks`. """ slave_id = "31fcae61-51a9-4ad1-8054-538503eb53a9-S5" task_id = "infra_mongodb_mongodb1.2580925d-0129-11e8-9a03-6e85ded2ca1e" sandbox_directory = "/tmp/mesos/slaves/31fcae61-51a9-4ad1-8054-538503eb53a9-S5/frameworks/27b52920-3899-4b90-a1d6-bf83a87f3612-0000/executors/dev_infra_mongodb_mongodb1.2580925d-0129-11e8-9a03-6e85ded2ca1e/runs/1ec0d0bf-0f11-49ba-8a03-2cf954ad1cfe" with application.test_client() as client: with RequestsMock() as rsps: rsps.add( method="GET", url= f"{DEFAULT_MESOS_ADDRESS}/tasks?task_id={self.user.current_account.namespace}_{task_id}", body=json.dumps(one_task_json_fixture), status=200, match_querystring=True) rsps.add( method="GET", url=f"{DEFAULT_MESOS_ADDRESS}/slaves?slave_id={slave_id}", body=json.dumps(one_slave_json_fixture), status=200, match_querystring=True) rsps.add(method="GET", url="http://127.0.0.1:5051/state", body=json.dumps(slave_state_fixture), status=200) rsps.add( method="GET", url= f"http://127.0.0.1:5051/files/browse?path={sandbox_directory}", body=json.dumps(task_browse_file_fixture), status=200, match_querystring=True) resp = client.get(f"/tasks/{task_id}/files", headers=self.auth_header) resp_data = json.loads(resp.data) self.assertEquals(200, resp.status_code) self.assertEqual(4, len(resp_data))
def test_a_request_for_restart_operation_with_appid_in_url_path_returns_a_tuple_of_marathonapp( self, fixture): with application.test_request_context('/v2/apps/xablau/restart', method='PUT', data=b'{"force": true}') as ctx: ctx.request.user = self.user request_parser = Request(ctx.request) with RequestsMock() as rsps: rsps.add(method='GET', url=conf.MARATHON_ADDRESSES[0] + '/v2/apps//dev/xablau', body=json.dumps({'app': fixture}), status=200) apps = list(request_parser.split()) original_app = MarathonApp.from_json(fixture) expected_app = (request_parser.merge_marathon_apps( MarathonApp(), original_app), original_app) self.assertEqual(apps, [expected_app])
def test_tasks_browse_files(self, task_browse_file_fixture, one_task_json_fixture, one_slave_json_fixture, slave_state_fixture): task_id = "infra_mysql.b331f6c9-fb9e-11e7-ab4b-faf0633ea91f" sandbox_directory = "/tmp/mesos/slaves/2084863b-12d1-4319-b515-992eab91a53d-S1/frameworks/27b52920-3899-4b90-a1d6-bf83a87f3612-0000/executors/dev_infra_mysql.b331f6c9-fb9e-11e7-ab4b-faf0633ea91f/runs/e14d7537-c1d0-4846-a076-25d623d6a70f" with application.test_client() as client: with RequestsMock() as rsps: rsps.add( method="GET", url= f"{DEFAULT_MESOS_ADDRESS}/tasks?task_id={self.user.current_account.namespace}_{task_id}", body=json.dumps(one_task_json_fixture), status=200, match_querystring=True) rsps.add( method="GET", url= f"{DEFAULT_MESOS_ADDRESS}/slaves?slave_id=2084863b-12d1-4319-b515-992eab91a53d-S1", body=json.dumps(one_slave_json_fixture), status=200, match_querystring=True) rsps.add(method="GET", url="http://127.0.0.1:5051/state", body=json.dumps(slave_state_fixture), status=200) rsps.add( method="GET", url= f"http://127.0.0.1:5051/files/browse?path={sandbox_directory}", body=json.dumps(task_browse_file_fixture), status=200, match_querystring=True) resp = client.get(f"/tasks/{task_id}/files", headers=self.auth_header) resp_data = json.loads(resp.data) self.assertEquals(200, resp.status_code) self.assertEqual(4, len(resp_data)) self.assertEqual( sorted([ "/stdout", "/stdout.logrotate.conf", "/stderr", "/stderr.logrotate.conf" ]), sorted([u['path'] for u in resp_data]))
def test_tasks_read_file_offset(self, task_file_read_fixture, one_task_json_fixture, one_slave_json_fixture, slave_state_fixture): slave_id = "31fcae61-51a9-4ad1-8054-538503eb53a9-S5" task_id = "infra_mongodb_mongodb1.2580925d-0129-11e8-9a03-6e85ded2ca1e" sandbox_directory = "/tmp/mesos/slaves/31fcae61-51a9-4ad1-8054-538503eb53a9-S5/frameworks/27b52920-3899-4b90-a1d6-bf83a87f3612-0000/executors/dev_infra_mongodb_mongodb1.2580925d-0129-11e8-9a03-6e85ded2ca1e/runs/1ec0d0bf-0f11-49ba-8a03-2cf954ad1cfe" with application.test_client() as client: with RequestsMock() as rsps: rsps.add( method="GET", url= f"{DEFAULT_MESOS_ADDRESS}/tasks?task_id={self.user.current_account.namespace}_{task_id}", body=json.dumps(one_task_json_fixture), status=200, match_querystring=True) rsps.add( method="GET", url=f"{DEFAULT_MESOS_ADDRESS}/slaves?slave_id={slave_id}", body=json.dumps(one_slave_json_fixture), status=200, match_querystring=True) rsps.add(method="GET", url="http://127.0.0.1:5051/state", body=json.dumps(slave_state_fixture), status=200) rsps.add( method="GET", url= f"http://127.0.0.1:5051/files/read?path={sandbox_directory}/stderr&offset=0&length=42", body=json.dumps(task_file_read_fixture), status=200, match_querystring=True) resp = client.get( f"/tasks/{task_id}/files/read?path=/stderr&offset=0&length=42", headers=self.auth_header) resp_data = json.loads(resp.data) self.assertEquals(200, resp.status_code) self.assertEquals(0, resp_data['offset']) self.assertEqual( "*** Starting uWSGI 2.0.14 (64bit) on [Wed Jan 31 19:58:13 2018] ***", resp_data['data'])
def test_iterpage(self): first_feed = next(self._container.itervalues()) collection = first_feed.OpenCollection() page_size = 200 collection.set_page(top=page_size, skip=0) with RequestsMock() as rsp: re_limit = re.compile( '.*q=SELECT\+%2A\+FROM\+%22measurement1.*LIMIT\+200&') re_limit_offset = re.compile( '.*q=SELECT\+%2A\+FROM\+%22measurement1.*LIMIT\+200\+OFFSET\+200&' ) rsp.add(rsp.GET, re.compile('.*SELECT\+COUNT.*'), json=json_count(collection.name), match_querystring=True) rsp.add(rsp.GET, re.compile('.*SELECT\+COUNT.*'), json=json_count(collection.name), match_querystring=True) rsp.add(rsp.GET, re_limit, json=json_points_list('measurement1', page_size=page_size), match_querystring=True) rsp.add(rsp.GET, re.compile('.*SELECT\+COUNT.*'), json=json_count(collection.name), match_querystring=True) rsp.add(rsp.GET, re.compile('.*SELECT\+COUNT.*'), json=json_count(collection.name), match_querystring=True) rsp.add(rsp.GET, re_limit_offset, json=json_points_list('measurement1', page_size=page_size), match_querystring=True) first_page = list(collection.iterpage()) collection.set_page(top=page_size, skip=page_size) second_page = list(collection.iterpage()) collection.close()
def patch_requests(): requests_mock = RequestsMock() requests_mock.start() yield requests_mock requests_mock.stop()