# -*- coding: utf-8 -*-
# 测试用例
# 作者: 陈磊
# 时间: 2019-12-02


from __future__ import division

from WorkApi.API.Host.host_create import HostCreate
from WorkUtils.UtilsLog import UtilsLog
from WorkUtils.UtilsDataBase import UtilsDataBase
from WorkUtils.UtilsResponse import UtilsResponse

from WorkApi.API.Problem.problem_acknowledge import ProblemAcknowledge

from WorkData.Zabbix.hosts import DataHosts
from WorkData.Zabbix.events import DataEvents
from WorkData.Zabbix.items import DataItems
from WorkData.Zabbix.functions import DataFunctions
from WorkData.Zabbix.problem import DataProblem

from WorkCase import CaseBase

import allure
import time


@allure.feature("测试模块：problem.acknowledge")
class TestProblemAcknowledge(object):
    log = UtilsLog()
    env = CaseBase().environment_test
    host = env["host_zabbix"]
    db_url = env["db_url_zabbix"]
    db_port = env["db_port_zabbix"]
    db_user = env["db_user_zabbix"]
    db_pw = env["db_pw_zabbix"]
    db_base = env["db_base_zabbix"]

    base_name = "SS EVENT"
    base_host_name = "SS HOST EVENT"
    base_description = "SS 自动化专用 告警"
    base_ip = "172.16.3.170"
    base_groupid = 99
    base_port = 161
    base_eventid = 92000000
    base_type_snmp = 10186

    @classmethod
    def setup_class(cls):
        cls.log.debug("开始执行测试套件.......")
        session = UtilsDataBase().conn_mysql(db_url=cls.db_url, db_port=cls.db_port, db_base=cls.db_base, db_user=cls.db_user, db_pw=cls.db_pw)
        sql = DataHosts().select_like_name(session=session, name=cls.base_host_name)

        for x, y in enumerate(sql):
            session = UtilsDataBase().conn_mysql(db_url=cls.db_url, db_port=cls.db_port, db_base=cls.db_base, db_user=cls.db_user, db_pw=cls.db_pw)
            DataItems().delete_hostid(session=session, hostid=y.hostid)

        session = UtilsDataBase().conn_mysql(db_url=cls.db_url, db_port=cls.db_port, db_base=cls.db_base, db_user=cls.db_user, db_pw=cls.db_pw)
        DataHosts().delete_like_name(session=session, name=cls.base_host_name)

        session = UtilsDataBase().conn_mysql(db_url=cls.db_url, db_port=cls.db_port, db_base=cls.db_base, db_user=cls.db_user, db_pw=cls.db_pw)
        DataEvents().delete_like_name(session=session, name=cls.base_name)

        session = UtilsDataBase().conn_mysql(db_url=cls.db_url, db_port=cls.db_port, db_base=cls.db_base, db_user=cls.db_user, db_pw=cls.db_pw)
        DataProblem().delete_like_name(session=session, name=cls.base_name)

    @classmethod
    def teardown_class(cls):
        cls.log.debug("结束执行测试套件.......")
        session = UtilsDataBase().conn_mysql(db_url=cls.db_url, db_port=cls.db_port, db_base=cls.db_base, db_user=cls.db_user, db_pw=cls.db_pw)
        sql = DataHosts().select_like_name(session=session, name=cls.base_host_name)

        for x, y in enumerate(sql):
            session = UtilsDataBase().conn_mysql(db_url=cls.db_url, db_port=cls.db_port, db_base=cls.db_base, db_user=cls.db_user, db_pw=cls.db_pw)
            DataItems().delete_hostid(session=session, hostid=y.hostid)

        session = UtilsDataBase().conn_mysql(db_url=cls.db_url, db_port=cls.db_port, db_base=cls.db_base, db_user=cls.db_user, db_pw=cls.db_pw)
        DataHosts().delete_like_name(session=session, name=cls.base_host_name)

        session = UtilsDataBase().conn_mysql(db_url=cls.db_url, db_port=cls.db_port, db_base=cls.db_base, db_user=cls.db_user, db_pw=cls.db_pw)
        DataEvents().delete_like_name(session=session, name=cls.base_name)

    def setup_method(self):
        self.log.debug("测试用例执行开始...")

    def teardown_method(self):
        self.log.debug("测试用例执行结束...")

    @allure.step("调用接口：problem.acknowledge")
    def problem_acknowledge(self, eventids=None, action=None):
        api = ProblemAcknowledge(_host=self.host)
        api.eventids = eventids
        api.action = action
        api.get_response()
        return api.response

    @allure.step("连接数据库：zabbix")
    def db_session(self):
        session = UtilsDataBase().conn_mysql(db_url=self.db_url, db_port=self.db_port, db_base=self.db_base, db_user=self.db_user, db_pw=self.db_pw)
        return session

    @allure.step("查询表：events")
    def select_events(self, eventid=None, objectid=None):
        session = self.db_session()
        sql = DataEvents().select_all_from_allKeys(session=session, eventid=eventid, objectid=objectid)
        return sql

    @allure.step("查询表：problem")
    def select_problem(self, eventid=None):
        session = self.db_session()
        sql = DataProblem().select_all_from_allKeys(session=session, eventid=eventid)
        return sql

    @allure.step("查询表：items")
    def select_items(self, hostid=None):
        session = self.db_session()
        sql = DataItems().select_all_from_allKeys(session=session, hostid=hostid)
        return sql

    @allure.step("查询表：items")
    def select_functions(self, itemid=None):
        session = self.db_session()
        sql = DataFunctions().select_all_from_allKeys(session=session, itemid=itemid)
        return sql

    @allure.step("新增表数据：events")
    def insert_events(self, eventid=None, source=None, _object=None, objectid=None, clock=None, value=None, acknowledged=None,
                      ns=None, name=None, severity=None):
        session = self.db_session()
        sql = DataEvents().insert_one(session, eventid=eventid, source=source, _object=_object, objectid=objectid, clock=clock,
                                      value=value, acknowledged=acknowledged, ns=ns, name=name, severity=severity)
        DataProblem().insert_one(session, eventid=eventid, source=source, _object=_object, objectid=objectid, clock=clock,
                                 r_eventid=None, r_clock=0, r_ns=0, correlationid=0, userid=0,
                                 acknowledged=acknowledged, ns=ns, name=name, severity=severity)
        return sql

    @allure.step("断言返回结果：校验排序")
    def check_sortfield(self, response, possible):
        result = UtilsResponse().get_result(response=response)
        UtilsResponse().check_sort(_list=result, key="eventid", possible=possible)

    @allure.step("断言返回结果：校验返回数据的数量")
    def check_num(self, response, num):
        result = UtilsResponse().get_result(response=response)
        assert len(result) == num

    @allure.step("断言返回结果")
    def check_code(self, response, code):
        _code = UtilsResponse().get_code(response=response)
        assert _code == code

    @allure.step("断言返回结果数据")
    def check_msg(self, response, msg):
        _msg = UtilsResponse().get_msg(response=response)
        assert _msg == msg

    @allure.step("调用接口：host.create")
    def host_create(self, host=None, name=None, description=None, groupids=None, interfaces=None, tags=None, templateids=None, macros=None,
                    inventory=None, status=None, inventory_mode=None):
        api = HostCreate(_host=self.host)
        api.host = host
        api.name = name
        api.description = description
        api.groupids = groupids
        api.interfaces = interfaces
        api.tags = tags
        api.templateids = templateids
        api.macros = macros
        api.inventory = inventory
        api.status = status
        api.inventory_mode = inventory_mode
        api.tls_connect = 1
        api.tls_accept = 1
        api.tls_psk_identity = ""
        api.tls_psk = ""
        api.get_response()
        return api.response

    @allure.step("创建测试数据")
    def case_create_host(self, num):
        host = self.base_host_name + num
        description = self.base_description + num
        interfaces = {
            "type": 2,
            "main": 1,
            "useip": 1,
            "ip": self.base_ip,
            "dns": "",
            "port": self.base_port,
            "bulk": 1
        }
        response = self.host_create(host=host, description=description, groupids=[self.base_groupid],
                                    interfaces=[interfaces], status=0, templateids=[self.base_type_snmp],
                                    macros=[{
                                        "macro": "{$SNMP_COMMUNITY}",
                                        "value": "public"
                                    }])
        self.check_code(response=response, code=0)
        self.hostid = UtilsResponse().get_result(response=response)["hostids"][0]

        sql_items = self.select_items(hostid=self.hostid)
        self.triggers_ids = []
        for x, y in enumerate(sql_items):
            sql_functions = self.select_functions(itemid=y.itemid)
            for q, w in enumerate(sql_functions):
                self.triggers_ids.append(w.triggerid)

        return self.hostid

    @allure.step("创建测试数据")
    def case_create(self, num, objectid, acknowledged):
        self.eventid = self.base_eventid + int(num)
        self.name = self.base_name + num
        self.insert_events(eventid=self.eventid, source=0, _object=0, objectid=objectid, clock=0, value=1,
                           acknowledged=acknowledged, ns=int(time.time()),
                           name=self.name, severity=0)
        return self.eventid

    @allure.step("校验告警状态")
    def check_sql(self, eventid, action):
        time.sleep(30)

        if action == 1:
            sql = self.select_events(eventid=eventid)
            assert sql != []
            for x, y in enumerate(sql):
                assert y.acknowledged == 0
                assert x == 0

            sql = self.select_problem(eventid=eventid)
            assert sql != []
            for x, y in enumerate(sql):
                assert y.acknowledged == 0
                assert y.r_clock != 0
                assert x == 0
        else:
            sql = self.select_events(eventid=eventid)
            assert sql != []
            for x, y in enumerate(sql):
                assert y.acknowledged == 1
                assert x == 0

            sql = self.select_problem(eventid=eventid)
            assert sql != []
            for x, y in enumerate(sql):
                assert y.acknowledged == 1
                assert y.r_clock == 0
                assert x == 0

    @allure.title("problem.acknowledge：action为空,返回异常")
    @allure.story("告警忽略/关闭：action为空,返回异常")
    @allure.severity("blocker")
    def test_case_01(self):
        response = self.problem_acknowledge()
        self.check_code(response=response, code=100)
        self.check_msg(response=response, msg="action 值错误")

    @allure.title("problem.acknowledge：eventids为空,返回异常")
    @allure.story("告警忽略/关闭：eventids为空,返回异常")
    def test_case_02(self):
        response = self.problem_acknowledge(action=1)
        self.check_code(response=response, code=100)
        # self.check_msg(response=response, msg="[eventids]不能为空")
        # self.check_msg(response=response, msg="[eventids]must not be empty")

    @allure.title("problem.acknowledge：action=1 关闭一个告警")
    @allure.story("告警忽略/关闭：action=1 关闭一个告警")
    def test_case_03(self):
        self.case_create_host(num="03")
        self.case_create(num="03", objectid=self.triggers_ids[0], acknowledged=0)
        response = self.problem_acknowledge(eventids=[self.eventid], action=1)
        self.check_code(response=response, code=0)
        self.check_sql(eventid=self.eventid, action=1)

    @allure.title("problem.acknowledge：action=2 忽略一个告警")
    @allure.story("告警忽略/关闭：action=2 忽略一个告警")
    def test_case_04(self):
        self.case_create_host(num="04")
        self.case_create(num="04", objectid=self.triggers_ids[0], acknowledged=0)
        response = self.problem_acknowledge(eventids=[self.eventid], action=2)
        self.check_code(response=response, code=0)
        self.check_sql(eventid=self.eventid, action=2)

    @allure.title("problem.acknowledge：action=1 关闭多个告警")
    @allure.story("告警忽略/关闭：action=1 关闭多个告警")
    def test_case_05(self):
        self.case_create_host(num="05")
        eventid_1 = self.case_create(num="051", objectid=self.triggers_ids[0], acknowledged=0)
        eventid_2 = self.case_create(num="052", objectid=self.triggers_ids[1], acknowledged=0)
        eventid_3 = self.case_create(num="053", objectid=self.triggers_ids[2], acknowledged=0)
        response = self.problem_acknowledge(eventids=[eventid_1, eventid_2, eventid_3], action=1)
        self.check_code(response=response, code=0)
        self.check_sql(eventid=eventid_1, action=1)
        self.check_sql(eventid=eventid_2, action=1)
        self.check_sql(eventid=eventid_3, action=1)

    @allure.title("problem.acknowledge：action=2 忽略多个告警")
    @allure.story("告警忽略/关闭：action=2 忽略多个告警")
    def test_case_06(self):
        self.case_create_host(num="06")
        eventid_1 = self.case_create(num="061", objectid=self.triggers_ids[0], acknowledged=0)
        eventid_2 = self.case_create(num="062", objectid=self.triggers_ids[1], acknowledged=0)
        eventid_3 = self.case_create(num="063", objectid=self.triggers_ids[2], acknowledged=0)
        response = self.problem_acknowledge(eventids=[eventid_1, eventid_2, eventid_3], action=2)
        self.check_code(response=response, code=0)
        self.check_sql(eventid=eventid_1, action=2)
        self.check_sql(eventid=eventid_2, action=2)
        self.check_sql(eventid=eventid_3, action=2)


if __name__ == "__main__":
    from WorkUtils.UtilsPyTest import UtilsPyTest
    from WorkUtils.UtilsCmd import UtilsCmd

    import os

    # 执行自动化测试用例
    case_info = os.path.split(__file__)
    case = UtilsCmd().pytest_cmd()
    r = UtilsPyTest(case=case, case_info=case_info)
    r.run_main()

    # a = TestProblemAcknowledge()
    # a.setup_class()
    # a.test_case_03()
