Beispiel #1
0
async def scale_all_apps(app: App):
    cloud_interface = AsgardInterface()
    state_checker = PeriodicStateChecker(cloud_interface)
    decision_maker = DecisionComponent()

    logger.debug({"AUTOSCALER": "iniciando autoscaler"})
    apps_stats = await state_checker.get_scalable_apps_stats()
    logger.debug({"AUTOSCALER_FETCH_APPS": [app.id for app in apps_stats]})
    scaling_decisions = decision_maker.decide_scaling_actions(apps_stats)
    await cloud_interface.apply_decisions(scaling_decisions)
    async def test_get_scalable_apps_stats_one_scalable_app(self):
        state_checker = PeriodicStateChecker(AsgardCloudInterface())
        with aioresponses() as rsps:

            apps_fixture = {
                "apps": [
                    {
                        "id": "test_app1",
                        "cpus": 3.5,
                        "mem": 1.0,
                        "labels": {
                            "asgard.autoscale.cpu": 0.3,
                            "asgard.autoscale.mem": 0.8,
                            "asgard.autoscale.ignore": "all",
                        },
                    },
                    {
                        "id": "/test_app2",
                        "cpus": 3.5,
                        "mem": 1.0,
                        "labels": {
                            "asgard.autoscale.cpu": 0.1,
                            "asgard.autoscale.mem": 0.1,
                            "asgard.autoscale.ignore": "",
                        },
                    },
                ]
            }

            rsps.get(
                f"{settings.ASGARD_API_ADDRESS}/v2/apps",
                status=200,
                payload=apps_fixture,
            )

            stats_fixture = {
                "stats": {
                    "type": "ASGARD",
                    "errors": {},
                    "cpu_pct": "1",
                    "ram_pct": "1",
                    "cpu_thr_pct": "1",
                }
            }

            for app in apps_fixture["apps"]:
                rsps.get(
                    f'{settings.ASGARD_API_ADDRESS}/apps{app["id"]}/stats/avg-1min',
                    status=200,
                    payload=stats_fixture,
                )

            scalable_apps = await state_checker.get_scalable_apps_stats()

            self.assertEqual(1, len(scalable_apps))
    async def test_get_scalable_apps_stats_no_scalable_apps(self):
        state_checker = PeriodicStateChecker(AsgardCloudInterface())
        with aioresponses() as rsps:
            rsps.get(
                f"{settings.ASGARD_API_ADDRESS}/v2/apps",
                status=200,
                payload={"apps": []},
            )

            scalable_apps = await state_checker.get_scalable_apps_stats()

            self.assertEqual(0, len(scalable_apps))
Beispiel #4
0
    async def test_decide_to_scale_all_apps(self):
        cloud_interface = AsgardCloudInterface()
        state_checker = PeriodicStateChecker(cloud_interface)
        decision_maker = DecisionComponent()

        with aioresponses() as rsps:
            stats_fixture = {
                "stats": {
                    "type": "ASGARD",
                    "errors": {},
                    "cpu_pct": "100",
                    "ram_pct": "100",
                    "cpu_thr_pct": "0",
                }
            }

            apps_fixture = {
                "apps": [
                    {
                        "id": "/test_app1",
                        "cpus": 3.5,
                        "mem": 1.0,
                        "labels": {
                            "asgard.autoscale.cpu": 0.3,
                            "asgard.autoscale.mem": 0.8,
                            "asgard.autoscale.ignore": "cpu",
                        },
                    },
                    {
                        "id": "/test_app2",
                        "cpus": 3.5,
                        "mem": 1.0,
                        "labels": {
                            "asgard.autoscale.cpu": 0.1,
                            "asgard.autoscale.mem": 0.6,
                            "asgard.autoscale.ignore": "mem",
                        },
                    },
                ]
            }

            rsps.get(
                f"{settings.ASGARD_API_ADDRESS}/v2/apps",
                status=200,
                payload=apps_fixture,
            )

            for app in apps_fixture["apps"]:
                rsps.get(
                    f"{settings.ASGARD_API_ADDRESS}/apps{app['id']}/stats/avg-1min",
                    status=200,
                    payload=stats_fixture,
                )

            rsps.put(
                f"{settings.ASGARD_API_ADDRESS}/v2/apps",
                status=200,
                payload={
                    "deploymentId": "test",
                    "version": "1.0"
                },
            )

            apps_stats = await state_checker.get_scalable_apps_stats()
            scaling_decision = decision_maker.decide_scaling_actions(
                apps_stats)
            await cloud_interface.apply_decisions(scaling_decision)

            scale_spy = rsps.requests.get(
                ("put", URL(f"{settings.ASGARD_API_ADDRESS}/v2/apps")))

        self.assertEqual(len(apps_stats), len(scaling_decision))
        self.assertEqual(1.25, scaling_decision[0].mem)
        self.assertEqual("test_app1", scaling_decision[0].id)
        self.assertEqual(None, scaling_decision[0].cpu)
        self.assertEqual("test_app2", scaling_decision[1].id)
        self.assertEqual(None, scaling_decision[1].mem)
        self.assertEqual(35, scaling_decision[1].cpu)
        self.assertIsNotNone(scale_spy)
Beispiel #5
0
    async def test_scales_when_difference_more_than_5_percent(self):
        cloud_interface = AsgardCloudInterface()
        state_checker = PeriodicStateChecker(cloud_interface)
        decision_maker = DecisionComponent()

        with aioresponses() as rsps:
            stats_fixture = {
                "stats": {
                    "type": "ASGARD",
                    "errors": {},
                    "cpu_pct": "24.9",
                    "ram_pct": "85.1",
                    "cpu_thr_pct": "0",
                }
            }

            apps_fixture = {
                "apps": [{
                    "id": "/test_app1",
                    "cpus": 3.5,
                    "mem": 1.0,
                    "labels": {
                        "asgard.autoscale.cpu": 0.3,
                        "asgard.autoscale.mem": 0.8,
                    },
                }]
            }

            rsps.get(
                f"{settings.ASGARD_API_ADDRESS}/v2/apps",
                status=200,
                payload=apps_fixture,
            )

            rsps.put(
                f"{settings.ASGARD_API_ADDRESS}/v2/apps",
                status=200,
                payload={
                    "deploymentId": "test",
                    "version": "1.0"
                },
            )

            for app in apps_fixture["apps"]:
                rsps.get(
                    f"{settings.ASGARD_API_ADDRESS}/apps{app['id']}/stats/avg-1min",
                    status=200,
                    payload=stats_fixture,
                )

            apps_stats = await state_checker.get_scalable_apps_stats()
            scaling_decision = decision_maker.decide_scaling_actions(
                apps_stats)
            await cloud_interface.apply_decisions(scaling_decision)
            scale_spy = rsps.requests.get(
                ("put", URL(f"{settings.ASGARD_API_ADDRESS}/v2/apps")))

        self.assertEqual(1, len(apps_stats), "didn't fetch one app")
        self.assertEqual(1, len(scaling_decision),
                         "didn't make scaling decision")
        self.assertEqual("test_app1", scaling_decision[0].id,
                         "made decision for wrong app")
        self.assertEqual(2.905, scaling_decision[0].cpu,
                         "scaled cpu to incorrect value")
        self.assertEqual(1.06375, scaling_decision[0].mem,
                         "scaled memory to incorrect value")
        self.assertIsNotNone(scale_spy)