Esempio n. 1
0
    def test_a_request_with_n_apps_returns_n_marathonapps(self, fixture):
        with application.test_request_context("/v2/apps/",
                                              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/",
                    body=json.dumps(fixture),
                    status=200,
                )
                apps = list(request_parser.split())

                self.assertEqual(
                    [request_app for request_app, _ in apps],
                    [
                        request_parser.merge_marathon_apps(
                            request_app, original_app)
                        for request_app, original_app in apps
                    ],
                )

                self.assertEqual(
                    [app.id for app, _ in apps],
                    [app["id"] for app in fixture["apps"]],
                )
Esempio n. 2
0
    def test_call_filter_method_passing_each_group(
            self, group_dev_namespace_fixture):
        """
        Todos os grupos de um response devem ser passados para os filtros,
        um de cada vez
        """

        with application.test_request_context("/v2/groups/group-b",
                                              method="GET") as ctx:
            ctx.request.user = self.user
            ok_response = FlaskResponse(
                response=json.dumps(group_dev_namespace_fixture["groups"][1]),
                status=HTTPStatus.OK,
                headers={},
            )

            response_wrapper = Response(ctx.request, ok_response)
            final_response = dispatch(
                user=self.user,
                request=response_wrapper,
                filters_pipeline={OperationType.READ: [DummyFilter()]},
                filter_method_name_callback=lambda *args: "response_group",
            )
            final_response_data = json.loads(final_response.data)
            returned_group = MarathonGroup.from_json(final_response_data)

            self.assertEqual("/dummy/dev/group-b", returned_group.id)
            self.assertEqual("/dummy/dev/group-b/group-b0",
                             returned_group.groups[0].id)
Esempio n. 3
0
 def test_add_query_string_from_original_request(self, mock_get):
     with application.test_request_context("/v2/apps?a=b&c=d",
                                           method="GET"):
         replay_request(flask.request)
         self.assertTrue(mock_get.called)
         called_headers = mock_get.call_args[1]['params']
         self.assertEqual(dict(called_headers), {"a": "b", "c": "d"})
Esempio n. 4
0
    def test_response_has_list_of_apps_modified_by_filters(self):
        """
        Certificamos que uma lista de apps pode ser modificada por algum
        filtro de response.
        """
        with application.test_request_context("/v2/apps/",
                                              method="GET") as ctx:
            single_full_app_one = deepcopy(self.single_full_app_fixture)
            single_full_app_one["id"] = "/dev/foo"

            single_full_app_two = deepcopy(self.single_full_app_fixture)
            single_full_app_two["id"] = "/dev/other-app"

            original_response = FlaskResponse(
                response=json.dumps(
                    {"apps": [single_full_app_one, single_full_app_two]}),
                status=200,
                headers={},
            )

            ctx.request.user = self.user
            response_wrapper = Response(ctx.request, original_response)
            final_response = dispatch(
                user=self.user,
                request=response_wrapper,
                filters_pipeline=FILTERS_PIPELINE[FilterType.RESPONSE],
                filter_method_name_callback=lambda *args: "response",
            )
            response_data = json.loads(final_response.data)
            self.assertEqual(200, final_response.status_code)
            self.assertEqual(2, len(response_data["apps"]))
            self.assertEqual("/foo", response_data["apps"][0]["id"])
            self.assertEqual("/other-app", response_data["apps"][1]["id"])
Esempio n. 5
0
    def test_multiapp_response_returns_multiple_marathonapp_instances(
            self, fixture):
        modified_app = fixture.copy()
        modified_app["id"] = "/xablau"

        apps = [fixture, modified_app]
        with application.test_request_context("/v2/apps/",
                                              method="GET",
                                              data=b"") as ctx:
            response = FlaskResponse(
                response=json.dumps({"apps": apps}),
                status=HTTPStatus.OK,
                headers={},
            )
            response = Response(ctx.request, response)

        with patch.object(response, "marathon_client") as client:
            original_apps = [MarathonApp.from_json(app) for app in apps]
            client.get_app.side_effect = original_apps
            apps = list(response.split())

        self.assertEqual(
            apps,
            [
                (AsgardApp.from_json(fixture), original_apps[0]),
                (AsgardApp.from_json(modified_app), original_apps[1]),
            ],
        )
Esempio n. 6
0
    def test_response_has_app_modified_by_filter(self):
        """
        Certificamos que um request em uma app, roda o pipeline
        e essa app pode ser modificada por algum filtro
        """
        with application.test_request_context("/v2/apps/dev/foo",
                                              method="GET") as ctx:
            single_full_app_one = deepcopy(self.single_full_app_fixture)
            single_full_app_one["id"] = "/dev/foo"

            _url = conf.MARATHON_ADDRESSES[0] + "/v2/apps//dev/foo"
            with RequestsMock() as rsps:
                rsps.add(
                    method="GET",
                    url=_url,
                    json={"app": single_full_app_one},
                    status=200,
                )
                original_response = FlaskResponse(
                    response=json.dumps({"app": single_full_app_one}),
                    status=200,
                    headers={},
                )

                ctx.request.user = self.user
                response_wrapper = Response(ctx.request, original_response)
                final_response = dispatch(
                    user=self.user,
                    request=response_wrapper,
                    filters_pipeline=FILTERS_PIPELINE[FilterType.RESPONSE],
                    filter_method_name_callback=lambda *args: "response",
                )
                self.assertEqual(200, final_response.status_code)
                self.assertEqual("/foo",
                                 json.loads(final_response.data)["app"]["id"])
Esempio n. 7
0
    def test_response_task_remove_from_response_tasks_outside_same_prefix_namespace(
            self, tasks_multinamespace_fixure):
        """
        Confirmamos que uma task do namespace "developers" *deve ser removida* quando o usuário faz parte
        do namespace "dev", mesmo esses dois namespaces começando pelo mesmo prefixo
        """
        with application.test_request_context("/v2/tasks/",
                                              method="GET") as ctx:

            original_response = FlaskResponse(
                response=json.dumps(tasks_multinamespace_fixure), status=200)

            ctx.request.user = self.user
            response_wrapper = Response(ctx.request, original_response)
            final_response = dispatch(
                user=self.user,
                request=response_wrapper,
                filters_pipeline=FILTERS_PIPELINE[FilterType.RESPONSE],
                filter_method_name_callback=lambda *args: "response_task",
            )
            response_data = json.loads(final_response.data)
            self.assertEqual(200, final_response.status_code)
            self.assertEqual(
                [
                    "waiting.01339ffa-ce9c-11e7-8144-2a27410e5638",
                    "waiting.0432fd4b-ce9c-11e7-8144-2a27410e5638",
                ],
                [task["id"] for task in response_data["tasks"]],
            )
            self.assertEqual(2, len(response_data["tasks"]))
Esempio n. 8
0
    def test_update_app_change_all_constraints(self):
        """
        Devemos respeitar as constraints quem estão da request,
        elas devem substituir as constrains da app original
        """
        class DummyFilter:
            def write(self, user, request_app, original_app):
                return request_app

        pipeline = {
                OperationType.WRITE: [DummyFilter(), ]
        }

        request_data = {"constraints": [["hostname", "LIKE", "myhost"]]}
        request_app = AsgardApp.from_json(request_data)
        original_app = AsgardApp.from_json(deepcopy(self.single_full_app_fixture))

        with application.test_request_context("/v2/apps/foo",
                                              method="PUT",
                                              data=json.dumps(request_data),
                                              headers={"Content-type": "application/json"}) as ctx:

            ctx.request.user = self.user
            request = Request(ctx.request)
            filtered_request = dispatch(self.user, request, filters_pipeline=pipeline)
            filtered_app = AsgardApp.from_json(filtered_request.get_json())
            self.assertEqual(1, len(filtered_app.constraints))
            self.assertEqual(["hostname", "LIKE", "myhost"], filtered_app.constraints[0].json_repr())
            self._check_other_fields("constraints", filtered_app)
Esempio n. 9
0
    def test_preserve_constraints_added_by_filter(self):
        """
        Certifica que quando um request remove todas as constraints e algum filtro adiciona novas
        constraints, essas constraints adicionadas pelo filtro são preservadas
        """
        class AddNewConstraintFilter:
            def write(self, user, request_app, original_app):
                request_app.constraints.append(MarathonConstraint.from_json("key:LIKE:value".split(":")))
                return request_app

        pipeline = {
                OperationType.WRITE: [AddNewConstraintFilter(), ]
        }

        request_data = {"constraints": []}
        request_app = AsgardApp.from_json(request_data)
        original_app = AsgardApp.from_json(deepcopy(self.single_full_app_fixture))

        with application.test_request_context("/v2/apps/foo",
                                              method="PUT",
                                              headers={"Content-type": "application/json"},
                                              data=json.dumps(request_data)) as ctx:

            ctx.request.user = self.user
            request = Request(ctx.request)
            filtered_request = dispatch(self.user, request, filters_pipeline=pipeline)
            filtered_request_app = AsgardApp.from_json(filtered_request.get_json())
            self.assertEqual(1, len(filtered_request_app.constraints))
            self._check_other_fields("constraints", filtered_request_app)
Esempio n. 10
0
    def test_update_app_remove_all_constraints(self):
        """
        Certifica que um request que remove todas as constraints,
        remove essas constraints na app original
        """
        class DummyFilter:
            def write(self, user, request_app, original_app):
                return request_app

        pipeline = {
                OperationType.WRITE: [DummyFilter(), ]
        }

        request_data = {"constraints": []}
        request_app = AsgardApp.from_json(request_data)
        original_app = AsgardApp.from_json(deepcopy(self.single_full_app_fixture))

        with application.test_request_context("/v2/apps/foo",
                                              method="PUT",
                                              data=json.dumps(request_data),
                                              headers={"Content-type": "application/json"}) as ctx:
            ctx.request.user = self.user
            request = Request(ctx.request)
            filtered_request = dispatch(self.user, request, filters_pipeline=pipeline)
            filtered_app = AsgardApp.from_json(filtered_request.get_json())
            self.assertEqual(0, len(filtered_app.constraints))
            self._check_other_fields("constraints", filtered_app)
Esempio n. 11
0
    def test_dispatch_should_pass_an_instance_if_SieveMarathonApp_to_filters(self):
        """
        Certifica que quando um request remove todas as constraints e algum filtro adiciona novas
        constraints, essas constraints adicionadas pelo filtro são preservadas
        """
        class AddNewConstraintFilter:
            def write(self, user, request_app, original_app):
                assert isinstance(request_app, AsgardApp)
                return request_app

        pipeline = {
                OperationType.WRITE: [AddNewConstraintFilter(), ]
        }

        request_data = {"constraints": []}
        request_app = AsgardApp.from_json(request_data)
        original_app = AsgardApp.from_json(deepcopy(self.single_full_app_fixture))

        with application.test_request_context("/v2/apps/foo",
                                              method="PUT",
                                              headers={"Content-type": "application/json"},
                                              data=json.dumps(request_data)) as ctx:

            ctx.request.user = self.user
            request = Request(ctx.request)
            filtered_request = dispatch(self.user, request, filters_pipeline=pipeline)
    def test_response_apps_remove_outside_current_namespace(self):
        with application.test_request_context("/v2/apps/", method="GET") as ctx:
            single_full_app_one = deepcopy(self.single_full_app_fixture)
            single_full_app_one['id'] = '/dev/foo'

            single_full_app_two = deepcopy(self.single_full_app_fixture)
            single_full_app_two['id'] = '/dev/other-app'

            single_full_app_three = deepcopy(self.single_full_app_fixture)
            single_full_app_three['id'] = '/othernamespace/other-app'

            with RequestsMock() as rsps:
                rsps.add(method='GET', url=conf.MARATHON_ADDRESSES[0] + '/v2/apps//dev/foo',
                         body=json.dumps({'app': single_full_app_one}), status=200)
                rsps.add(method='GET', url=conf.MARATHON_ADDRESSES[0] + '/v2/apps//dev/other-app',
                         body=json.dumps({'app': single_full_app_two}), status=200)
                rsps.add(method='GET', url=conf.MARATHON_ADDRESSES[0] + '/v2/apps//othernamespace/other-app',
                         body=json.dumps({'app': single_full_app_three}), status=200)

                original_response = FlaskResponse(response=json.dumps({'apps': [single_full_app_one, single_full_app_two, single_full_app_three]}),
                                                  status=200, headers={})

                ctx.request.user = self.user
                response_wrapper = Response(ctx.request, original_response)
                final_response = dispatch(user=self.user,
                                          request=response_wrapper,
                                          filters_pipeline=FILTERS_PIPELINE[FilterType.RESPONSE],
                                          filter_method_name_callback=lambda *args: "response"
                                 )
                response_data = json.loads(final_response.data)
                self.assertEqual(200, final_response.status_code)
                self.assertEqual(2, len(response_data['apps']))
                self.assertEqual("/foo", response_data['apps'][0]['id'])
                self.assertEqual("/other-app", response_data['apps'][1]['id'])
    def test_do_not_call_filter_if_it_doesnt_implement_response_method(self):
        class DummyRequestFilter:
            def write(self, user, request_app):
                return request_app

        with application.test_request_context("/v2/apps/foo", method="GET") as ctx:
            single_full_app_one = deepcopy(self.single_full_app_fixture)
            single_full_app_one['id'] = "/dev/foo"

            with RequestsMock() as rsps:
                rsps.add(method='GET', url=conf.MARATHON_ADDRESSES[0] + '/v2/apps//foo',
                         json={"app": single_full_app_one}, status=200)

                original_response = FlaskResponse(response=json.dumps({"app": single_full_app_one}),
                                                  status=200, headers={})

                ctx.request.user = self.user
                response_wrapper = Response(ctx.request, original_response)
                final_response = dispatch(user=self.user,
                                          request=response_wrapper,
                                          filters_pipeline={OperationType.READ: [DummyRequestFilter()]},
                                          filter_method_name_callback=lambda *args: "response"
                                 )
                response_data = json.loads(final_response.data)
                self.assertEqual(200, final_response.status_code)
                self.assertEqual("/dev/foo", response_data['app']['id'])
Esempio n. 14
0
    def test_join_one_app_should_produce_one_app_not_a_list(self, fixture):
        """
        Um POST em /v2/apps, apesar de receber no body apens uma app ({...}),
        após o request.join(), restá produzindo um request com uma lista de apps:
            [{...}], e a API do marathon não aceita lista no POST apenas no PUT.

            O problema parece ser no request.join():89, onde fazemos if self.is_list_app_request().
            Precisamos olhar se é PUT ou POST e gerar list() ou dict() apropriadamente.
        """
        with application.test_request_context("/v2/apps/",
                                              method="POST",
                                              data=json.dumps(fixture)) as ctx:
            ctx.request.user = self.user
            request_parser = Request(ctx.request)
            mock_app = get_fixture("single_full_app.json")
            mock_apps = [(MarathonApp.from_json(mock_app), Mock())]

            joined_request = request_parser.join(mock_apps)
            self.assertIsInstance(joined_request, HollowmanRequest)
            joined_request_data = json.loads(joined_request.data)
            self.assertFalse(
                isinstance(joined_request_data, list),
                "Body não deveria ser uma lista",
            )
            self.assertEqual("/foo", joined_request_data["id"])
Esempio n. 15
0
    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)
Esempio n. 16
0
    def test_preserve_upgrade_strategy_added_by_filter(self):
        class AddNewUpgradeStrategyFilter:
            def write(self, user, request_app, original_app):
                us_data = {
                    "maximumOverCapacity": 1,
                    "minimumHealthCapacity": 0.75
                }
                request_app.upgrade_strategy = MarathonUpgradeStrategy.from_json(us_data)
                return request_app

        pipeline = {
                OperationType.WRITE: [AddNewUpgradeStrategyFilter(), ]
        }
        # Simulando uma app que veio sem o campo "upgradeStrategy"
        request_data = {}

        request_app = AsgardApp.from_json(request_data)
        original_app = AsgardApp.from_json(deepcopy(self.single_full_app_fixture))

        with application.test_request_context("/v2/apps/foo",
                                              method="PUT",
                                              headers={"Content-type": "application/json"},
                                              data=json.dumps(request_data)) as ctx:

            ctx.request.user = self.user
            request = Request(ctx.request)
            filtered_request = dispatch(self.user, request, filters_pipeline=pipeline)
            filtered_app = AsgardApp.from_json(filtered_request.get_json())
            self.assertEqual(1, filtered_app.upgrade_strategy.maximum_over_capacity)
            self.assertEqual(0.75, filtered_app.upgrade_strategy.minimum_health_capacity)
            self._check_other_fields("upgradeStrategy", filtered_app)
Esempio n. 17
0
    def test_response_task_filter_modifies_task(self, tasks_get_fixture):
        class ModifyTaskFilter:
            def response_task(self, user, response_task, original_task):
                response_task.id = f"{response_task.id}_bla"
                return response_task

        with application.test_request_context("/v2/tasks/",
                                              method="GET") as ctx:

            original_response = FlaskResponse(
                response=json.dumps(tasks_get_fixture), status=200)

            ctx.request.user = self.user
            response_wrapper = Response(ctx.request, original_response)
            final_response = dispatch(
                user=self.user,
                request=response_wrapper,
                filters_pipeline={OperationType.READ: [ModifyTaskFilter()]},
                filter_method_name_callback=lambda *args: "response_task",
            )
            response_data = json.loads(final_response.data)
            self.assertEqual(200, final_response.status_code)
            self.assertEqual(3, len(response_data["tasks"]))
            self.assertEqual(
                [
                    "dev_waiting.01339ffa-ce9c-11e7-8144-2a27410e5638_bla",
                    "dev_waiting.0432fd4b-ce9c-11e7-8144-2a27410e5638_bla",
                    "dev_waiting.75b2ed9c-ce9c-11e7-8144-2a27410e5638_bla",
                ],
                [task["id"] for task in response_data["tasks"]],
            )
Esempio n. 18
0
    def test_preserve_envs_added_by_filter(self):
        class AddNewEnvFilter:
            def write(self, user, request_app, original_app):
                request_app.env["env1"] = "env-value1"
                return request_app

        pipeline = {
                OperationType.WRITE: [AddNewEnvFilter(), ]
        }
        request_data = {"env": []}

        request_app = AsgardApp.from_json(request_data)
        original_app = AsgardApp.from_json(deepcopy(self.single_full_app_fixture))

        with application.test_request_context("/v2/apps/foo",
                                              method="PUT",
                                              headers={"Content-type": "application/json"},
                                              data=json.dumps(request_data)) as ctx:

            ctx.request.user = self.user
            request = Request(ctx.request)
            filtered_request = dispatch(self.user, request, filters_pipeline=pipeline)
            filtered_app = AsgardApp.from_json(filtered_request.get_json())
            self.assertEqual(1, len(filtered_app.env.keys()))
            self.assertEqual({"env1": "env-value1"}, filtered_app.env)
            self._check_other_fields("env", filtered_app)
Esempio n. 19
0
    def test_response_task_remove_from_response_tasks_outside_namespace(
            self, tasks_multinamespace_fixure):
        class ModifyTaskFilter:
            def response_task(self, user, response_task):
                response_task.id = response_task.id.replace(
                    f"{user.current_account.namespace}_", "")
                return response_task

        with application.test_request_context("/v2/tasks/",
                                              method="GET") as ctx:

            original_response = FlaskResponse(
                response=json.dumps(tasks_multinamespace_fixure), status=200)

            ctx.request.user = self.user
            response_wrapper = Response(ctx.request, original_response)
            final_response = dispatch(
                user=self.user,
                request=response_wrapper,
                filters_pipeline=FILTERS_PIPELINE[FilterType.RESPONSE],
                filter_method_name_callback=lambda *args: "response_task",
            )
            response_data = json.loads(final_response.data)
            self.assertEqual(200, final_response.status_code)
            self.assertEqual(2, len(response_data["tasks"]))
            self.assertEqual(
                [
                    "waiting.01339ffa-ce9c-11e7-8144-2a27410e5638",
                    "waiting.0432fd4b-ce9c-11e7-8144-2a27410e5638",
                ],
                [task["id"] for task in response_data["tasks"]],
            )
Esempio n. 20
0
    def test_do_not_call_task_method_if_filter_does_not_implement(self):
        """
        Caso um filtro não implemente write_task, apenas não chamamos esse filtro
        durante o pipeline
        """
        class DummyFilter:
            def write(self, user, request_app, original_app):
                raise Exception()

        pipeline = {
                OperationType.WRITE: [DummyFilter(), ]
        }

        request_data = {"ids": ["task_0"]}
        request_app = MarathonTask.from_json({'id': request_data['ids'][0]})
        original_app = request_app # Por enquanto não temos como passar a original task

        with application.test_request_context("/v2/tasks/delete",
                                              method="POST",
                                              data=json.dumps(request_data),
                                              headers={"Content-type": "application/json"}) as ctx:
            ctx.request.user = self.user
            request = Request(ctx.request)
            with patch.object(request, "split", return_value=[(request_app, original_app)]):
                filtered_request = dispatch(self.user, request, filters_pipeline=pipeline)
                filtered_app = MarathonTask.from_json({"id": filtered_request.get_json()['ids'][0]})
                self.assertEqual("task_0", filtered_app.id)
Esempio n. 21
0
    def test_response_task_do_not_dispatch_pipeline_if_response_is_deployment(
            self, tasks_post_fixture):
        """
        Se o request for de escrita em /v2/tasks e foi passado `?scale=true`, não devemos
        rodar o pipeline, já que nesse response tem apenas um DeploymentId
        """
        with application.test_request_context("/v2/tasks/delete?scale=true",
                                              method="POST") as ctx:

            original_response = FlaskResponse(
                response=json.dumps(tasks_post_fixture), status=200)

            response_wrapper = Response(ctx.request, original_response)
            final_response = dispatch(
                user=self.user,
                request=response_wrapper,
                filters_pipeline=[],
                filter_method_name_callback=lambda *args: "response_task",
            )
            response_data = json.loads(final_response.data)
            self.assertEqual(200, final_response.status_code)
            self.assertEqual(
                "5ed4c0c5-9ff8-4a6f-a0cd-f57f59a34b43",
                response_data["deploymentId"],
            )
Esempio n. 22
0
    def test_split_groups_read_on_root_group(self, group_dev_namespace_fixture):
        with application.test_request_context('/v2/groups/', method='GET') as ctx:
            response = FlaskResponse(
                response=json.dumps(group_dev_namespace_fixture),
                status=HTTPStatus.OK,
                headers={}
            )
            with RequestsMock() as rsps:
                rsps.add(method='GET', url=conf.MARATHON_ADDRESSES[0] + '/v2/groups//dev/',
                         body=json.dumps(deepcopy(group_dev_namespace_fixture)), status=200)
                rsps.add(method='GET', url=conf.MARATHON_ADDRESSES[0] + '/v2/groups//dev/a',
                         body=json.dumps(deepcopy(group_dev_namespace_fixture['groups'][0])), status=200)
                rsps.add(method='GET', url=conf.MARATHON_ADDRESSES[0] + '/v2/groups//dev/group-b',
                         body=json.dumps(deepcopy(group_dev_namespace_fixture['groups'][1])), status=200)
                rsps.add(method='GET', url=conf.MARATHON_ADDRESSES[0] + '/v2/groups//dev/group-b/group-b0',
                         body=json.dumps(deepcopy(group_dev_namespace_fixture['groups'][1]['groups'][0])), status=200)
                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(5, len(groups_tuple))
                expected_groups = [AsgardAppGroup(g) for g in AsgardAppGroup(MarathonGroup.from_json(group_dev_namespace_fixture)).iterate_groups()]
                # Compara com os groups originais
                self.assertEqual(expected_groups, [g[1] for g in groups_tuple])
Esempio n. 23
0
    def test_it_recreates_a_get_response_for_multiple_apps(self, fixture):
        modified_app = deepcopy(fixture)
        modified_app["id"] = "/xablau"

        fixtures = [fixture, modified_app]
        expected_response = deepcopy(fixtures)
        with application.test_request_context("/v2/apps/",
                                              method="GET",
                                              data=b"") as ctx:
            response = FlaskResponse(
                response=json.dumps({"apps": fixtures}),
                status=HTTPStatus.OK,
                headers={},
            )
            response = Response(ctx.request, response)

        with patch.object(response, "marathon_client") as client:
            original_apps = [AsgardApp.from_json(app) for app in fixtures]
            client.get_app.side_effect = original_apps
            apps = list(response.split())

            joined_response = response.join(apps)

            self.assertIsInstance(joined_response, FlaskResponse)
            self.assertDictEqual(json.loads(joined_response.data),
                                 {"apps": expected_response})
Esempio n. 24
0
    def test_multiapp_response_returns_multiple_marathonapp_instances(self, fixture):
        modified_app = fixture.copy()
        modified_app['id'] = '/xablau'

        apps = [fixture, modified_app]
        with application.test_request_context('/v2/apps/',
                                              method='GET', data=b'') as ctx:
            response = FlaskResponse(response=json.dumps({"apps": apps}),
                                     status=HTTPStatus.OK,
                                     headers={})
            response = Response(ctx.request, response)

        with patch.object(response, 'marathon_client') as client:
            original_apps = [MarathonApp.from_json(app) for app in apps]
            client.get_app.side_effect = original_apps
            apps = list(response.split())
            self.assertEqual([call("/foo"), call("/xablau")], client.get_app.call_args_list)

        self.assertEqual(
            apps,
            [
                (AsgardApp.from_json(fixture), original_apps[0]),
                (AsgardApp.from_json(modified_app), original_apps[1])
            ]
        )
Esempio n. 25
0
    def test_changes_from_all_filters_are_persisted_after_response_join(
            self, group_dev_namespace_fixture):
        """
        Certificamos que uma modificação de um filtro não é perdida durante a
        execução do pipeline. No response final, todas as modificações devem estar
        disponíveis.
        """
        with application.test_request_context("/v2/groups/group-b",
                                              method="GET") as ctx:
            ctx.request.user = self.user
            ok_response = FlaskResponse(
                response=json.dumps(group_dev_namespace_fixture["groups"][1]),
                status=HTTPStatus.OK,
                headers={},
            )

            ctx.request.user = self.user
            response_wrapper = Response(ctx.request, ok_response)
            final_response = dispatch(
                user=self.user,
                request=response_wrapper,
                filters_pipeline={
                    OperationType.READ: [DummyFilter(),
                                         FooFilter()]
                },
                filter_method_name_callback=lambda *args: "response_group",
            )
            final_response_data = json.loads(final_response.data)
            returned_group = MarathonGroup.from_json(final_response_data)
            self.assertEqual("/foo/dummy/dev/group-b/appb0",
                             returned_group.apps[0].id)
            self.assertEqual(
                "/foo/dummy/dev/group-b/group-b0/app0",
                returned_group.groups[0].apps[0].id,
            )
Esempio n. 26
0
    def test_filters_can_modify_all_apps_from_group_and_subgroups(self, group_dev_namespace_fixture):
        """
        Um fltro deve poder alterar todas as apps de todos os grupos de um response.
        """
        with application.test_request_context("/v2/groups/group-b", method="GET") as ctx:
            ctx.request.user = self.user
            ok_response = FlaskResponse(
                response=json.dumps(group_dev_namespace_fixture['groups'][1]),
                status=HTTPStatus.OK,
                headers={}
            )
            with RequestsMock() as rsps:
                rsps.add(method='GET', url=conf.MARATHON_ADDRESSES[0] + '/v2/groups//dev/group-b',
                         body=json.dumps(deepcopy(group_dev_namespace_fixture['groups'][1])), status=200)
                rsps.add(method='GET', url=conf.MARATHON_ADDRESSES[0] + '/v2/groups//dev/group-b/group-b0',
                         body=json.dumps(deepcopy(group_dev_namespace_fixture['groups'][1]['groups'][0])), status=200)

                response_wrapper = Response(ctx.request, ok_response)
                final_response = dispatch(user=self.user,
                                          request=response_wrapper,
                                          filters_pipeline={OperationType.READ: [DummyFilter()]},
                                          filter_method_name_callback=lambda *args: "response_group")
                final_response_data = json.loads(final_response.data)
                returned_group = MarathonGroup.from_json(final_response_data)
                self.assertEqual("/dummy/dev/group-b/appb0", returned_group.apps[0].id)
                self.assertEqual("/dummy/dev/group-b/group-b0/app0", returned_group.groups[0].apps[0].id)
Esempio n. 27
0
    def test_filters_can_modify_all_apps_from_group_and_subgroups(
            self, group_dev_namespace_fixture):
        """
        Um fltro deve poder alterar todas as apps de todos os grupos de um response.
        """
        with application.test_request_context("/v2/groups/group-b",
                                              method="GET") as ctx:
            ctx.request.user = self.user
            ok_response = FlaskResponse(
                response=json.dumps(group_dev_namespace_fixture["groups"][1]),
                status=HTTPStatus.OK,
                headers={},
            )

            response_wrapper = Response(ctx.request, ok_response)
            final_response = dispatch(
                user=self.user,
                request=response_wrapper,
                filters_pipeline={OperationType.READ: [DummyFilter()]},
                filter_method_name_callback=lambda *args: "response_group",
            )
            final_response_data = json.loads(final_response.data)
            returned_group = MarathonGroup.from_json(final_response_data)
            self.assertEqual("/dummy/dev/group-b/appb0",
                             returned_group.apps[0].id)
            self.assertEqual(
                "/dummy/dev/group-b/group-b0/app0",
                returned_group.groups[0].apps[0].id,
            )
Esempio n. 28
0
    def test_split_groups_read_on_specific_group(self, group_b_fixture):

        with application.test_request_context('/v2/groups/group-b',
                                              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-b',
                         body=json.dumps(group_b_fixture),
                         status=200)

                apps = list(request_parser.split())
                self.assertEqual(2, len(apps))

                original_app_one = MarathonApp.from_json(
                    {"id": "/dev/group-b/appb0"})
                original_app_two = MarathonApp.from_json(
                    {"id": "/dev/group-b/group-b0/app0"})
                expected_apps = [
                    (request_parser.merge_marathon_apps(
                        MarathonApp(), original_app_one), original_app_one),
                    (request_parser.merge_marathon_apps(
                        MarathonApp(), original_app_two), original_app_two),
                ]
                self.assertEqual(expected_apps, apps)
Esempio n. 29
0
    def test_can_read_app_if_already_migrated(self, single_full_app_fixture):
        """
        Conferimos que é possível fazer um GET em
        /v2/apps/<app-id> para uma app que já está migrada.
        O <app-id> usado é sempre *sem* namespace
        """
        request_data = deepcopy(single_full_app_fixture)
        single_full_app_fixture["id"] = "/dev/foo"
        with application.test_request_context("/v2/apps/foo",
                                              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/apps//dev/foo",
                    body=json.dumps({"app": single_full_app_fixture}),
                    status=200,
                )

                apps = list(request_parser.split())

                original_app = MarathonApp.from_json(single_full_app_fixture)
                expected_app = (
                    request_parser.merge_marathon_apps(MarathonApp(),
                                                       original_app),
                    original_app,
                )
                self.assertEqual(apps, [expected_app])
Esempio n. 30
0
 def test_add_original_payload_to_upstream_request(self, mock_get):
     with application.test_request_context("/v2/apps?a=b&c=d",
                                           method="GET",
                                           data="Request Data"):
         replay_request(flask.request)
         self.assertTrue(mock_get.called)
         called_headers = mock_get.call_args[1]['data']
         self.assertEqual(called_headers, b"Request Data")