From da1fd68d6624b26816378a98b1707584fce19a1f Mon Sep 17 00:00:00 2001 From: ygcyao Date: Tue, 19 Mar 2024 14:58:27 +0800 Subject: [PATCH] =?UTF-8?q?test(backend):=20mongos=20=E6=89=A9=E7=BC=A9?= =?UTF-8?q?=E5=AE=B9=E6=8E=A5=E5=85=A5=E5=B1=82=E5=8D=95=E5=85=83=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=20#3559?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tests/mock_data/ticket/mongodb_flow.py | 337 ++++++++++++++++++ .../backend/tests/ticket/test_mangodb_flow.py | 156 ++++++++ 2 files changed, 493 insertions(+) create mode 100644 dbm-ui/backend/tests/mock_data/ticket/mongodb_flow.py create mode 100644 dbm-ui/backend/tests/ticket/test_mangodb_flow.py diff --git a/dbm-ui/backend/tests/mock_data/ticket/mongodb_flow.py b/dbm-ui/backend/tests/mock_data/ticket/mongodb_flow.py new file mode 100644 index 0000000000..9b7ffcbe47 --- /dev/null +++ b/dbm-ui/backend/tests/mock_data/ticket/mongodb_flow.py @@ -0,0 +1,337 @@ +# -*- coding: utf-8 -*- +""" +TencentBlueKing is pleased to support the open source community by making 蓝鲸智云-DB管理系统(BlueKing-BK-DBM) available. +Copyright (C) 2017-2023 THL A29 Limited, a Tencent company. All rights reserved. +Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. +You may obtain a copy of the License at https://opensource.org/licenses/MIT +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on +an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. +""" + + +from backend.db_meta.enums.cluster_type import ClusterType +from backend.ticket.constants import TicketType + +BK_USERNAME = "admin" +BK_BIZ_ID = 1 +CLUSTER_ID = 1 + +# mangos 扩容请求单据 +MANGODB_ADD_MANGOS_TICKET_DATA = { + "ticket_type": TicketType.MONGODB_ADD_MONGOS, + "bk_biz_id": BK_BIZ_ID, + "details": { + "infos": [ + {"cluster_id": CLUSTER_ID, "role": "mongos", "resource_spec": {"mongos": {"spec_id": 3, "count": 1}}} + ] + }, +} + +# mangos 缩容请求单据 +MANGODB_REDUCE_MANGOS_DATA = { + "bk_biz_id": BK_BIZ_ID, + "ticket_type": TicketType.MONGODB_REDUCE_MONGOS, + "details": { + "is_safe": True, + "infos": [ + { + "cluster_id": CLUSTER_ID, + "role": "mongos", + "reduce_nodes": [{"ip": "127.0.0.1", "bk_cloud_id": 0, "bk_host_id": 3}], + } + ], + }, +} + +# mangos 扩容资源池数据 +MANGOS_ADD_SOURCE_DATA = { + "0_mongos": [ + { + "bk_biz_id": BK_BIZ_ID, + "ip": "127.0.0.1", + "bk_cloud_id": 0, + "bk_host_id": 3, + "bk_cpu": 2, + "bk_disk": 147, + "bk_mem": 3663, + "storage_device": {"/data": {"size": 50, "disk_id": "disk-01", "disk_type": "HDD", "file_type": "ext4"}}, + "city": "", + "sub_zone": "", + "sub_zone_id": "", + "rack_id": "", + "device_class": "", + } + ] +} + +# 初始化mongodb集群 +MANGODB_CLUSTER_DATA = { + "id": CLUSTER_ID, + "creator": BK_USERNAME, + "updater": BK_USERNAME, + "name": "shard01", + "alias": "shard01", + "bk_biz_id": BK_BIZ_ID, + "cluster_type": ClusterType.MongoShardedCluster, + "db_module_id": 0, + "immute_domain": "mongos.shard01.dba.db", + "major_version": "3.4.20", + "phase": "online", + "status": "normal", + "bk_cloud_id": 0, + "region": "default", + "time_zone": "+08:00", + "disaster_tolerance_level": "NONE", +} + +# mangodb集群规格数据 +MANGODB_SPEC_DATA = [ + { + "spec_id": 3, + "spec_name": "1核_1G_10G", + "cpu": {"max": 256, "min": 1}, + "mem": {"max": 256, "min": 1}, + "storage_spec": [{"size": 10, "type": "ALL", "mount_point": "/data"}], + "spec_cluster_type": ClusterType.MongoShardedCluster, + "spec_machine_type": "mongos", + "qps": {"max": 0, "min": 0}, + "enable": 1, + }, + { + "spec_id": 1, + "spec_name": "1核_1G_10G", + "cpu": {"max": 256, "min": 1}, + "mem": {"max": 256, "min": 1}, + "storage_spec": [{"size": 10, "type": "ALL", "mount_point": "/data"}], + "spec_cluster_type": ClusterType.MongoShardedCluster, + "spec_machine_type": "mongos", + "qps": {"max": 0, "min": 0}, + "enable": 1, + }, + { + "spec_id": 2, + "spec_name": "2核_1G_10G", + "cpu": {"max": 256, "min": 1}, + "mem": {"max": 256, "min": 1}, + "storage_spec": [{"size": 10, "type": "ALL", "mount_point": "/data"}], + "spec_cluster_type": ClusterType.MongoShardedCluster, + "spec_machine_type": "mongos", + "qps": {"max": 0, "min": 0}, + "enable": 1, + }, +] + +# mongodb实例数据 +MANGODB_PROXYINSTANCE_DATA = [ + { + "creator": BK_USERNAME, + "create_at": "2024-03-14 01:36:51.626234", + "updater": "", + "update_at": "2024-03-14 01:36:51.626234", + "version": "", + "port": 10000, + "admin_port": 20000, + "db_module_id": 0, + "bk_biz_id": BK_BIZ_ID, + "access_layer": "proxy", + "machine_type": "mongos", + "cluster_type": ClusterType.MongoShardedCluster, + "status": "running", + "name": "", + "time_zone": "+08:00", + "bk_instance_id": 7089, + "machine_id": 3, + "phase": "online", + }, + { + "creator": BK_USERNAME, + "create_at": "2024-03-13 11:14:48.438115", + "updater": "", + "update_at": "2024-03-13 11:14:48.438115", + "version": "", + "port": 10000, + "admin_port": 20000, + "db_module_id": 0, + "bk_biz_id": BK_BIZ_ID, + "access_layer": "proxy", + "machine_type": "mongos", + "cluster_type": ClusterType.MongoShardedCluster, + "status": "running", + "name": "", + "time_zone": "+08:00", + "bk_instance_id": 7087, + "machine_id": 130, + "phase": "online", + }, + { + "creator": "", + "create_at": "2024-03-12 04:52:46.603053", + "updater": "", + "update_at": "2024-03-12 04:52:46.603053", + "version": "", + "port": 10000, + "admin_port": 20000, + "db_module_id": 0, + "bk_biz_id": BK_BIZ_ID, + "access_layer": "proxy", + "machine_type": "mongos", + "cluster_type": ClusterType.MongoShardedCluster, + "status": "running", + "name": "", + "time_zone": "+08:00", + "bk_instance_id": 7023, + "machine_id": 1, + "phase": "online", + }, + { + "creator": "", + "create_at": "2024-03-12 04:52:46.598053", + "updater": "", + "update_at": "2024-03-12 04:52:46.598053", + "version": "", + "port": 10000, + "admin_port": 20000, + "db_module_id": 0, + "bk_biz_id": BK_BIZ_ID, + "access_layer": "proxy", + "machine_type": "mongos", + "cluster_type": ClusterType.MongoShardedCluster, + "status": "running", + "name": "", + "time_zone": "+08:00", + "bk_instance_id": 7024, + "machine_id": 2, + "phase": "online", + }, +] + +# mangodb 集群机器信息 +MANGODB_MACHINE_DATA = [ + { + "creator": BK_USERNAME, + "create_at": "2024-03-13 11:14:48.433116", + "updater": "", + "update_at": "2024-03-13 11:14:48.433116", + "ip": "1.1.1.4", + "bk_biz_id": BK_BIZ_ID, + "db_module_id": 0, + "access_layer": "proxy", + "machine_type": "mongos", + "cluster_type": ClusterType.MongoShardedCluster, + "bk_host_id": 130, + "bk_os_name": "linux centos", + "bk_idc_area": "", + "bk_idc_area_id": 0, + "bk_sub_zone": "", + "bk_sub_zone_id": 0, + "bk_rack": "", + "bk_rack_id": 0, + "bk_svr_device_cls_name": "", + "bk_idc_name": "", + "bk_idc_id": 0, + "bk_cloud_id": 0, + "net_device_id": "", + "bk_city_id": 0, + "spec_config": '{"id": 3, "cpu": {"max": 256, "min": 1}, "mem": {"max": 256, "min": 1}, ' + '"qps": {"max": 0, "min": 0}, "name": "1核_1G_10G", "count": 1, "device_class": [],' + ' "storage_spec": [{"size": 10, "type": "ALL", "mount_point": "/data"}]}', + "spec_id": 3, + "bk_agent_id": "", + }, + { + "creator": "", + "create_at": "2024-03-12 04:52:46.559806", + "updater": "", + "update_at": "2024-03-12 04:52:46.560347", + "ip": "1.1.1.5", + "bk_biz_id": BK_BIZ_ID, + "db_module_id": 0, + "access_layer": "proxy", + "machine_type": "mongos", + "cluster_type": ClusterType.MongoShardedCluster, + "bk_host_id": 2, + "bk_os_name": "linux centos", + "bk_idc_area": "", + "bk_idc_area_id": 0, + "bk_sub_zone": "", + "bk_sub_zone_id": 0, + "bk_rack": "", + "bk_rack_id": 0, + "bk_svr_device_cls_name": "", + "bk_idc_name": "", + "bk_idc_id": 0, + "bk_cloud_id": 0, + "net_device_id": "", + "bk_city_id": 0, + "spec_config": '{"id": 2, "cpu": {"max": 256, "min": 1}, "mem": {"max": 256, "min": 1}, ' + '"qps": {"max": 0, "min": 0}, "name": "2核_1G_10G", "count": 2, "device_class": [],' + '"storage_spec": [{"size": 10, "type": "ALL", "mount_point": "/data"}]}', + "spec_id": 2, + "bk_agent_id": "", + }, + { + "creator": "", + "create_at": "2024-03-12 04:52:46.570057", + "updater": "", + "update_at": "2024-03-12 04:52:46.570057", + "ip": "1.1.1.3", + "bk_biz_id": BK_BIZ_ID, + "db_module_id": 0, + "access_layer": "proxy", + "machine_type": "mongos", + "cluster_type": ClusterType.MongoShardedCluster, + "bk_host_id": 1, + "bk_os_name": "linux centos", + "bk_idc_area": "", + "bk_idc_area_id": 0, + "bk_sub_zone": "", + "bk_sub_zone_id": 0, + "bk_rack": "", + "bk_rack_id": 0, + "bk_svr_device_cls_name": "", + "bk_idc_name": "", + "bk_idc_id": 0, + "bk_cloud_id": 0, + "net_device_id": "", + "bk_city_id": 0, + "spec_config": '{"id": 2, "cpu": {"max": 256, "min": 1}, "mem": {"max": 256, "min": 1}, ' + '"qps": {"max": 0, "min": 0}, "name": "2核_1G_10G", "count": 2, "device_class": [],' + ' "storage_spec": [{"size": 10, "type": "ALL", "mount_point": "/data"}]}', + "spec_id": 2, + "bk_agent_id": "", + }, + { + "creator": BK_USERNAME, + "create_at": "2024-03-14 01:36:51.614034", + "updater": "", + "update_at": "2024-03-14 01:36:51.614034", + "ip": "1.1.1.7", + "bk_biz_id": BK_BIZ_ID, + "db_module_id": 0, + "access_layer": "proxy", + "machine_type": "mongos", + "cluster_type": ClusterType.MongoShardedCluster, + "bk_host_id": 3, + "bk_os_name": "linux centos", + "bk_idc_area": "", + "bk_idc_area_id": 0, + "bk_sub_zone": "", + "bk_sub_zone_id": 0, + "bk_rack": "", + "bk_rack_id": 0, + "bk_svr_device_cls_name": "", + "bk_idc_name": "", + "bk_idc_id": 0, + "bk_cloud_id": 0, + "net_device_id": "", + "bk_city_id": 0, + "spec_config": '{"id": 3, "cpu": {"max": 256, "min": 1}, "mem": {"max": 256, "min": 1}, ' + '"qps": {"max": 0, "min": 0}, "name": "1核_1G_10G", "count": 1, "device_class": [],' + ' "storage_spec": [{"size": 10, "type": "ALL", "mount_point": "/data"}]}', + "spec_id": 3, + "bk_agent_id": "", + }, +] + +APPCACHE_DATA = {"bk_biz_id": BK_BIZ_ID, "db_app_abbr": "dba"} diff --git a/dbm-ui/backend/tests/ticket/test_mangodb_flow.py b/dbm-ui/backend/tests/ticket/test_mangodb_flow.py new file mode 100644 index 0000000000..55d5fc5e74 --- /dev/null +++ b/dbm-ui/backend/tests/ticket/test_mangodb_flow.py @@ -0,0 +1,156 @@ +# -*- coding: utf-8 -*- +""" +TencentBlueKing is pleased to support the open source community by making 蓝鲸智云-DB管理系统(BlueKing-BK-DBM) available. +Copyright (C) 2017-2023 THL A29 Limited, a Tencent company. All rights reserved. +Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. +You may obtain a copy of the License at https://opensource.org/licenses/MIT +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on +an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. +""" +import copy +import logging +from unittest.mock import PropertyMock, patch + +import pytest +from django.conf import settings +from rest_framework.permissions import AllowAny +from rest_framework.test import APIClient + +from backend.db_meta.models import AppCache, Cluster, Machine, ProxyInstance, Spec +from backend.tests.mock_data.components.cc import CCApiMock +from backend.tests.mock_data.components.itsm import ItsmApiMock +from backend.tests.mock_data.iam_app.permission import PermissionMock +from backend.tests.mock_data.ticket.mongodb_flow import ( + APPCACHE_DATA, + MANGODB_ADD_MANGOS_TICKET_DATA, + MANGODB_CLUSTER_DATA, + MANGODB_MACHINE_DATA, + MANGODB_PROXYINSTANCE_DATA, + MANGODB_REDUCE_MANGOS_DATA, + MANGODB_SPEC_DATA, + MANGOS_ADD_SOURCE_DATA, +) +from backend.tests.mock_data.ticket.ticket_flow import ROOT_ID, SN +from backend.ticket.constants import FlowType, TicketFlowStatus, TicketStatus +from backend.ticket.flow_manager.inner import InnerFlow +from backend.ticket.flow_manager.pause import PauseFlow +from backend.ticket.models import Flow +from backend.ticket.views import TicketViewSet + +logger = logging.getLogger("test") +pytestmark = pytest.mark.django_db +client = APIClient() + +INITIAL_FLOW_FINISHED_STATUS = [TicketFlowStatus.SKIPPED, TicketStatus.SUCCEEDED] +CHANGED_MOCK_STATUS = [TicketFlowStatus.SKIPPED, TicketStatus.SUCCEEDED, TicketFlowStatus.RUNNING] + + +@pytest.fixture(scope="function") +def query_fixture(django_db_blocker): + with django_db_blocker.unblock(): + # 初始化集群数据 + Spec.objects.all().delete() + Cluster.objects.create(**MANGODB_CLUSTER_DATA) + AppCache.objects.create(**APPCACHE_DATA) + Spec.objects.bulk_create([Spec(**data) for data in MANGODB_SPEC_DATA]) + Machine.objects.bulk_create([Machine(**data) for data in MANGODB_MACHINE_DATA]) + ProxyInstance.objects.bulk_create([ProxyInstance(**data) for data in MANGODB_PROXYINSTANCE_DATA]) + cluster_id = Cluster.objects.first() + for proxy_instance in ProxyInstance.objects.all(): + proxy_instance.cluster.add(cluster_id) + + yield + ProxyInstance.objects.all().delete() + Cluster.objects.all().delete() + AppCache.objects.all().delete() + Spec.objects.all().delete() + Machine.objects.all().delete() + + +@pytest.fixture(autouse=True) # autouse=True 会自动应用这个fixture到所有的测试中 +def set_empty_middleware(): + with patch.object(settings, "MIDDLEWARE", []): + yield + + +class TestMangodbFlow: + """ + mangodb测试类 + """ + + # mangos 扩容接入层 + @patch.object(TicketViewSet, "permission_classes") + @patch.object(InnerFlow, "_run") + @patch.object(InnerFlow, "status", new_callable=PropertyMock) + @patch.object(PauseFlow, "status", new_callable=PropertyMock) + @patch.object(TicketViewSet, "get_permissions", lambda x: []) + @patch("backend.ticket.flow_manager.itsm.ItsmApi", ItsmApiMock()) + @patch("backend.db_services.cmdb.biz.CCApi", CCApiMock()) + @patch("backend.components.cmsi.handler.CmsiHandler.send_msg", lambda msg: "有一条MANGOS 扩容接入层待办需要您处理") + @patch( + "backend.ticket.flow_manager.resource.ResourceApplyFlow.apply_resource", + lambda resource_request_id, node_infos: (1, MANGOS_ADD_SOURCE_DATA), + ) + @patch("backend.db_services.cmdb.biz.Permission", PermissionMock) + def test_mango_add_mangos_flow( + self, mock_pause_status, mocked_status, mocked__run, mocked_permission_classes, query_fixture, db + ): + # MANGODB 扩容接入层: start --> itsm --> PAUSE --> RESOURC --> INNER_FLOW --> end + mocked_status.return_value = TicketStatus.SUCCEEDED + mock_pause_status.return_value = TicketFlowStatus.SKIPPED + mocked__run.return_value = ROOT_ID + mocked_permission_classes.return_value = [AllowAny] + + client.login(username="admin") + + # itsm流程 + mangos_add_data = copy.deepcopy(MANGODB_ADD_MANGOS_TICKET_DATA) + client.post("/apis/tickets/", data=mangos_add_data) + current_flow = Flow.objects.filter(flow_obj_id=SN).first() + assert current_flow is not None + + # PAUSE流程 + client.post(f"/apis/tickets/{current_flow.ticket_id}/callback/") + current_flow = Flow.objects.exclude(flow_obj_id="").last() + assert current_flow.flow_type == FlowType.PAUSE + # RESOURCE_APPLY -> INNER_FLOW + client.post(f"/apis/tickets/{current_flow.ticket_id}/callback/") + current_flow = Flow.objects.exclude(flow_obj_id="").last() + assert current_flow.flow_type == FlowType.INNER_FLOW + + # mangos 缩容接入层 + @patch.object(TicketViewSet, "permission_classes") + @patch.object(InnerFlow, "_run") + @patch.object(InnerFlow, "status", new_callable=PropertyMock) + @patch.object(PauseFlow, "status", new_callable=PropertyMock) + @patch.object(TicketViewSet, "get_permissions", lambda x: []) + @patch("backend.ticket.flow_manager.itsm.ItsmApi", ItsmApiMock()) + @patch("backend.db_services.cmdb.biz.CCApi", CCApiMock()) + @patch("backend.components.cmsi.handler.CmsiHandler.send_msg", lambda msg: "有一条MANGOS 缩容接入层待办需要您处理") + @patch("backend.db_services.cmdb.biz.Permission", PermissionMock) + def test_mango_reduce_mangos_flow( + self, mock_pause_status, mocked_status, mocked__run, mocked_permission_classes, query_fixture, db + ): + # MANGOS 缩容接入层: start --> itsm --> PAUSE --> INNER_FLOW --> end + mocked_status.return_value = TicketStatus.SUCCEEDED + mock_pause_status.return_value = TicketFlowStatus.SKIPPED + mocked__run.return_value = ROOT_ID + mocked_permission_classes.return_value = [AllowAny] + + client.login(username="admin") + + # itsm流程 + mangos_add_data = copy.deepcopy(MANGODB_REDUCE_MANGOS_DATA) + client.post("/apis/tickets/", data=mangos_add_data) + current_flow = Flow.objects.filter(flow_obj_id=SN).first() + assert current_flow is not None + + # PAUSE流程 + client.post(f"/apis/tickets/{current_flow.ticket_id}/callback/") + current_flow = Flow.objects.exclude(flow_obj_id="").last() + assert current_flow.flow_type == FlowType.PAUSE + # RESOURCE_APPLY -> INNER_FLOW + client.post(f"/apis/tickets/{current_flow.ticket_id}/callback/") + current_flow = Flow.objects.exclude(flow_obj_id="").last() + assert current_flow.flow_type == FlowType.INNER_FLOW