Beispiel #1
0
    def get(self):
        cmd = '/usr/bin/python3.7 /data/soft/Qa_quality/scripts/killallprocess.py'
        print(cmd)

        def ssh(ip, username, password, cmd):
            try:
                transport = paramiko.Transport((ip, 9922))
                transport.connect(username=username, password=password)
                ssh = paramiko.SSHClient()
                ssh._transport = transport
                stdin, stdout, stderr = ssh.exec_command(
                    cmd, get_pty=True)  # 支持多条命令拼接
                print('执行了')

                line = stdout.readline()
                print(line)
            except Exception as e:
                print(e)

        ssh('10.55.142.248', 'root', 'fudao@123456', cmd)

        #操作日志存放
        date = time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime())
        operation_content = username + '/终止所有进程/' + date
        print(operation_content)
        except_log().putlog(1, 1, operation_content, 1, 2)

        j_data = {'msg': '终止所有压测脚本成功', 'statusCode': 200}
        return jsonify(j_data)
Beispiel #2
0
        def ssh2(ip, username, password, cmd, filename):
            try:
                uid = cmd.split()[14]
                tree_id = cmd.split()[16]
                treename = cmd.split()[18]
                transport = paramiko.Transport((ip, 9922))
                transport.connect(username=username, password=password)
                ssh = paramiko.SSHClient()
                ssh._transport = transport
                stdin, stdout, stderr = ssh.exec_command(
                    cmd, get_pty=True)  # 支持多条命令拼接
                print('执行了')

                #日志存放骚操作
                batch_log = '/data/soft/Quality_Platform/logs/{Filename}.log'.format(
                    Filename=filename)
                Results_log = open(batch_log, 'w+', encoding='utf-8')
                while True:
                    line = stdout.readline()
                    #line = line.replace('\x00','')
                    print(line, file=open(batch_log, 'w+', encoding='utf-8'))
                    print(line)
                    Results_log.write(line)

                    if not line:
                        Results_log.close()
                        break
                # 操作成功并失败上传日志存库
                operation_content = '执行脚本完毕:' + treename
                operation_result = 1
                except_log().putlog(tree_id, uid, operation_content,
                                    operation_result, 2)
                print('远程命令执行完毕')

            except Exception as e:
                #操作失败并失败上传日志存库
                operation_content = '执行脚本失败:' + treename
                operation_result = 2
                except_log().putlog(tree_id, uid, operation_content,
                                    operation_result, 2)
                print('远程命令执行失败.', e)
                error = '500'
                print('远程命令执行失败')

            transport.close()
Beispiel #3
0
    def delete(self):
        # 获取请求的json数据,返回字典
        req_dict = request.get_json()
        id = req_dict.get("id")  # 文件名id

        project_type = req_dict.get("project_type")
        # tree_id = req_dict.get("tree_id")
        uid = req_dict.get("uid")
        operation_content = req_dict.get("operation_content")
        operation_content =  "删除树:%s"%operation_content

        # 创建空列表 存储与id相同的父id
        tree_storagelist = []

        # 判断目录下面是否存在脚本或者目录,只能删除最低级
        try:
            # 查看是否有父id中是否存在被删除数据,存在证明不是末节分支
            tree_pidlist = db.session.query(db_mysql.Tree).filter(db_mysql.Tree.pid == id)
            db.session.commit()
            for row in tree_pidlist:
                tree_storagelist.append(row.id)

        except IntegrityError as e:
            # 数据库操作错误后的回滚
            db.session.rollback()
            current_app.logger.error(e)
            db.session.close()
            except_log().putlog(id, uid, operation_content, 2, project_type)
            return jsonify(statusCode=RET.DATAERR, msg="查询父id失败")
        if len(tree_storagelist) > 0:
            except_log().putlog(id, uid, operation_content, 2, project_type)
            return jsonify(statusCode=RET.OK, msg="请先删除子目录")
        else:
            # 删除文件
            try:
                tree_deleteid = db.session.query(db_mysql.Tree).filter(db_mysql.Tree.id == id).delete()
                db.session.commit()
            except IntegrityError as e:
                # 数据库操作错误后的回滚
                db.session.rollback()
                current_app.logger.error(e)
                db.session.close()
                except_log().putlog(id, uid, operation_content, 2, project_type)
                return jsonify(statusCode=RET.DATAERR, msg="删除失败")
            db.session.close()
            except_log().putlog(id, uid, operation_content, 1, project_type)
            return jsonify(statusCode=RET.OK, msg="删除成功")
Beispiel #4
0
        def type_post():
            # 本机测试脚本路径
            file = glob.glob(
                '/data/soft/Quality_Platform/scripts/template/qa-post-test.py')
            # 定义自动生成脚本函数
            for one_polling in file:
                date = time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime())
                new_file = "/data/soft/Quality_Platform/scripts/singlescripts/{username}-qa-test-{date}.py".format(
                    date=date, username=username)
                filename = '{username}-qa-test-{date}.py'.format(
                    date=date, username=username)
                put_file = "/home/wenba/xz/automation/snail/scripts/" + "{username}-qa-test-{date}.py".format(
                    date=date, username=username)
                print('脚本生成', new_file)

                f1 = open(new_file, 'w+')
                f = open(one_polling, 'r+')
                all_lines = f.readlines()
                f.seek(0)
                for line in all_lines:
                    line = line.replace('hostip', hostip)
                    line = line.replace('hostpath', hostpath)
                    line = line.replace('customcs', parameter)
                    f1.write(line)
                f.close()
                f1.close()
                cf = str(os.path.exists(new_file))
                df = os.path.getsize(new_file)
                try:
                    if (cf == 'True' and df > 0):
                        cg = "200"
                        print(cg)
                        # 上传生成脚本
                    def ssh1(ip, username, password, file):
                        try:
                            transport = paramiko.Transport((ip, 9922))
                            transport.connect(username=username,
                                              password=password)
                            sftp = paramiko.SFTPClient.from_transport(
                                transport)
                            ssh = paramiko.SSHClient()
                            ssh._transport = transport
                            sftp.put(file, put_file)
                            stdin, stdout, stderr = ssh.exec_command(
                                "chmod a+x {put_file}".format(
                                    put_file=put_file))
                            transport.close()
                        except:
                            error = "上传脚本失败,请检查!"
                            print('上传脚本失败')
                            j_data = {"msg": error, "statusCode": 200}
                            return jsonify(j_data)

                    ssh1('10.55.142.248', 'root', 'fudao@123456', new_file)

                    #操作成功日志存库
                    excelog['operation_result'] = 1
                    except_log().putlog(excelog)
                    return filename

                except:
                    print('脚本执行失败,请检查.')

                    # 操作失败日志存库
                    excelog['operation_result'] = 2
                    except_log().putlog(excelog)
                    error = '脚本生成失败,请检查!'
                    return '500'
Beispiel #5
0
    def post(self):

        # 获取请求的json数据,返回字典
        req_dict = request.get_json()
        filename = req_dict.get("filename")  # 文件名
        pid = req_dict.get("pid")  # 父id
        file_type = req_dict.get("file_type")  # 文件 类型 1 为文件 2 为脚本 3 为 全链路脚本
        project_type = req_dict.get("project_type")  # 项目类型 2 为压测中心 3 为用例中心 4 为日志管理
        uid = req_dict.get("uid")  # 用户id

        operation_content = req_dict.get("operation_content") #用户操作内容

        operation_content = "新增树父节点:%s"%operation_content

        # putlog(self, tree_id, uid, operation_content, operation_result, project_type)
        # 判断文件名是否传值或者为空
        if filename is None:
            except_log().putlog(pid, uid, operation_content, 2,project_type)
            return jsonify(statusCode=RET.PARAMERR, msg="文件名字为必填项")
        elif filename == "":
            except_log().putlog(pid, uid, operation_content, 2,project_type)
            return jsonify(statusCode=RET.PARAMERR, msg="文件名字不能为空")

        # 判断父id是否传值或者为空
        if pid is None:
            except_log().putlog(pid, uid, operation_content, 2,project_type)
            return jsonify(statusCode=RET.PARAMERR, msg="父id为必填项")
        elif pid == "":
            except_log().putlog(pid, uid, operation_content, 2,project_type)
            return jsonify(statusCode=RET.PARAMERR, msg="父id不能为空")

        # 判断项目id是否传值或者为空
        if project_type is None:
            except_log().putlog(pid, uid, operation_content, 2,project_type)
            return jsonify(statusCode=RET.PARAMERR, msg="项目id为必填项")
        elif project_type == "":
            except_log().putlog(pid, uid, operation_content, 2,project_type)
            return jsonify(statusCode=RET.PARAMERR, msg="项目id不能为空")

        # 判断文件类型是否传值或者为空
        if file_type is None:
            except_log().putlog(pid, uid, operation_content, 2,project_type)
            return jsonify(statusCode=RET.PARAMERR, msg="文件类型为必填项")

        # 判断用户uid是否传值或者为空
        if uid is None:
            except_log().putlog(pid, uid, operation_content, 2,project_type)
            return jsonify(statusCode=RET.PARAMERR, msg="uid为必填项")

        try:
            try:
                treedata = db_mysql.Tree(filename=filename, pid=pid, file_type=file_type, uid=uid,project_type=project_type)
                db.session.add(treedata)
                db.session.flush()
                db.session.commit()
                zzid = treedata.id
            finally:
                db.session.close()

        except IntegrityError as e:
            # 数据库操作错误后的回滚
            db.session.rollback()
            current_app.logger.error(e)
            db.session.close()
            except_log().putlog(pid, uid, operation_content, 2,project_type)
            return jsonify(statusCode=RET.DATAERR, msg="数据创建失败")
        db.session.close()

        j_data = {
            # "zzid" : zzid ,
            "statusstatusCode" : RET.OK,
            "msg" : "创建成功"
        }
        # print(zzid)
        except_log().putlog(pid, uid, operation_content, 1,project_type)
        return jsonify(statusCode = RET.OK,msg = "创建成功",zzid = zzid)
Beispiel #6
0
    def put(self):
        # 获取请求的json数据,返回字典
        req_dict = request.get_json()

        id = req_dict.get("id")  # 文件名id
        file_type = req_dict.get("file_type")  # 文件 类型 1 为文件 2 为脚本 3为全链路脚本
        filename = req_dict.get("filename")  # 文件名
        # meth = req_dict.get("meth")  # 请求类型 post get
        # sc_ip = req_dict.get("sc_ip")  # 脚本ip
        # sc_path = req_dict.get("sc_path")  # 脚本路径
        sc_praameter = req_dict.get("sc_praameter")  # 脚本参数
        sc_name = req_dict.get("sc_name")  # 脚本名称
        concurrency = req_dict.get("concurrency")  # 并发数
        strategy = req_dict.get("strategy")  # 并发策略
        con_praameter = req_dict.get("con_praameter")  # 并发参数
        # test_env = req_dict.get("test_env")  # 压测环境  测试:0 预发:1 线上:2
        link_parameters = req_dict.get("link_parameters")  # 全链路参数

        project_type = req_dict.get("project_type")
        # tree_id = req_dict.get("tree_id")
        # uid = req_dict.get("uid")
        operation_content = req_dict.get("operation_content")
        operation_content =  "修改树:%s"%operation_content

        Permission_parameters = req_dict.get("Permission_parameters")
        uid = Permission_parameters["uid"]


        if id is None:
            except_log().putlog(id, uid, operation_content, 2,project_type)
            return jsonify(statusCode=RET.PARAMERR, msg="脚本id为必填项")
        # file_type == 1 为文件夹类型只能修改文件夹名称
        if file_type == 1 or file_type == 6 or file_type == 7:
            # 判断文件名是否传值或者为空
            if filename is None:
                except_log().putlog(id, uid, operation_content, 2, project_type)
                return jsonify(statusCode=RET.PARAMERR, msg="文件名字为必填项")
            elif filename == "":
                except_log().putlog(id, uid, operation_content, 2, project_type)
                return jsonify(statusCode=RET.PARAMERR, msg="文件名字不能为空")
            try:
                try:
                    user_list = db.session.query(db_mysql.Tree).filter(db_mysql.Tree.id == id).update(
                        {"filename": filename})
                    db.session.commit()
                finally:
                    db.session.close()
            except IntegrityError as e:
                # 数据库操作错误后的回滚
                db.session.rollback()
                current_app.logger.error(e)
                db.session.close()
                except_log().putlog(id, uid, operation_content, 2, project_type)
                return jsonify(statusCode=RET.DATAERR, msg="修改失败")
        # file_type == 2 为脚本类型,可以修改脚本名,脚本ip,脚本路径,脚本参数
        elif file_type == 2 or file_type == 3 or file_type == 4 or file_type == 5 or file_type == 8 or file_type == 9:


            #判断链路参数是否传值
            if link_parameters is None:
                except_log().putlog(id, uid, operation_content, 2, project_type)
                return jsonify(statusCode=RET.PARAMERR, msg="链路参数为必填项")
            elif link_parameters == "":
                except_log().putlog(id, uid, operation_content, 2, project_type)
                return jsonify(statusCode=RET.PARAMERR, msg="链路参数不能为空")

            try:
                try:
                    user_list = db.session.query(db_mysql.Tree).filter(db_mysql.Tree.id == id).update(
                        {
                            "sc_name": sc_name,
                            "concurrency": concurrency,
                            "strategy": strategy,
                            "con_praameter": con_praameter,
                            "link_parameters":link_parameters
                        })
                    db.session.commit()
                finally:
                    db.session.close()
            except IntegrityError as e:
                # 数据库操作错误后的回滚
                db.session.rollback()
                current_app.logger.error(e)
                db.session.close()

                except_log().putlog(id, uid, operation_content, 2, project_type)
                return jsonify(statusCode=RET.DATAERR, msg="修改失败")
        except_log().putlog(id, uid, operation_content, 1, project_type)
        return jsonify(statusCode=RET.OK, msg="修改成功")
Beispiel #7
0
    def post(self):
        # 获取请求的json数据, 从列表中取字典的值
        req_dic = request.get_json()
        case_id = req_dic.get("case_id")  # 用例id
        uid = req_dic.get("uid")  # 用户id
        role = req_dic.get("role")  # 用户角色
        test_result = req_dic.get("test_result")  # 0:提交测试,1:测试通过,2:测试不通过
        tree_id = req_dic.get("tree_id")  # 父id为0的项目id
        operation_content = req_dic.get("operation_content")  # 操作内容

        # 开发身份
        if role == 0:
            # DingTalk("流程提醒:提交测试")
            return jsonify(statusCode=RET.OK, msg="提交成功")

        # 测试身份
        elif role == 1:
            if test_result == 1:
                # DingTalk("流程提醒:测试通过")
                try:
                    # 查询用例的所有条数
                    case_all = db.session.query(func.count(db_mysql.TestCase.test_result.is_(None))). \
                        filter(db_mysql.TestCase.case_id == case_id).scalar()
                    # 查询用例pass的条数
                    case_pass = db.session.query(func.count(db_mysql.TestCase.test_result.is_(None))).\
                        filter(db_mysql.TestCase.case_id == case_id, db_mysql.TestCase.test_result == 0).scalar()
                    # 查询用例fail的条数
                    case_fail = db.session.query(func.count(db_mysql.TestCase.test_result.is_(None))).\
                        filter(db_mysql.TestCase.case_id == case_id, db_mysql.TestCase.test_result == 1).scalar()
                    # 查询用例block的条数
                    case_block = db.session.query(func.count(db_mysql.TestCase.test_result.is_(None))).\
                        filter(db_mysql.TestCase.case_id == case_id, db_mysql.TestCase.test_result == 2).scalar()
                    # 查询用例执行为空的条数
                    case_none = db.session.query(func.count(db_mysql.TestCase.test_result.is_(None))).\
                        filter(db_mysql.TestCase.case_id == case_id, db_mysql.TestCase.test_result.is_(None)).scalar()
                    # 根据case_id查询出对应轮次数据
                    report_val = db.session.query(db_mysql.TestReport).filter(
                        db_mysql.TestReport.case_id == case_id)

                    db.session.commit()

                except IntegrityError as e:

                    # 数据库操作错误后的回滚
                    db.session.rollback()
                    current_app.logger.error(e)
                    return jsonify(statusCode=RET.DATAERR, msg="查询失败")
                db.session.close()

                # 取出case_id对应的轮次数,存入report_list
                report_list = []
                for val in report_val:
                    report_list.append(val.test_rounds)
                # 如果report_list为空,count默认为1,否则取列表里最后一位数+1
                if len(report_list) == 0:
                    count = 1
                else:
                    count = report_list[-1] + 1

                # return case_all, case_pass, case_fail, case_block, case_none
                # 将用例对应的统计数据插入数据库
                try:
                    db.session.add(
                        db_mysql.TestReport(case_id=case_id,
                                            test_rounds=count,
                                            case_number=case_all,
                                            case_pass=case_pass,
                                            case_fail=case_fail,
                                            case_block=case_block,
                                            no_test=case_none,
                                            uid=uid,
                                            test_result=test_result))
                    db.session.commit()

                except IntegrityError as e:
                    # 数据库操作错误后的回滚
                    db.session.rollback()
                    current_app.logger.error(e)

                    # 增加用户操作日志
                    operation_content = "测试通过:%s" % operation_content

                    except_log().putlog(tree_id, uid, operation_content, 2, 3)

                    return jsonify(statusCode=RET.DATAERR, msg="数据创建失败")
                db.session.close()

                # 增加用户操作日志
                operation_content = "测试通过:%s" % operation_content

                except_log().putlog(tree_id, uid, operation_content, 1, 3)

                return jsonify(statusCode=RET.OK, msg="创建成功")

            elif test_result == 2:
                # DingTalk("流程提醒:测试不通过")
                try:
                    # 查询用例的所有条数
                    case_all = db.session.query(func.count(db_mysql.TestCase.test_result.is_(None))). \
                        filter(db_mysql.TestCase.case_id == case_id).scalar()
                    # 查询用例pass的条数
                    case_pass = db.session.query(func.count(db_mysql.TestCase.test_result.is_(None))). \
                        filter(db_mysql.TestCase.case_id == case_id, db_mysql.TestCase.test_result == 0).scalar()
                    # 查询用例fail的条数
                    case_fail = db.session.query(func.count(db_mysql.TestCase.test_result.is_(None))). \
                        filter(db_mysql.TestCase.case_id == case_id, db_mysql.TestCase.test_result == 1).scalar()
                    # 查询用例block的条数
                    case_block = db.session.query(func.count(db_mysql.TestCase.test_result.is_(None))). \
                        filter(db_mysql.TestCase.case_id == case_id, db_mysql.TestCase.test_result == 2).scalar()
                    # 查询用例执行为空的条数
                    case_none = db.session.query(func.count(db_mysql.TestCase.test_result.is_(None))). \
                        filter(db_mysql.TestCase.case_id == case_id, db_mysql.TestCase.test_result.is_(None)).scalar()
                    # 根据case_id查询出对应轮次数据
                    report_val = db.session.query(db_mysql.TestReport).filter(
                        db_mysql.TestReport.case_id == case_id)

                    db.session.commit()

                except IntegrityError as e:

                    # 数据库操作错误后的回滚
                    db.session.rollback()
                    current_app.logger.error(e)
                    return jsonify(statusCode=RET.DATAERR, msg="查询失败")
                db.session.close()

                # 取出case_id对应的轮次数,存入report_list
                report_list = []
                for val in report_val:
                    report_list.append(val.test_rounds)
                # 如果report_list为空,count默认为1,否则取列表里最后一位数+1
                if len(report_list) == 0:
                    count = 1
                else:
                    count = report_list[-1] + 1

                # return case_all, case_pass, case_fail, case_block, case_none
                # 将用例对应的统计数据插入数据库
                try:
                    db.session.add(
                        db_mysql.TestReport(case_id=case_id,
                                            test_rounds=count,
                                            case_number=case_all,
                                            case_pass=case_pass,
                                            case_fail=case_fail,
                                            case_block=case_block,
                                            no_test=case_none,
                                            uid=uid,
                                            test_result=test_result))
                    db.session.commit()

                except IntegrityError as e:
                    # 数据库操作错误后的回滚
                    db.session.rollback()
                    current_app.logger.error(e)

                    # 增加用户操作日志
                    operation_content = "测试不通过:%s" % operation_content

                    except_log().putlog(tree_id, uid, operation_content, 2, 3)

                    return jsonify(statusCode=RET.DATAERR, msg="数据创建失败")
                db.session.close()

                # 增加用户操作日志
                operation_content = "测试不通过:%s" % operation_content

                except_log().putlog(tree_id, uid, operation_content, 1, 3)

                return jsonify(statusCode=RET.OK, msg="创建成功")

        # 产品身份
        elif role == 2:
            if test_result == 1:
                # DingTalk("流程提醒:产品验收通过")
                return jsonify(statusCode=RET.OK, msg="提交成功")
            elif test_result == 2:
                # DingTalk("流程提醒:产品验收不通过")
                return jsonify(statusCode=RET.OK, msg="提交成功")
    def post(self):
        # 获取请求的json数据,返回字典
        try:
            tfdata = request.get_json()
            tree_id = tfdata.get("tree_id")
            uid = tfdata.get("uid")
            test_result = tfdata.get("test_result")

            # project_type = tfdata.get("project_type")
            operation_content = tfdata.get("operation_content")
            operation_content = "脑图报告:%s" % operation_content

        except Exception as e:
            return jsonify(statusCode=RET.PARAMERR, msg="请查看是否传入json格式的参数")

        # 判断tree_id是否传值或者为空
        if tree_id is None:
            except_log().putlog(tree_id, uid, operation_content, 2, 3)
            return jsonify(statusCode=RET.PARAMERR, msg="tree_id为必填项")
        elif tree_id == "":
            except_log().putlog(tree_id, uid, operation_content, 2, 3)
            return jsonify(statusCode=RET.PARAMERR, msg="tree_id不能为空")

        # 判断uid是否传值或者为空
        if uid is None:
            except_log().putlog(tree_id, uid, operation_content, 2, 3)
            return jsonify(statusCode=RET.PARAMERR, msg="uid为必填项")
        elif uid == "":
            except_log().putlog(tree_id, uid, operation_content, 2, 3)
            return jsonify(statusCode=RET.PARAMERR, msg="uid不能为空")

        # 判断type是否传值或者为空
        if type is None:
            except_log().putlog(tree_id, uid, operation_content, 2, 3)
            return jsonify(statusCode=RET.PARAMERR, msg="type为必填项")
        elif type == "":
            except_log().putlog(tree_id, uid, operation_content, 2, 3)
            return jsonify(statusCode=RET.PARAMERR, msg="type不能为空")

        try:
            try:
                # user_list = db.session.query(db_mysql.Tree).filter(db_mysql.Tree.uid == uid)
                user_list = db.session.query(db_mysql.Brainmap).filter(
                    db_mysql.Brainmap.tree_id == tree_id)
                db.session.commit()
            finally:
                db.session.close()
        except IntegrityError as e:

            # 数据库操作错误后的回滚
            db.session.rollback()
            current_app.logger.error(e)
            db.session.close()
            except_log().putlog(tree_id, uid, operation_content, 2, 3)
            return jsonify(statusCode=RET.DATAERR, msg="查询失败")

        check_list = []
        for raw in user_list:
            # check_dic = {}
            # check_dic["children"] = []
            # check_dic["id"] = raw.id
            # check_dic["pid"] = raw.pid
            # check_dic["brainmapname"] = raw.brainmapname
            # check_dic["rdstatus"] = raw.rdstatus
            # check_dic["qastatus"] = raw.qastatus
            # check_dic["tree_id"] = raw.tree_id
            # check_dic["uid"] = raw.uid
            check_list.append(raw.qastatus)

        # 用例条数
        case_number = 0
        # 用例通过数
        case_pass = 0
        # 不通过用例数
        case_fail = 0
        # 阻碍用例数
        case_block = 0
        # 为提测用例数
        no_test = 0
        # 测试轮次
        test_rounds = 1

        for i in check_list:
            if i != None:
                case_number += 1
                if int(i) == 1:
                    case_pass += 1
                elif int(i) == 2:
                    case_fail += 1
                elif int(i) == 3:
                    case_block += 1
            elif i == None:
                no_test += 1
        try:
            try:
                re_list = db.session.query(db_mysql.TestReport).filter(
                    db_mysql.TestReport.case_id == tree_id)
                db.session.commit()
            finally:
                db.session.close()
        except IntegrityError as e:
            # 数据库操作错误后的回滚
            db.session.rollback()
            current_app.logger.error(e)
            db.session.close()
            except_log().putlog(tree_id, uid, operation_content, 2, 3)
            return jsonify(statusCode=RET.DATAERR, msg="查询失败")

        if re_list:
            roli = []
            # 循环list 轮次+1
            for a in re_list:
                roli.append(a.test_rounds)
            if roli:
                test_rounds = max(roli) + 1
        try:
            try:
                db.session.add(
                    db_mysql.TestReport(case_id=tree_id,
                                        test_rounds=test_rounds,
                                        case_number=case_number,
                                        case_pass=case_pass,
                                        case_fail=case_fail,
                                        case_block=case_block,
                                        no_test=no_test,
                                        uid=uid,
                                        test_result=test_result))
                db.session.commit()
            finally:
                db.session.close()
        except IntegrityError as e:
            # 数据库操作错误后的回滚
            db.session.rollback()
            current_app.logger.error(e)
            db.session.close()
            except_log().putlog(tree_id, uid, operation_content, 2, 3)
            return jsonify(statusCode=RET.DATAERR, msg="添加失败")
        except_log().putlog(tree_id, uid, operation_content, 1, 3)
        return jsonify(statusCode=RET.OK, msg="添加成功")