Ejemplo n.º 1
0
class TreeView(APIView):
    """
    树形结构操作
    """

    # authentication_classes = [OnlyGetAuthenticator, ]

    @method_decorator(request_log(level='INFO'))
    def get(self, request, **kwargs):
        """
        返回树形结构
        当前最带节点ID
        """

        try:
            tree_type = request.query_params['type']
            tree = models.Relation.objects.get(project__id=kwargs['pk'],
                                               type=tree_type)
        except KeyError:
            return Response(response.KEY_MISS)

        except ObjectDoesNotExist:
            return Response(response.SYSTEM_ERROR)

        body = eval(tree.tree)  # list
        tree = {
            "tree": body,
            "id": tree.id,
            "success": True,
            "max": get_tree_max_id(body)
        }
        return Response(tree)

    @method_decorator(request_log(level='INFO'))
    def patch(self, request, **kwargs):
        """
        修改树形结构,ID不能重复
        """
        try:
            body = request.data['body']
            mode = request.data['mode']

            relation = models.Relation.objects.get(id=kwargs['pk'])
            relation.tree = body
            relation.save()

        except KeyError:
            return Response(response.KEY_MISS)

        except ObjectDoesNotExist:
            return Response(response.SYSTEM_ERROR)

        #  mode -> True remove node
        if mode:
            prepare.tree_end(request.data, relation.project)

        response.TREE_UPDATE_SUCCESS['tree'] = body
        response.TREE_UPDATE_SUCCESS['max'] = get_tree_max_id(body)

        return Response(response.TREE_UPDATE_SUCCESS)
Ejemplo n.º 2
0
class HostIPView(viewsets.ModelViewSet):
    """
    域名管理视图
    create: 传id时认为是在复制,不传时在新建
    """
    pagination_class = pagination.MyPageNumberPagination
    permission_classes = (DjangoModelPermissions, IsBelongToProject)

    def get_queryset(self):
        return models.HostIP.objects.filter(
            project__id=self.request.query_params['project']).order_by(
                '-update_time')

    def get_serializer_class(self):
        if self.action in ['create', 'update', 'partial_update']:
            return serializers.HostIPSerializerPost
        else:
            return serializers.HostIPSerializerList

    @method_decorator(request_log(level='INFO'))
    def create(self, request, *args, **kwargs):
        if 'id' in request.data.keys():
            pk = request.data['id']
            name = request.data['name']

            host_info = self.get_queryset().get(id=pk)
            # models.HostIP.objects.get(id=pk)
            request_data = {
                "name": name,
                "hostInfo": json.loads(host_info.hostInfo),
                "project": host_info.project_id,
                "base_url": host_info.base_url
            }
        else:
            request_data = request.data
        serializer = self.get_serializer(data=request_data)

        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data,
                        status=status.HTTP_201_CREATED,
                        headers=headers)

    @method_decorator(request_log(level='INFO'))
    def destroy(self, request, *args, **kwargs):
        if kwargs.get('pk') and int(kwargs['pk']) != -1:
            instance = self.get_object()
            self.perform_destroy(instance)
        elif request.data:
            for content in request.data:
                self.kwargs['pk'] = content['id']
                instance = self.get_object()
                self.perform_destroy(instance)
        return Response(status=status.HTTP_204_NO_CONTENT)
Ejemplo n.º 3
0
class DebugTalkView(GenericViewSet):
    """
    DebugTalk update
    """
    # authentication_classes = [OnlyGetAuthenticator, ]
    serializer_class = serializers.DebugTalkSerializer

    @method_decorator(request_log(level='INFO'))
    def debugtalk(self, request, **kwargs):
        """
        得到debugtalk code
        """
        pk = kwargs.pop('pk')
        try:
            queryset = models.Debugtalk.objects.get(project__id=pk)
        except ObjectDoesNotExist:
            return Response(response.DEBUGTALK_NOT_EXISTS)

        serializer = self.get_serializer(queryset, many=False)

        return Response(serializer.data)

    @method_decorator(request_log(level='INFO'))
    def update(self, request):
        """
        编辑debugtalk.py 代码并保存
        """
        pk = request.data['id']
        try:
            models.Debugtalk.objects.filter(id=pk). \
                update(code=request.data['code'], updater=request.user.username)

        except ObjectDoesNotExist:
            return Response(response.SYSTEM_ERROR)

        return Response(response.DEBUGTALK_UPDATE_SUCCESS)

    @method_decorator(request_log(level='INFO'))
    def run(self, request):
        try:
            code = request.data["code"]
        except KeyError:
            return Response(response.KEY_MISS)
        debug = DebugCode(code)
        debug.run()
        resp = {
            "msg": debug.resp,
            "success": True,
            "code": "0001"
        }
        return Response(resp)
Ejemplo n.º 4
0
class PycodeView(ModelViewSet):
    """
    驱动代码模块
    """
    serializer_class = serializers.PycodeSerializer
    pagination_class = pagination.MyPageNumberPagination
    permission_classes = (DjangoModelPermissions, IsBelongToProject)

    def get_queryset(self):
        project = self.request.query_params["project"]
        queryset = models.Pycode.objects.filter(
            project_id=project).order_by('-update_time')
        if self.action == 'list':
            queryset = queryset.filter(
                name__contains=self.request.query_params["search"])
        return queryset

    @method_decorator(request_log(level='INFO'))
    def destroy(self, request, *args, **kwargs):
        if kwargs.get('pk') and int(kwargs['pk']) != -1:
            instance = self.get_object()
            if instance.name == 'debugtalk.py':
                Response(status=status.HTTP_423_LOCKED)
            else:
                self.perform_destroy(instance)
        elif request.data:
            for content in request.data:
                self.kwargs['pk'] = content['id']
                instance = self.get_object()
                if instance.name != 'debugtalk.py':
                    self.perform_destroy(instance)
        return Response(status=status.HTTP_204_NO_CONTENT)
Ejemplo n.º 5
0
class DashboardView(GenericViewSet):
    """
    dashboard信息
    """
    # permission_classes = (DjangoModelPermissions, IsBelongToProject)
    @method_decorator(request_log(level='INFO'))
    def get(self, request, **kwargs):
        return Response(prepare.get_project_detail(kwargs['pk']))
Ejemplo n.º 6
0
class DashboardView(GenericViewSet):
    """
    dashboard信息
    """

    @method_decorator(request_log(level='INFO'))
    def get(self, request, **kwargs):
        return Response(prepare.get_project_detail(kwargs['pk']))
Ejemplo n.º 7
0
class DownloadView(APIView):
    """下载文件接口
    """
    @method_decorator(request_log(level='DEBUG'))
    def post(self, request, **kwargs):
        """下载文件
            请求参数:{
                fileType: int (1:testdata, 2: report_excel 3: report_html)
                id: int,
                project: int
            }
        """
        try:
            file_type = int(request.data["fileType"])
            idno = int(request.data["id"])
            project = int(request.data["project"])
        except KeyError:
            return Response(response.KEY_MISS,
                            status=status.HTTP_400_BAD_REQUEST)
        try:
            if file_type == 1:
                fileObject = models.ModelWithFileField.objects.get(
                    project_id=project, id=idno)
                filename = fileObject.name
                filepath = os.path.join(MEDIA_ROOT, str(fileObject.file))
            else:
                fileObject = models.ReportDetail.objects.get(
                    project_id=project, report_id=idno)
                filename = fileObject.name
                summary = json.loads(fileObject.summary)
                filepath = write_excel_log(summary)

            fileresponse = FileResponse(open(filepath, 'rb'))
            fileresponse["Content-Type"] = "application/octet-stream"
            fileresponse[
                "Content-Disposition"] = "attachment;filename={}".format(
                    filename)
            return fileresponse

        except ObjectDoesNotExist:
            return Response(response.FILE_DOWNLOAD_FAIL,
                            status=status.HTTP_400_BAD_REQUEST)
Ejemplo n.º 8
0
class ProjectView(ModelViewSet):
    """
    项目增删改查
    """
    queryset = models.Project.objects.all().order_by('-update_time')
    serializer_class = serializers.ProjectSerializer
    pagination_class = pagination.MyCursorPagination
    permission_classes = (DjangoModelPermissions,)

    @method_decorator(request_log(level='INFO'))
    def single(self, request, **kwargs):
        """
        得到单个项目相关统计信息
        """
        pk = kwargs.pop('pk')

        try:
            queryset = models.Project.objects.get(id=pk)
        except ObjectDoesNotExist:
            return Response(response.PROJECT_NOT_EXISTS)

        serializer = self.get_serializer(queryset, many=False)

        project_info = prepare.get_project_detail(pk)
        project_info.update(serializer.data)

        return Response(project_info)

    def perform_create(self, serializer):
        instance = serializer.save()
        # 生成debugtalk.py文件
        models.Pycode.objects.create(project=instance, name="debugtalk.py", desc="项目的根目录文件,项目中所使用函数都从此中调用")
        # 自动生成API tree
        models.Relation.objects.create(project=instance)
        # 自动生成Test Tree
        models.Relation.objects.create(project=instance, type=2)

    def perform_destroy(self, instance):
        project_id = instance.id
        celery_models.PeriodicTask.objects.filter(description=project_id).delete()
        instance.delete()
Ejemplo n.º 9
0
class CaseStepView(APIView):
    """
    测试用例step操作视图
    """

    @method_decorator(request_log(level='INFO'))
    def get(self, request, **kwargs):
        """
        返回用例集信息
        """
        pk = kwargs['pk']

        queryset = models.CaseStep.objects.filter(case__id=pk).order_by('step')

        serializer = serializers.CaseStepSerializer(instance=queryset, many=True)

        resp = {
            "case": serializers.CaseSerializer(instance=models.Case.objects.get(id=pk), many=False).data,
            "step": serializer.data
        }
        return Response(resp)
Ejemplo n.º 10
0
class PycodeRunView(GenericViewSet, mixins.RetrieveModelMixin):
    """
    驱动代码调试运行
    """
    serializer_class = serializers.PycodeSerializer

    def get_queryset(self):
        project = self.request.query_params["project"]
        queryset = models.Pycode.objects.filter(
            project_id=project).order_by('-update_time')
        return queryset

    @method_decorator(request_log(level='INFO'))
    def retrieve(self, request, *args, **kwargs):
        instance = self.get_object()
        serializer = self.get_serializer(instance)

        debug = DebugCode(serializer.data["code"], serializer.data["project"],
                          serializer.data["name"])
        debug.run()

        debug_rsp = {"msg": debug.resp}
        return Response(data=debug_rsp)
Ejemplo n.º 11
0
class VariablesView(GenericViewSet):
    serializer_class = serializers.VariablesSerializer
    queryset = models.Variables.objects
    permission_classes = (DjangoModelPermissions,)

    @method_decorator(request_log(level='DEBUG'))
    def list(self, request):
        project = request.query_params['project']
        search = request.query_params["search"]

        queryset = self.get_queryset().filter(project__id=project).order_by('-update_time')

        if search != '':
            queryset = queryset.filter(key__contains=search)

        pagination_queryset = self.paginate_queryset(queryset)
        serializer = self.get_serializer(pagination_queryset, many=True)

        return self.get_paginated_response(serializer.data)

    @method_decorator(request_log(level='INFO'))
    def add(self, request):
        """
            add new variables
            {
                key: str
                value: str
                project: int
            }
        """

        try:
            project = models.Project.objects.get(id=request.data["project"])
        except ObjectDoesNotExist:
            return Response(response.PROJECT_NOT_EXISTS)

        if models.Variables.objects.filter(key=request.data["key"], project=project).first():
            return Response(response.VARIABLES_EXISTS)

        request.data["project"] = project

        models.Variables.objects.create(**request.data)
        return Response(response.CONFIG_ADD_SUCCESS)

    @method_decorator(request_log(level='INFO'))
    def update(self, request, **kwargs):
        """
        pk: int
        {
          key: str
          value:str
        }
        """
        pk = kwargs['pk']

        try:
            variables = models.Variables.objects.get(id=pk)

        except ObjectDoesNotExist:
            return Response(response.VARIABLES_NOT_EXISTS)

        if models.Variables.objects.exclude(id=pk).filter(key=request.data['key']).first():
            return Response(response.VARIABLES_EXISTS)

        variables.key = request.data["key"]
        variables.value = request.data["value"]
        variables.save()

        return Response(response.VARIABLES_UPDATE_SUCCESS)

    @method_decorator(request_log(level='INFO'))
    def delete(self, request, **kwargs):
        """
        删除一个变量 pk
        删除多个
        [{
            id:int
        }]
        """

        try:
            if kwargs.get('pk'):  # 单个删除
                models.Variables.objects.get(id=kwargs['pk']).delete()
            else:
                for content in request.data:
                    models.Variables.objects.get(id=content['id']).delete()

        except ObjectDoesNotExist:
            return Response(response.VARIABLES_NOT_EXISTS)

        return Response(response.API_DEL_SUCCESS)
Ejemplo n.º 12
0
class ConfigView(GenericViewSet):
    serializer_class = serializers.ConfigSerializer
    queryset = models.Config.objects
    permission_classes = (DjangoModelPermissions,)

    @method_decorator(request_log(level='DEBUG'))
    def list(self, request):
        project = request.query_params['project']
        search = request.query_params["search"]

        queryset = self.get_queryset().filter(project__id=project).order_by('-update_time')

        if search != '':
            queryset = queryset.filter(name__contains=search)

        pagination_queryset = self.paginate_queryset(queryset)
        serializer = self.get_serializer(pagination_queryset, many=True)

        return self.get_paginated_response(serializer.data)

    @method_decorator(request_log(level='DEBUG'))
    def all(self, request, **kwargs):
        """
        get all config
        """
        pk = kwargs["pk"]

        queryset = self.get_queryset().filter(project__id=pk). \
            order_by('-update_time').values("id", "name")

        return Response(queryset)

    @method_decorator(request_log(level='INFO'))
    def add(self, request):
        """
            add new config
            {
                name: str
                project: int
                body: dict
            }
        """

        config = Format(request.data, level='config')
        config.parse()
        del config.testcase["skipIf"]

        try:
            config.project = models.Project.objects.get(id=config.project)
        except ObjectDoesNotExist:
            return Response(response.PROJECT_NOT_EXISTS)

        if models.Config.objects.filter(name=config.name, project=config.project).first():
            return Response(response.CONFIG_EXISTS)

        config_body = {
            "name": config.name,
            "base_url": config.base_url,
            "body": config.testcase,
            "project": config.project
        }

        models.Config.objects.create(**config_body)
        return Response(response.CONFIG_ADD_SUCCESS)

    @method_decorator(request_log(level='INFO'))
    def update(self, request, **kwargs):
        """
        pk: int
        {
            name: str,
            base_url: str,
            variables: []
            parameters: []
            request: []
            }
        }
        """
        pk = kwargs['pk']

        try:
            config = models.Config.objects.get(id=pk)

        except ObjectDoesNotExist:
            return Response(response.CONFIG_NOT_EXISTS)

        format = Format(request.data, level="config")
        format.parse()
        del format.testcase["skipIf"]

        if models.Config.objects.exclude(id=pk).filter(name=format.name, project=config.project).first():
            return Response(response.CONFIG_EXISTS)

        case_step = models.CaseStep.objects.filter(method="config", name=config.name)

        for case in case_step:
            case.name = format.name
            case.body = format.testcase
            case.save()

        config.name = format.name
        config.body = format.testcase
        config.base_url = format.base_url
        config.save()

        return Response(response.CONFIG_UPDATE_SUCCESS)
Ejemplo n.º 13
0
        case_step = models.CaseStep.objects.filter(method="config", name=config.name)

        for case in case_step:
            case.name = format.name
            case.body = format.testcase
            case.save()

        config.name = format.name
        config.body = format.testcase
        config.base_url = format.base_url
        config.save()

        return Response(response.CONFIG_UPDATE_SUCCESS)

    @method_decorator(request_log(level='INFO'))
    def copy(self, request, **kwargs):
        """
        pk: int
        {
            name: str
        }
        """
        pk = kwargs['pk']
        try:
            config = models.Config.objects.get(id=pk)
        except ObjectDoesNotExist:
            return Response(response.CONFIG_NOT_EXISTS)

        if models.Config.objects.filter(**request.data).first():
            return Response(response.CONFIG_EXISTS)
Ejemplo n.º 14
0
class HostIPView(GenericViewSet):
    serializer_class = serializers.HostIPSerializer
    queryset = models.HostIP.objects

    @method_decorator(request_log(level='DEBUG'))
    def list(self, request):
        project = request.query_params['project']
        queryset = self.get_queryset().filter(
            project__id=project).order_by('-update_time')
        pagination_queryset = self.paginate_queryset(queryset)
        serializer = self.get_serializer(pagination_queryset, many=True)

        return self.get_paginated_response(serializer.data)

    @method_decorator(request_log(level='INFO'))
    def add(self, request):
        """
            add new variables
            {
                name: str
                value: str
                project: int
            }
        """

        try:
            project = models.Project.objects.get(id=request.data["project"])
        except ObjectDoesNotExist:
            return Response(response.PROJECT_NOT_EXISTS)

        if models.HostIP.objects.filter(name=request.data["name"],
                                        project=project).first():
            return Response(response.HOSTIP_EXISTS)

        request.data["project"] = project

        models.HostIP.objects.create(**request.data)
        return Response(response.HOSTIP_ADD_SUCCESS)

    @method_decorator(request_log(level='INFO'))
    def update(self, request, **kwargs):
        """pk: int{
          name: str
          value:str
        }
        """
        pk = kwargs['pk']

        try:
            host = models.HostIP.objects.get(id=pk)

        except ObjectDoesNotExist:
            return Response(response.HOSTIP_NOT_EXISTS)

        if models.HostIP.objects.exclude(id=pk).filter(
                name=request.data['name']).first():
            return Response(response.HOSTIP_EXISTS)

        host.name = request.data["name"]
        host.value = request.data["value"]
        host.save()

        return Response(response.HOSTIP_UPDATE_SUCCESS)

    @method_decorator(request_log(level='INFO'))
    def delete(self, request, **kwargs):
        """删除host
        """
        try:
            models.HostIP.objects.get(id=kwargs['pk']).delete()
        except ObjectDoesNotExist:
            return Response(response.HOSTIP_NOT_EXISTS)

        return Response(response.HOST_DEL_SUCCESS)

    @method_decorator(request_log(level='DEBUG'))
    def all(self, request, **kwargs):
        """
        get all config
        """
        pk = kwargs["pk"]

        queryset = self.get_queryset().filter(project__id=pk). \
            order_by('-update_time').values("id", "name")

        return Response(queryset)
Ejemplo n.º 15
0
class ScheduleView(GenericViewSet):
    """
    定时任务增删改查
    """
    queryset = models.PeriodicTask.objects
    serializer_class = serializers.PeriodicTaskSerializer
    pagination_class = pagination.MyPageNumberPagination

    @method_decorator(request_log(level='DEBUG'))
    def list(self, request):
        """
        查询项目信息
        """
        project = request.query_params.get("project")
        schedule = self.get_queryset().filter(
            description=project).order_by('-date_changed')
        page_schedule = self.paginate_queryset(schedule)
        serializer = self.get_serializer(page_schedule, many=True)
        return self.get_paginated_response(serializer.data)

    @method_decorator(request_log(level='INFO'))
    def add(self, request):
        """新增定时任务{
            name: str
            corntab: str
            switch: bool
            data: [int,int]
            strategy: str
            receiver: str
            copy: str
            project: int
        }
        """
        task = Task(**request.data)
        resp = task.add_task()
        return Response(resp)

    #
    # @method_decorator(request_log(level='INFO'))
    # def update(self, request):
    #     """
    #     编辑项目
    #     """
    #
    #     try:
    #         project = models.Project.objects.get(id=request.data['id'])
    #     except (KeyError, ObjectDoesNotExist):
    #         return Response(response.SYSTEM_ERROR)
    #
    #     if request.data['name'] != project.name:
    #         if models.Project.objects.filter(name=request.data['name']).first():
    #             return Response(response.PROJECT_EXISTS)
    #
    #     # 调用save方法update_time字段才会自动更新
    #     project.name = request.data['name']
    #     project.desc = request.data['desc']
    #     project.save()
    #
    #     return Response(response.PROJECT_UPDATE_SUCCESS)
    #
    # @method_decorator(request_log(level='INFO'))
    def delete(self, request, **kwargs):
        """删除任务
        """
        task = models.PeriodicTask.objects.get(id=kwargs["pk"])
        task.enabled = False
        task.delete()
        return Response(response.TASK_DEL_SUCCESS)
Ejemplo n.º 16
0
class APITemplateView(GenericViewSet):
    """
    API操作视图
    """
    serializer_class = serializers.APISerializer
    queryset = models.API.objects
    schema = APITemplateViewSchema()

    @swagger_auto_schema(query_serializer=serializers.AssertSerializer)
    @method_decorator(request_log(level='DEBUG'))
    def list(self, request):
        """
        api-获取api列表

        支持多种条件搜索
        """
        ser = serializers.AssertSerializer(data=request.query_params)
        if ser.is_valid():
            node = ser.validated_data.get('node')
            project = ser.validated_data.get('project')
            search: str = ser.validated_data.get('search')
            tag = ser.validated_data.get('tag')
            rig_env = ser.validated_data.get('rigEnv')
            delete = ser.validated_data.get('delete')
            only_me = ser.validated_data.get('onlyMe')

            queryset = self.get_queryset().filter(
                project__id=project, delete=delete).order_by('-update_time')

            if only_me is True:
                queryset = queryset.filter(creator=request.user)

            if search != '':
                search: list = search.split()
                for key in search:
                    queryset = queryset.filter(
                        Q(name__contains=key) | Q(url__contains=key))

            if node != '':
                queryset = queryset.filter(relation=node)

            if tag != '':
                queryset = queryset.filter(tag=tag)

            if rig_env != '':
                queryset = queryset.filter(rig_env=rig_env)

            pagination_queryset = self.paginate_queryset(queryset)
            serializer = self.get_serializer(pagination_queryset, many=True)

            return self.get_paginated_response(serializer.data)
        else:
            return Response(ser.errors, status=status.HTTP_400_BAD_REQUEST)

    @method_decorator(request_log(level='INFO'))
    def add(self, request):
        """
        api-新增一个api

        前端按照格式组装好,注意body
        """

        api = Format(request.data)
        api.parse()

        api_body = {
            'name': api.name,
            'body': api.testcase,
            'url': api.url,
            'method': api.method,
            'project': models.Project.objects.get(id=api.project),
            'relation': api.relation,
            'creator': request.user.username
        }

        try:
            models.API.objects.create(**api_body)
        except DataError:
            return Response(response.DATA_TO_LONG)

        return Response(response.API_ADD_SUCCESS)

    @method_decorator(request_log(level='INFO'))
    def update(self, request, **kwargs):
        """
        api-更新单个api

        更新单个api的内容
        """
        pk = kwargs['pk']
        api = Format(request.data)
        api.parse()

        api_body = {
            'name': api.name,
            'body': api.testcase,
            'url': api.url,
            'method': api.method,
            'updater': request.user.username
        }

        try:
            models.API.objects.filter(id=pk).update(**api_body)
        except ObjectDoesNotExist:
            return Response(response.API_NOT_FOUND)

        return Response(response.API_UPDATE_SUCCESS)

    @method_decorator(request_log(level='INFO'))
    def move(self, request):
        """
        api-批量更新api的目录

        移动api到指定目录
        """
        project: int = request.data.get('project')
        relation: int = request.data.get('relation')
        apis: list = request.data.get('api')
        ids = [api['id'] for api in apis]

        try:
            models.API.objects.filter(project=project,
                                      id__in=ids).update(relation=relation)
        except ObjectDoesNotExist:
            return Response(response.API_NOT_FOUND)

        return Response(response.API_UPDATE_SUCCESS)

    @method_decorator(request_log(level='INFO'))
    def copy(self, request, **kwargs):
        """
        api-复制api

        复制一个api
        """
        pk = kwargs['pk']
        name = request.data['name']
        api = models.API.objects.get(id=pk)
        body = eval(api.body)
        body["name"] = name
        api.body = body
        api.id = None
        api.name = name
        api.creator = request.user.username
        api.updater = request.user.username
        api.save()
        return Response(response.API_ADD_SUCCESS)

    @method_decorator(request_log(level='INFO'))
    def delete(self, request, **kwargs):
        """
        api-删除一个api

        软删除一个api
        """

        try:
            if kwargs.get('pk'):  # 单个删除
                # models.API.objects.get(id=kwargs['pk']).delete()
                models.API.objects.filter(id=kwargs['pk']).update(
                    delete=1, update_time=datetime.datetime.now())
            else:
                for content in request.data:
                    # models.API.objects.get(id=content['id']).delete()
                    models.API.objects.filter(id=content['id']).update(
                        delete=1)

        except ObjectDoesNotExist:
            return Response(response.API_NOT_FOUND)

        return Response(response.API_DEL_SUCCESS)

    @method_decorator(request_log(level='INFO'))
    def add_tag(self, request, **kwargs):
        """
        api-更新api的tag,暂时默认为调试成功

        更新api的tag类型
        """

        try:
            if kwargs.get('pk'):
                models.API.objects.filter(id=kwargs['pk']).update(
                    tag=request.data['tag'],
                    update_time=datetime.datetime.now(),
                    updater=request.user.username)
        except ObjectDoesNotExist:
            return Response(response.API_NOT_FOUND)

        return Response(response.API_UPDATE_SUCCESS)

    @method_decorator(request_log(level='INFO'))
    def sync_case(self, request, **kwargs):
        """
        api-同步api的到case_step

        1.根据api_id查出("name", "body", "url", "method")
        2.根据api_id更新case_step中的("name", "body", "url", "method", "updater")
        3.更新case的update_time, updater
        """
        pk = kwargs['pk']
        source_api = models.API.objects.filter(pk=pk).values(
            "name", "body", "url", "method").first()
        case_steps = models.CaseStep.objects.filter(source_api_id=pk)
        case_steps.update(**source_api,
                          updater=request.user.username,
                          update_time=datetime.datetime.now())
        case_ids = case_steps.values('case')
        models.Case.objects.filter(pk__in=case_ids).update(
            update_time=datetime.datetime.now(), updater=request.user.username)
        return Response(response.CASE_STEP_SYNC_SUCCESS)

    @method_decorator(request_log(level='INFO'))
    def single(self, request, **kwargs):
        """
        api-获取单个api详情,返回body信息

        获取单个api的详细情况
        """
        try:
            api = models.API.objects.get(id=kwargs['pk'])
        except ObjectDoesNotExist:
            return Response(response.API_NOT_FOUND)

        parse = Parse(eval(api.body))
        parse.parse_http()

        resp = {
            'id': api.id,
            'body': parse.testcase,
            'success': True,
        }

        return Response(resp)
Ejemplo n.º 17
0
class TestCaseView(GenericViewSet):
    queryset = models.Case.objects
    serializer_class = serializers.CaseSerializer
    tag_options = {"冒烟用例": 1, "集成用例": 2, "监控脚本": 3}

    @method_decorator(request_log(level='INFO'))
    def get(self, request):
        """
        查询指定CASE列表,不包含CASE STEP
        {
            "project": int,
            "node": int
        }
        """
        node = request.query_params["node"]
        search = request.query_params["search"]
        # update_time 降序排列
        queryset = self.filter_queryset(
            self.get_queryset()).order_by('-update_time')

        if search != '':
            queryset = queryset.filter(name__contains=search)

        if node != '':
            queryset = queryset.filter(relation=node)

        pagination_query = self.paginate_queryset(queryset)
        serializer = self.get_serializer(pagination_query, many=True)

        return self.get_paginated_response(serializer.data)

    @method_decorator(request_log(level='INFO'))
    def copy(self, request, **kwargs):
        """
        pk int: test id
        {
            name: test name
            relation: int
            project: int
        }
        """
        pk = kwargs['pk']
        name = request.data['name']
        case = models.Case.objects.get(id=pk)
        case.id = None
        case.name = name
        case.save()

        case_step = models.CaseStep.objects.filter(case__id=pk)

        for step in case_step:
            step.id = None
            step.case = case
            step.save()

        return Response(response.CASE_ADD_SUCCESS)

    @method_decorator(request_log(level='INFO'))
    def patch(self, request, **kwargs):
        """
        更新测试用例集
        {
            name: str
            id: int
            body: []
            project: int
        }
        """

        pk = kwargs['pk']
        project = request.data.pop("project")
        body = request.data.pop('body')
        relation = request.data.pop("relation")

        if models.Case.objects.exclude(id=pk). \
                filter(name=request.data['name'],
                       project__id=project,
                       relation=relation).first():
            return Response(response.CASE_EXISTS)

        case = models.Case.objects.get(id=pk)

        prepare.update_casestep(body, case)

        request.data['tag'] = self.tag_options[request.data['tag']]
        models.Case.objects.filter(id=pk).update(**request.data)

        return Response(response.CASE_UPDATE_SUCCESS)

    @method_decorator(request_log(level='INFO'))
    def post(self, request):
        """
        新增测试用例集
        {
            name: str
            project: int,
            relation: int,
            tag:str
            body: [{
                id: int,
                project: int,
                name: str,
                method: str,
                url: str
            }]
        }
        """

        try:
            pk = request.data['project']
            request.data['project'] = models.Project.objects.get(id=pk)

        except KeyError:
            return Response(response.KEY_MISS)

        except ObjectDoesNotExist:
            return Response(response.PROJECT_NOT_EXISTS)

        body = request.data.pop('body')

        request.data['tag'] = self.tag_options[request.data['tag']]
        models.Case.objects.create(**request.data)

        case = models.Case.objects.filter(**request.data).first()

        prepare.generate_casestep(body, case)

        return Response(response.CASE_ADD_SUCCESS)

    @method_decorator(request_log(level='INFO'))
    def delete(self, request, **kwargs):
        """
        pk: test id delete single
        [{id:int}] delete batch
        """
        pk = kwargs.get('pk')

        try:
            if pk:
                prepare.case_end(pk)
            else:
                for content in request.data:
                    prepare.case_end(content['id'])

        except ObjectDoesNotExist:
            return Response(response.SYSTEM_ERROR)

        return Response(response.CASE_DELETE_SUCCESS)
Ejemplo n.º 18
0
class TestCaseView(ModelViewSet):
    """
    create:新增测试用例集
        {
            name: str
            project: int,
            relation: int,
            tag:str
            body: [{
                id: int,
                project: int,
                name: str
            }]
        }
    create: copy{
        id: 36
        name: "d"
        project: 6
        relation: 1
        }
    """
    serializer_class = serializers.CaseSerializer
    pagination_class = pagination.MyPageNumberPagination
    permission_classes = (DjangoModelPermissions,)

    def get_queryset(self):
        project = self.request.query_params["project"]
        queryset = models.Case.objects.filter(project__id=project).order_by('-update_time')
        if self.action == 'list':
            node = self.request.query_params["node"]
            search = self.request.query_params["search"]
            if search != '':
                queryset = queryset.filter(name__contains=search)
            if node != '':
                queryset = queryset.filter(relation=node)
        return queryset

    @method_decorator(request_log(level='INFO'))
    def create(self, request, *args, **kwargs):
        if 'id' in request.data.keys():
            pk = request.data['id']
            name = request.data['name']
            case_info = models.Case.objects.get(id=pk)
            request_data = {
                "name": name,
                "relation": case_info.relation,
                "length": case_info.length,
                "tag": case_info.tag,
                "project": case_info.project_id
            }
            serializer = self.get_serializer(data=request_data)
            serializer.is_valid(raise_exception=True)
            self.perform_create(serializer)
            case_step = models.CaseStep.objects.filter(case__id=pk)
            for step in case_step:
                step.id = None
                step.case_id = serializer.data["id"]
                step.save()
        else:
            body = request.data.pop('body')
            serializer = self.get_serializer(data=request.data)
            serializer.is_valid(raise_exception=True)
            self.perform_create(serializer)

            case = models.Case.objects.filter(**request.data).first()
            prepare.generate_casestep(body, case)

        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

    @method_decorator(request_log(level='INFO'))
    def update(self, request, *args, **kwargs):
        body = request.data.pop('body')

        partial = kwargs.pop('partial', False)
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=request.data, partial=partial)
        serializer.is_valid(raise_exception=True)

        prepare.update_casestep(body, instance)

        self.perform_update(serializer)

        if getattr(instance, '_prefetched_objects_cache', None):
            # If 'prefetch_related' has been applied to a queryset, we need to
            # forcibly invalidate the prefetch cache on the instance.
            instance._prefetched_objects_cache = {}

        return Response(serializer.data)

    @method_decorator(request_log(level='INFO'))
    def destroy(self, request, *args, **kwargs):
        if kwargs.get('pk') and int(kwargs['pk']) != -1:
            instance = self.get_object()
            prepare.case_end(int(kwargs['pk']))
            self.perform_destroy(instance)
        elif request.data:
            for content in request.data:
                self.kwargs['pk'] = content['id']
                instance = self.get_object()
                prepare.case_end(int(kwargs['pk']))
                self.perform_destroy(instance)
        return Response(status=status.HTTP_204_NO_CONTENT)

    @method_decorator(request_log(level='INFO'))
    def retrieve(self, request, *args, **kwargs):
        instance = self.get_object()
        serializer = self.get_serializer(instance)
        queryset = models.CaseStep.objects.filter(case__id=kwargs['pk']).order_by('step')
        casestep_serializer = serializers.CaseStepSerializer(queryset, many=True)
        resp = {
            "case": serializer.data,
            "step": casestep_serializer.data
        }
        return Response(resp)
Ejemplo n.º 19
0
class ScheduleView(GenericViewSet):
    """
    定时任务增删改查
    """
    queryset = models.PeriodicTask.objects
    serializer_class = serializers.PeriodicTaskSerializer
    pagination_class = pagination.MyPageNumberPagination

    @method_decorator(request_log(level='DEBUG'))
    def list(self, request):
        """
        查询项目信息
        """
        project = request.query_params.get("project")
        schedule = self.get_queryset().filter(description=project).order_by('-date_changed')
        page_schedule = self.paginate_queryset(schedule)
        serializer = self.get_serializer(page_schedule, many=True)
        return self.get_paginated_response(serializer.data)

    @method_decorator(request_log(level='INFO'))
    def add(self, request):
        """新增定时任务{
            name: str
            crontab: str
            switch: bool
            data: [int,int]
            strategy: str
            receiver: str
            copy: str
            project: int
        }
        """
        request.data.update({"creator": request.user.username})
        task = Task(**request.data)
        resp = task.add_task()
        return Response(resp)

    @method_decorator(request_log(level='INFO'))
    def update(self, request, **kwargs):
        """更新任务
        :param request:
        :param kwargs:
        :return:
        """
        task = Task(**request.data)
        resp = task.update_task(kwargs['pk'])
        return Response(resp)

    @method_decorator(request_log(level='INFO'))
    def patch(self, request, **kwargs):
        """更新任务的状态
        :param request:
        :param kwargs:
        :return:
        """
        # {'pk': 22}
        task_obj = self.get_queryset().get(pk=kwargs['pk'])
        task_obj.enabled = request.data['switch']
        kwargs = json.loads(task_obj.kwargs)
        kwargs['updater'] = request.user.username
        task_obj.kwargs = json.dumps(kwargs, ensure_ascii=False)
        task_obj.save()
        return Response(response.TASK_UPDATE_SUCCESS)

    def delete(self, request, **kwargs):
        """删除任务
        """
        task = models.PeriodicTask.objects.get(id=kwargs["pk"])
        task.enabled = False
        task.delete()
        return Response(response.TASK_DEL_SUCCESS)

    @method_decorator(request_log(level='INFO'))
    def run(self, request, **kwargs):
        task = models.PeriodicTask.objects.get(id=kwargs["pk"])
        task_name = 'fastrunner.tasks.schedule_debug_suite'
        args = eval(task.args)
        kwargs = eval(task.kwargs)
        app.send_task(name=task_name, args=args, kwargs=kwargs)
        return Response(response.TASK_RUN_SUCCESS)
Ejemplo n.º 20
0
class TestCaseView(GenericViewSet):
    queryset = models.Case.objects
    serializer_class = serializers.CaseSerializer
    tag_options = {
        "冒烟用例": 1,
        "集成用例": 2,
        "监控脚本": 3
    }

    @staticmethod
    def case_step_search(search):
        """
        搜索case_step的url或者name
        返回对应的case_id
        """
        case_id = models.CaseStep.objects.filter(Q(name__contains=search) | Q(url__contains=search)).values('case_id')

        case_id = set([item['case_id'] for _, item in enumerate(case_id)])
        return case_id

    @method_decorator(request_log(level='INFO'))
    def get(self, request):
        """
        查询指定CASE列表,不包含CASE STEP
        {
            "project": int,
            "node": int
        }
        """
        ser = serializers.CaseSearchSerializer(data=request.query_params)
        if ser.is_valid():
            node = ser.validated_data.get("node")
            project = ser.validated_data.get("project")
            search = ser.validated_data.get("search")
            search_type = ser.validated_data.get("searchType")
            case_type = ser.validated_data.get("caseType")
            only_me = ser.validated_data.get("onlyMe")

    
            # update_time 降序排列
            queryset = self.get_queryset().filter(project__id=project).order_by('-update_time')
    
            if only_me is True:
                queryset = queryset.filter(creator=request.user)
    
            if node != '':
                queryset = queryset.filter(relation=node)
    
            if case_type != '':
                queryset = queryset.filter(tag=case_type)
    
            if search != '':
                # 用例名称搜索
                if search_type == '1':
                    queryset = queryset.filter(name__contains=search)
                # API名称或者API URL搜索
                elif search_type == '2':
                    case_id = self.case_step_search(search)
                    queryset = queryset.filter(pk__in=case_id)
    
            pagination_query = self.paginate_queryset(queryset)
            serializer = self.get_serializer(pagination_query, many=True)
    
            return self.get_paginated_response(serializer.data)
        else:
            return Response(ser.errors, status=status.HTTP_400_BAD_REQUEST)

    @method_decorator(request_log(level='INFO'))
    def copy(self, request, **kwargs):
        """
        pk int: test id
        {
            name: test name
            relation: int
            project: int
        }
        """
        pk = kwargs['pk']
        name = request.data['name']
        username = request.user.username


        tree_id = request.data['treeId']
        pro_id = request.data['projectId']

        if '|' in name:
            resp = self.split(pk, name)
        else:
            for tree in tree_id:
                case = models.Case.objects.get(id=pk)
                case.id = None
                case.name = name
                case.creator = username
                case.updater = username
                case.relation = tree
                case.project_id = pro_id
                case.save()

                case_step = models.CaseStep.objects.filter(case__id=pk)

                for step in case_step:
                    step.id = None
                    step.case = case
                    step.creator = username
                    step.updater = username
                    step.save()
            resp = response.CASE_ADD_SUCCESS

        return Response(resp)
Ejemplo n.º 21
0
class ProjectView(ModelViewSet):
    """
    项目增删改查
    """
    serializer_class = serializers.ProjectSerializer
    pagination_class = pagination.MyCursorPagination
    permission_classes = (DjangoModelPermissions, IsBelongToProject)

    def get_queryset(self):
        if self.request.user.is_superuser:
            return models.Project.objects.annotate(
                count=Count("api")).all().order_by('-create_time')
        project_id_list = UserModel.objects.filter(
            id=self.request.user.id).values_list('belong_project', flat=True)
        return models.Project.objects.filter(
            id__in=[_ for _ in project_id_list]).annotate(
                count=Count("api")).all().order_by('-update_time')

    @method_decorator(request_log(level='INFO'))
    def single(self, request, **kwargs):
        """
        得到单个项目相关统计信息
        """
        pk = kwargs.pop('pk')

        try:
            queryset = models.Project.objects.get(id=pk)
        except ObjectDoesNotExist:
            return Response(response.PROJECT_NOT_EXISTS)

        serializer = self.get_serializer(queryset, many=False)

        project_info = prepare.get_project_detail(pk)
        project_info.update(serializer.data)

        return Response(project_info)

    def perform_create(self, serializer):
        instance = serializer.save()
        # 生成debugtalk.py文件
        models.Pycode.objects.create(project=instance,
                                     name="debugtalk.py",
                                     desc="项目的根目录文件,项目中所使用函数都从此中调用")
        models.Pycode.objects.create(project=instance,
                                     name="get_excel_data.py",
                                     desc="获取excel表格数据",
                                     code="""
# _*_ coding:utf-8 _*_
import xlrd
import os

class Xlaccountinfo():
    # 获取excel数据,从第三行开始,第二行是表头,第一行是备注
    def __init__(self, path=''):
        self.xl = xlrd.open_workbook(path)

    def floattostr(self, val):
        if isinstance(val, float) and float(int(val)) != val:
            val = str(int(val))
        if val.lower() == 'true':
            val = True
        elif val.lower() == 'false':
            val = False
        return val

    def get_sheetinfo_by_name(self, name):
        self.sheet = self.xl.sheet_by_name(name)
        return self.get_sheet_info()

    def get_sheetinfo_by_index(self, index):
        self.sheet = self.xl.sheet_by_index(index)
        return self.get_sheet_info()

    def get_sheetinfo_by_rowName(self, name):
        self.sheet = self.xl.sheet_by_name(name)
        infolist = []
        for col in range(self.sheet.ncols):
            if col == 0:
                listKey = [self.floattostr(val.strip()) for val in self.sheet.col_values(col)]
            elif col == 1:
                info = [self.floattostr(val.strip()) for val in self.sheet.col_values(col)]
                tmp = zip(listKey, info)
                infolist.append(dict(tmp))
        return infolist

    def get_sheet_info(self):
        infolist = []
        for row in range(1, self.sheet.nrows):
            if row == 1:
                listKey = [self.floattostr(val.strip()) for val in self.sheet.row_values(row)]
            else:
                info = [self.floattostr(val.strip()) for val in self.sheet.row_values(row)]
                tmp = zip(listKey, info)
                infolist.append(dict(tmp))
        return infolist


# 通过行获取excel数据
def get_xlsx_by_cols(excelName, sheetName):
    xlinfo = Xlaccountinfo(excelName)
    info = xlinfo.get_sheetinfo_by_name(sheetName)
    return info

# 通过列获取excel数据
def xlsxPlatform(excelName, sheetName):
    xlinfo = Xlaccountinfo(excelName)
    info = xlinfo.get_sheetinfo_by_rowName(sheetName)
    return info
    
if __name__ == '__main__':
    excelName = os.environ["excelName"]
    sheetName = os.environ["excelsheet"]
                                     """)
        # 自动生成API tree
        models.Relation.objects.create(project=instance)
        # 自动生成Test Tree
        models.Relation.objects.create(project=instance, type=2)
        # 自动生成 TestData Tree
        models.Relation.objects.create(project=instance, type=3)

    def perform_destroy(self, instance):
        project_id = instance.id
        celery_models.PeriodicTask.objects.filter(
            description=project_id).delete()
        instance.delete()
Ejemplo n.º 22
0
class TreeView(GenericViewSet):
    """
    树形结构操作
    """
    permission_classes = (DjangoModelPermissions, IsBelongToProject)

    def get_queryset(self):
        project_id = self.kwargs.get('pk')
        queryset = models.Relation.objects.filter(
            project__id=project_id).order_by('-update_time')
        return queryset

    @method_decorator(request_log(level='INFO'))
    def get(self, request, **kwargs):
        """
        返回树形结构
        当前最带节点ID
        """

        try:
            tree_type = request.query_params['type']
        except KeyError:
            return Response(response.KEY_MISS)
        try:
            tree = models.Relation.objects.get(project_id=kwargs['pk'],
                                               type=tree_type)
            body = eval(tree.tree)
        except ObjectDoesNotExist as e:
            tree = models.Relation.objects.create(project_id=kwargs['pk'],
                                                  type=tree_type,
                                                  tree=[{
                                                      'id': 1,
                                                      'label': 'testdata',
                                                      'children': []
                                                  }])
            body = []

        tree = {
            "tree": body,
            "id": tree.id,
            "success": True,
            "max": get_tree_max_id(body)
        }
        return Response(tree)

    @method_decorator(request_log(level='INFO'))
    def patch(self, request, **kwargs):
        """
        修改树形结构,ID不能重复
        """
        try:
            body = request.data['body']
            mode = request.data['mode']

            relation = models.Relation.objects.get(id=kwargs['pk'])
            relation.tree = body
            relation.save()

        except KeyError:
            return Response(response.KEY_MISS)

        except ObjectDoesNotExist:
            return Response(response.SYSTEM_ERROR)

        #  mode -> True remove node
        if mode:
            prepare.tree_end(request.data, relation.project)

        response.TREE_UPDATE_SUCCESS['tree'] = body
        response.TREE_UPDATE_SUCCESS['max'] = get_tree_max_id(body)

        return Response(response.TREE_UPDATE_SUCCESS)
Ejemplo n.º 23
0
class APITemplateView(GenericViewSet):
    """
    API操作视图
    """
    serializer_class = serializers.APISerializer
    queryset = models.API.objects
    permission_classes = (DjangoModelPermissions, )

    @method_decorator(request_log(level='DEBUG'))
    def list(self, request):
        """
        接口列表 {
            project: int,
            node: int
        }
        """

        node = request.query_params["node"]
        project = request.query_params["project"]
        search = request.query_params["search"]
        queryset = self.get_queryset().filter(
            project__id=project).order_by('-update_time')

        if search != '':
            queryset = queryset.filter(name__contains=search)

        if node != '':
            queryset = queryset.filter(relation=node)

        pagination_queryset = self.paginate_queryset(queryset)
        serializer = self.get_serializer(pagination_queryset, many=True)

        return self.get_paginated_response(serializer.data)

    @method_decorator(request_log(level='INFO'))
    def add(self, request):
        """
        新增一个接口
        """

        api = Format(request.data)
        api.parse()

        api_body = {
            'name': api.name,
            'body': api.testcase,
            'url': api.url,
            'method': api.method,
            'project': models.Project.objects.get(id=api.project),
            'relation': api.relation
        }

        try:
            models.API.objects.create(**api_body)
        except DataError:
            return Response(response.DATA_TO_LONG)

        return Response(response.API_ADD_SUCCESS)

    @method_decorator(request_log(level='INFO'))
    def update(self, request, **kwargs):
        """
        更新接口
        更新接口时同时更新testcase中的case_step的request和header
        """
        pk = kwargs['pk']
        api = Format(request.data)
        api.parse()

        api_body = {
            'name': api.name,
            'body': api.testcase,
            'url': api.url,
            'method': api.method,
        }

        try:
            models.API.objects.filter(id=pk).update(**api_body)
            case_step = models.CaseStep.objects.filter(apiId=pk)
            for case in case_step:
                csae_body = eval(case.body)
                csae_body["request"] = api_body["body"]["request"]
                csae_body["desc"]["header"] = api_body["body"]["desc"][
                    "header"]
                csae_body["desc"]["data"] = api_body["body"]["desc"]["data"]
                csae_body["desc"]["files"] = api_body["body"]["desc"]["files"]
                csae_body["desc"]["params"] = api_body["body"]["desc"][
                    "params"]

                case.url = api_body["url"]
                case.method = api_body["method"]
                case.body = csae_body
                case.save()

        except ObjectDoesNotExist:
            return Response(response.API_NOT_FOUND)

        return Response(response.API_UPDATE_SUCCESS)

    @method_decorator(request_log(level='INFO'))
    def copy(self, request, **kwargs):
        """
        pk int: test id
        {
            name: api name
        }
        """
        pk = kwargs['pk']
        name = request.data['name']
        api = models.API.objects.get(id=pk)
        body = eval(api.body)
        body["name"] = name
        api.body = body
        api.id = None
        api.name = name
        api.save()
        return Response(response.API_ADD_SUCCESS)

    @method_decorator(request_log(level='INFO'))
    def delete(self, request, **kwargs):
        """
        删除一个接口 pk
        删除多个
        [{
            id:int
        }]
        """

        try:
            if kwargs.get('pk'):  # 单个删除
                models.API.objects.get(id=kwargs['pk']).delete()
            else:
                for content in request.data:
                    models.API.objects.get(id=content['id']).delete()

        except ObjectDoesNotExist:
            return Response(response.API_NOT_FOUND)

        return Response(response.API_DEL_SUCCESS)

    @method_decorator(request_log(level='INFO'))
    def single(self, request, **kwargs):
        """
        查询单个api,返回body信息
        """
        try:
            api = models.API.objects.get(id=kwargs['pk'])
        except ObjectDoesNotExist:
            return Response(response.API_NOT_FOUND)

        parse = Parse(eval(api.body))
        parse.parse_http()

        resp = {
            'id': api.id,
            'body': parse.testcase,
            'success': True,
        }

        return Response(resp)
Ejemplo n.º 24
0
class ReportView(GenericViewSet):
    """
    报告视图
    """
    authentication_classes = ()
    queryset = models.Report.objects
    serializer_class = serializers.ReportSerializer
    pagination_class = pagination.MyPageNumberPagination

    @method_decorator(request_log(level='DEBUG'))
    def list(self, request):
        """报告列表
        """

        project = request.query_params['project']
        search = request.query_params["search"]

        queryset = self.get_queryset().filter(
            project__id=project).order_by('-update_time')

        if search != '':
            queryset = queryset.filter(name__contains=search)

        page_report = self.paginate_queryset(queryset)
        serializer = self.get_serializer(page_report, many=True)
        return self.get_paginated_response(serializer.data)

    @method_decorator(request_log(level='INFO'))
    def delete(self, request, **kwargs):
        """删除报告
        """
        """
           删除一个报告pk
           删除多个
           [{
               id:int
           }]
        """
        try:
            if kwargs.get('pk'):  # 单个删除
                models.Report.objects.get(id=kwargs['pk']).delete()
            else:
                for content in request.data:
                    models.Report.objects.get(id=content['id']).delete()

        except ObjectDoesNotExist:
            return Response(response.REPORT_NOT_EXISTS)

        return Response(response.REPORT_DEL_SUCCESS)

    @method_decorator(request_log(level='INFO'))
    def look(self, request, **kwargs):
        """查看报告
        """
        pk = kwargs["pk"]
        report = models.Report.objects.get(id=pk)
        summary = json.loads(report.summary, encoding="utf-8")
        summary["html_report_name"] = report.name
        return render_to_response('report_template.html', summary)

    def download(self, request, **kwargs):
        """下载报告
        """
        pass
Ejemplo n.º 25
0
class ScheduleView(ModelViewSet):
    """
    定时任务增删改查
    """
    serializer_class = serializers.PeriodicTaskSerializer
    pagination_class = pagination.MyPageNumberPagination
    permission_classes = (DjangoModelPermissions, )

    def get_queryset(self):
        project = self.request.query_params.get("project")
        return celery_models.PeriodicTask.objects.filter(
            description=project).order_by('-date_changed')

    @method_decorator(request_log(level='INFO'))
    def create(self, request, *args, **kwargs):
        """新增定时任务{
            name: str
            corntab: str
            switch: bool
            data: [{kwargs: dict,} ,]
            strategy: str
            receiver: str
            copy: str
            project: int,
        }
        """
        if 'id' in request.data.keys():
            pk = request.data['id']
            name = request.data['name']

            periodic_info = self.get_queryset().get(id=pk)
            request_data = {
                "name": name,
                "task": "fastrunner.tasks.schedule_debug_suite",
                "crontab": periodic_info.crontab_id,
                "args": periodic_info.args,
                "kwargs": periodic_info.kwargs,
                "description": periodic_info.description,
                "enabled": periodic_info.enabled
            }
        else:
            request_data = format_request(request.data)
            if not request_data["kwargs"]["receiver"]["success"]:
                return Response(request_data["_email"]["receiver"]["error"],
                                status=status.HTTP_400_BAD_REQUEST)
            if not request_data["kwargs"]["mail_cc"]["success"]:
                return Response(request_data["_email"]["mail_cc"]["error"],
                                status=status.HTTP_400_BAD_REQUEST)
            if request_data["kwargs"]["strategy"] in [
                    '始终发送', '仅失败发送'
            ] and request_data["kwargs"]["receiver"] == []:
                return Response({"receiver": "请填写接收邮箱"},
                                status=status.HTTP_400_BAD_REQUEST)
            if not request_data["crontab"]["success"]:
                return Response(request_data["crontab"]["error"],
                                status=status.HTTP_400_BAD_REQUEST)
            crontab = celery_models.CrontabSchedule.objects.filter(
                **request_data["crontab"]["crontab"]).first()
            if crontab is None:
                crontab = serializers.CrontabScheduleSerializer(
                    data=request_data["crontab"]["crontab"])
                crontab.is_valid(raise_exception=True)
                crontab.save()
                crontab = celery_models.CrontabSchedule.objects.filter(
                    **request_data["crontab"]["crontab"]).first()
            request_data["crontab"] = crontab.id
            request_data["kwargs"]["receiver"] = request_data["kwargs"][
                "receiver"]["email"]
            request_data["kwargs"]["mail_cc"] = request_data["kwargs"][
                "mail_cc"]["email"]
            request_data["kwargs"] = json.dumps(request_data["kwargs"],
                                                ensure_ascii=False)

        serializer = self.get_serializer(data=request_data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data,
                        status=status.HTTP_201_CREATED,
                        headers=headers)

    @method_decorator(request_log(level='INFO'))
    def update(self, request, *args, **kwargs):
        partial = kwargs.pop('partial', False)
        instance = self.get_object()

        request_data = format_request(request.data)
        if not request_data["kwargs"]["receiver"]["success"]:
            return Response(request_data["kwargs"]["receiver"]["error"],
                            status=status.HTTP_400_BAD_REQUEST)
        if not request_data["kwargs"]["mail_cc"]["success"]:
            return Response(request_data["kwargs"]["mail_cc"]["error"],
                            status=status.HTTP_400_BAD_REQUEST)
        if request_data["kwargs"]["strategy"] in [
                '始终发送', '仅失败发送'
        ] and request_data["kwargs"]["receiver"] == []:
            return Response({"receiver": "请填写接收邮箱"},
                            status=status.HTTP_400_BAD_REQUEST)
        if not request_data["crontab"]["success"]:
            return Response(request_data["crontab"]["error"],
                            status=status.HTTP_400_BAD_REQUEST)
        crontab = celery_models.CrontabSchedule.objects.filter(
            **request_data["crontab"]["crontab"]).first()
        if crontab is None:
            crontab = serializers.CrontabScheduleSerializer(
                data=request_data["crontab"]["crontab"])
            crontab.is_valid(raise_exception=True)
            crontab.save()
            crontab = celery_models.CrontabSchedule.objects.filter(
                **request_data["crontab"]["crontab"]).first()
        request_data["crontab"] = crontab.id
        request_data["kwargs"]["receiver"] = request_data["kwargs"][
            "receiver"]["email"]
        request_data["kwargs"]["mail_cc"] = request_data["kwargs"]["mail_cc"][
            "email"]
        request_data["kwargs"] = json.dumps(request_data["kwargs"],
                                            ensure_ascii=False)

        serializer = self.get_serializer(instance,
                                         data=request_data,
                                         partial=partial)
        serializer.is_valid(raise_exception=True)
        self.perform_update(serializer)
        if getattr(instance, '_prefetched_objects_cache', None):
            # If 'prefetch_related' has been applied to a queryset, we need to
            # forcibly invalidate the prefetch cache on the instance.
            instance._prefetched_objects_cache = {}

        return Response(serializer.data)

    def destroy(self, request, *args, **kwargs):
        if kwargs.get('pk') and int(kwargs['pk']) != -1:
            instance = self.get_object()
            self.perform_destroy(instance)
        elif request.data:
            for content in request.data:
                self.kwargs['pk'] = content['id']
                instance = self.get_object()
                self.perform_destroy(instance)
        return Response(status=status.HTTP_204_NO_CONTENT)
Ejemplo n.º 26
0
class ReportView(GenericViewSet):
    """
    报告视图
    """
    queryset = models.Report.objects
    serializer_class = serializers.ReportSerializer
    pagination_class = pagination.MyPageNumberPagination

    def get_authenticators(self):
        # 查看报告详情不需要鉴权
        # self.request.path = '/api/fastrunner/reports/3053/'
        pattern = re.compile(r'/api/fastrunner/reports/\d+/')
        if self.request.method == 'GET' and re.search(
                pattern, self.request.path) is not None:
            return []
        return super().get_authenticators()

    @method_decorator(request_log(level='DEBUG'))
    def list(self, request):
        """报告列表
        """

        project = request.query_params['project']
        search = request.query_params["search"]
        report_type = request.query_params["reportType"]
        report_status = request.query_params["reportStatus"]
        only_me = request.query_params["onlyMe"]

        queryset = self.get_queryset().filter(
            project__id=project).order_by('-update_time')

        # 前端传过来是小写的字符串,不是python的True
        if only_me == 'true':
            queryset = queryset.filter(creator=request.user)

        if search != '':
            queryset = queryset.filter(name__contains=search)

        if report_type != '':
            queryset = queryset.filter(type=report_type)

        if report_status != '':
            queryset = queryset.filter(status=report_status)

        page_report = self.paginate_queryset(queryset)
        serializer = self.get_serializer(page_report, many=True)
        return self.get_paginated_response(serializer.data)

    @method_decorator(request_log(level='INFO'))
    def delete(self, request, **kwargs):
        """删除报告
        """
        """
           删除一个报告pk
           删除多个
           [{
               id:int
           }]
        """
        try:
            if kwargs.get('pk'):  # 单个删除
                models.Report.objects.get(id=kwargs['pk']).delete()
            else:
                for content in request.data:
                    models.Report.objects.get(id=content['id']).delete()

        except ObjectDoesNotExist:
            return Response(response.REPORT_NOT_EXISTS)

        return Response(response.REPORT_DEL_SUCCESS)

    @method_decorator(request_log(level='INFO'))
    def look(self, request, **kwargs):
        """查看报告
        """
        pk = kwargs["pk"]
        report = models.Report.objects.get(id=pk)
        report_detail = models.ReportDetail.objects.get(report_id=pk)
        summary = json.loads(report.summary, encoding="utf-8")

        summary['details'] = str(report_detail.summary_detail).replace(
            'Markup', '').replace('\\n',
                                  '').replace(" ", "").replace(""", "\"")
        summary['details'] = eval(summary['details'])
        print(summary)

        summary["html_report_name"] = report.name
        # return render_to_response('report_template.html', summary)

        return render(request,
                      template_name='report_template.html',
                      context=summary)

    def download(self, request, **kwargs):
        """下载报告
        """
        pass
Ejemplo n.º 27
0
class APIRigView(GenericViewSet):
    authentication_classes = []
    serializer_class = serializers.APISerializer
    queryset = models.API.objects

    def list(self, request):
        """
        接口列表 {
            project: int,
            node: int
        }
        """

        node = request.query_params["node"]
        project = request.query_params["project"]
        search = request.query_params["search"]
        # queryset = self.get_queryset().filter(project__id=project).order_by('-update_time')
        queryset = self.get_queryset().filter(
            project__id=project, delete=0).order_by('-update_time')
        # queryset = self.get_queryset().filter(Q(project__id=project) and ~Q(delete=1)).order_by('-update_time')

        if search != '':
            queryset = queryset.filter(name__contains=search)

        if node != '':
            queryset = queryset.filter(relation=node)

        pagination_queryset = self.paginate_queryset(queryset)
        serializer = self.get_serializer(pagination_queryset, many=True)

        return self.get_paginated_response(serializer.data)

    @method_decorator(request_log(level='INFO'))
    def add(self, request):
        """
        新增一个接口
        {
  "header": {
    "header": {
      "wb-token": "$wb_token"
    },
    "desc": {
      "wb-token": "用户登陆token"
    }
  },
  "request": {
    "form": {
      "data": {},
      "desc": {}
    },
    "json": {},
    "params": {
      "params": {
        "goodsCode": "42470"
      },
      "desc": {
        "goodsCode": "商品编码"
      }
    },
    "files": {
      "files": {},
      "desc": {}
    }
  },
  "extract": {
    "extract": [],
    "desc": {}
  },
  "validate": {
    "validate": [{"equals": ["content.info.error",0]}]
  },
  "variables": {
    "variables": [
      {
        "auth_type": "APP_MEMBER_AUTH"
      },
      {
        "rpc_Group": "wbiao.seller.prod"
      },
      {
        "rpc_Interface": "cn.wbiao.seller.api.GoodsDetailService"
      },
      {
        "params_type": "Key_Value"
      },
      {
        "author": "xuqirong"
      }
    ],
    "desc": {
      "auth_type": "认证类型",
      "rpc_Group": "RPC服务组",
      "rpc_Interface": "后端服务接口",
      "params_type": "入参数形式",
      "author": "作者"
    }
  },
  "hooks": {
    "setup_hooks": [
      "${get_sign($request,$auth_type)}"
    ],
    "teardown_hooks": []
  },
  "url": "/wxmp/mall/goods/detail/getRecommendGoodsList",
  "method": "GET",
  "name": "查询关联的商品推荐列表-小程序需签名",
  "times": 1,
  "nodeId": "member",
  "project": 5,
  "rig_id":200014
}
        """

        api = Format(request.data)
        api.parse()
        # try:
        #     rig_env = api.rig_env
        # except KeyError:
        #     # 不传环境,使用默认测试环境0
        #     rig_env = 0
        try:
            relation = API_RELATION[api.relation]
        except KeyError:
            relation = API_RELATION['default']

        if api.rig_id:
            api.name = api.name + '-' + str(api.rig_id)

        if api.rig_env == 0:
            api.name += '-测试'

        elif api.rig_env == 1:
            api.name += '-生产'
            # 生产环境比测试环境的关系节点大20
            relation += 20
        else:
            api.name += '-预发布'

        api.testcase['name'] = api.name
        api_body = {
            'name': api.name,
            'body': api.testcase,
            'url': api.url,
            'method': api.method,
            'project': models.Project.objects.get(id=api.project),
            # 'relation': api.relation,
            'rig_id': api.rig_id,
            'rig_env': api.rig_env,
            'relation': relation
        }
        # try:
        #     relation = API_RELATION[api.relation]
        # except KeyError:
        #     relation = API_RELATION['default']

        # api_body['relation'] = relation
        try:
            # 增加api之前先删除已经存在的相同id的除了手动调试成功的api
            models.API.objects.filter(
                rig_id=api.rig_id).filter(~Q(tag=1)).update(
                    delete=1, update_time=datetime.datetime.now())
            # 创建成功,返回对象,方便获取id
            obj = models.API.objects.create(**api_body)
        except DataError:
            return Response(response.DATA_TO_LONG)

        # api作者
        # 2019年10月22日 修复rig增加api运行失败时,没有复制api到Java同学项目
        author = api_body['body']['variables'][4]['author']
        self.copy_to_java(api.rig_id, author)

        # api运行成功,就自动增加到用例集里面
        run_result = run.auto_run_api_pk(config=api.rig_env, id=obj.id)
        if run_result == 'success':
            run.update_auto_case_step(**api_body)

        return Response(response.API_ADD_SUCCESS)

    # 复制一份到Java同学项目
    def copy_to_java(self, rig_id, author):
        # 根据作者决定分组
        try:
            relation = API_AUTHOR[author]
        except KeyError:
            relation = API_AUTHOR['default']

        # Java项目的id=4
        # obj = models.API.objects.get(rig_id=rig_id)
        # 修复已经存在的rig_id的api无法复制
        obj = models.API.objects.filter(rig_id=rig_id).order_by('-id')[0]
        obj.id = None
        obj.relation = relation
        obj.project_id = 4
        obj.save()

    @method_decorator(request_log(level='INFO'))
    def update(self, request, **kwargs):
        """
        更新接口
        """
        pk = kwargs['rig_id']
        api = Format(request.data)
        api.parse()

        api_body = {
            'name': api.name,
            'body': api.testcase,
            'url': api.url,
            'method': api.method,
        }

        try:
            models.API.objects.filter(rig_id=pk).update(**api_body)
        except ObjectDoesNotExist:
            return Response(response.API_NOT_FOUND)
        return Response(response.API_UPDATE_SUCCESS)
Ejemplo n.º 28
0
class TestSuiteView(GenericViewSet):

    queryset = models.TestSuite.objects
    serializer_class = serializers.TestSuiteSerializer
    tag_options = {
        "冒烟用例集": 1,
        "集成用例集": 2,
        "监控脚本": 3
    }

    @staticmethod
    def testsuite_step_search(search):
        """
        搜索case_step的url或者name
        返回对应的case_id
        """
        case_id = models.TestSuiteStep.objects.filter(Q(name__contains=search) | Q(url__contains=search)).values('case_id')

        case_id = set([item['case_id'] for _, item in enumerate(case_id)])
        return case_id

    @method_decorator(request_log(level='INFO'))
    def get(self, request):
        """
        查询指定CASE列表,不包含CASE STEP
        {
            "project": int,
            "node": int
        }
        """
        ser = serializers.TestSuiteSearchSerializer(data=request.query_params)
        if ser.is_valid():
            node = ser.validated_data.get("node")
            project = ser.validated_data.get("project")
            search = ser.validated_data.get("search")
            search_type = ser.validated_data.get("searchType")
            case_type = ser.validated_data.get("caseType")
            only_me = ser.validated_data.get("onlyMe")

            # update_time 降序排列
            queryset = self.get_queryset().filter(project__id=project).order_by('-update_time')

            if only_me is True:
                queryset = queryset.filter(creator=request.user)

            if node != '':
                queryset = queryset.filter(relation=node)

            if case_type != '':
                queryset = queryset.filter(tag=case_type)

            if search != '':
                # 用例集名称搜索
                if search_type == '1':
                    queryset = queryset.filter(name__contains=search)
                # API名称或者API URL搜索
                elif search_type == '2':
                    case_id = self.testsuite_step_search(search)
                    queryset = queryset.filter(pk__in=case_id)

            pagination_query = self.paginate_queryset(queryset)
            serializer = self.get_serializer(pagination_query, many=True)

            return self.get_paginated_response(serializer.data)
        else:
            return Response(ser.errors, status=status.HTTP_400_BAD_REQUEST)
Ejemplo n.º 29
0
class APITemplateView(GenericViewSet):
    """
    API操作视图
    """
    serializer_class = serializers.APISerializer
    queryset = models.API.objects
    permission_classes = (DjangoModelPermissions, IsBelongToProject)

    @method_decorator(request_log(level='DEBUG'))
    def list(self, request):
        """
        接口列表 {
            project: int,
            node: int
        }
        """

        node = request.query_params["node"]
        project = request.query_params["project"]
        search = request.query_params["search"]
        queryset = self.get_queryset().filter(
            project__id=project).order_by('-update_time')

        if search != '':
            # queryset = queryset.filter(name__contains=search)
            queryset = queryset.filter(
                Q(name__contains=search) | Q(url__contains=search))

        if node != '':
            queryset = queryset.filter(relation=node)

        pagination_queryset = self.paginate_queryset(queryset)
        serializer = self.get_serializer(pagination_queryset, many=True)

        return self.get_paginated_response(serializer.data)

    @method_decorator(request_log(level='INFO'))
    def add(self, request):
        """添加或更新一个或多个接口

        """
        add_apis = []
        if request.data.get("bulk_add"):
            project_id = int(request.data.get("project"))
            node_id = int(request.data.get("nodeId"))
            temps = request.data.get("interfaces", {})
            for temp in temps.values():
                id = temp.get('id', 0)
                temp.update({"project": project_id, "nodeId": node_id})
                api = Format(temp)
                api.parse()

                api_body = {
                    'name': api.name,
                    'body': api.testcase,
                    'url': api.url,
                    'method': api.method,
                    'project': models.Project.objects.get(id=api.project),
                    'relation': api.relation
                }
                obj = models.API.objects.filter(id=id,
                                                relation=node_id,
                                                project=project_id)
                if obj:
                    obj.update(**api_body)
                else:
                    add_apis.append(models.API(**api_body))
        else:
            api = Format(request.data)
            api.parse()

            api_body = {
                'name': api.name,
                'body': api.testcase,
                'url': api.url,
                'method': api.method,
                'project': models.Project.objects.get(id=api.project),
                'relation': api.relation
            }
            add_apis.append(models.API(**api_body))
        try:
            if len(add_apis):
                models.API.objects.bulk_create(add_apis)
        except DataError:
            return Response(response.DATA_TO_LONG)
        except Exception as e:
            return Response({"error": str(e)})

        return Response(response.API_ADD_SUCCESS)

    @method_decorator(request_log(level='INFO'))
    def update(self, request, **kwargs):
        """
        更新接口
        """
        pk = kwargs['pk']
        api = Format(request.data)
        api.parse()

        api_body = {
            'name': api.name,
            'body': api.testcase,
            'url': api.url,
            'method': api.method,
        }

        try:
            models.API.objects.filter(id=pk).update(**api_body)
        except ObjectDoesNotExist:
            return Response(response.API_NOT_FOUND)

        return Response(response.API_UPDATE_SUCCESS)

    @method_decorator(request_log(level='INFO'))
    def copy(self, request, **kwargs):
        """
        pk int: test id
        {
            name: api name
        }
        """
        pk = kwargs['pk']
        name = request.data['name']
        api = models.API.objects.get(id=pk)
        body = eval(api.body)
        body["name"] = name
        api.body = body
        api.id = None
        api.name = name
        api.save()
        return Response(response.API_ADD_SUCCESS)

    @method_decorator(request_log(level='INFO'))
    def move(self, request, **kwargs):
        """移动接口到新的node

        """
        relation_id = request.data.get('relation')
        ids = request.data.get('ids', [])
        success, failure = [], []
        for id in ids:
            try:
                api = models.API.objects.get(id=id)
                api.relation = int(relation_id)
                api.save()
                success.append(id)
            except:
                failure.append(id)
        result = {
            'relation': relation_id,
            "success": success,
            'failure': failure
        }
        ret = response.API_MOVE_SUCCESS
        ret.update(result=result)
        return Response(ret)

    @method_decorator(request_log(level='INFO'))
    def delete(self, request, **kwargs):
        """
        删除一个接口 pk
        删除多个
        [{
            id:int
        }]
        """

        try:
            if kwargs.get('pk'):  # 单个删除
                api_end(kwargs['pk'])
            else:
                for content in request.data:
                    api_end(content['id'])

        except ObjectDoesNotExist:
            return Response(response.API_NOT_FOUND)

        return Response(response.API_DEL_SUCCESS)

    @method_decorator(request_log(level='INFO'))
    def single(self, request, **kwargs):
        """
        查询单个api,返回body信息
        """
        try:
            api = models.API.objects.get(id=kwargs['pk'])
        except ObjectDoesNotExist:
            return Response(response.API_NOT_FOUND)

        parse = Parse(eval(api.body))
        parse.parse_http()

        resp = {
            'id': api.id,
            'body': parse.testcase,
            'success': True,
        }

        return Response(resp)
Ejemplo n.º 30
0
class ProjectView(GenericViewSet):
    """
    项目增删改查
    """
    queryset = models.Project.objects.all().order_by('-update_time')
    serializer_class = serializers.ProjectSerializer
    pagination_class = pagination.MyCursorPagination

    @method_decorator(request_log(level='DEBUG'))
    def list(self, request):
        """
        查询项目信息
        """
        projects = self.get_queryset()
        page_projects = self.paginate_queryset(projects)
        serializer = self.get_serializer(page_projects, many=True)
        return self.get_paginated_response(serializer.data)

    @method_decorator(request_log(level='INFO'))
    def add(self, request):
        """添加项目 {
            name: str
        }
        """

        name = request.data["name"]

        if models.Project.objects.filter(name=name).first():
            response.PROJECT_EXISTS["name"] = name
            return Response(response.PROJECT_EXISTS)
        # 反序列化
        serializer = serializers.ProjectSerializer(data=request.data)

        if serializer.is_valid():
            serializer.save()
            project = models.Project.objects.get(name=name)
            prepare.project_init(project)
            return Response(response.PROJECT_ADD_SUCCESS)

        return Response(response.SYSTEM_ERROR)

    @method_decorator(request_log(level='INFO'))
    def update(self, request):
        """
        编辑项目
        """

        try:
            project = models.Project.objects.get(id=request.data['id'])
        except (KeyError, ObjectDoesNotExist):
            return Response(response.SYSTEM_ERROR)

        if request.data['name'] != project.name:
            if models.Project.objects.filter(
                    name=request.data['name']).first():
                return Response(response.PROJECT_EXISTS)

        # 调用save方法update_time字段才会自动更新
        project.name = request.data['name']
        project.desc = request.data['desc']
        project.responsible = request.data['responsible']
        project.yapi_base_url = request.data['yapi_base_url']
        project.yapi_openapi_token = request.data['yapi_openapi_token']
        project.save()

        return Response(response.PROJECT_UPDATE_SUCCESS)

    @method_decorator(request_log(level='INFO'))
    def delete(self, request):
        """
        删除项目
        """
        if request.user.is_superuser is False:
            return Response(status=status.HTTP_401_UNAUTHORIZED)
        try:
            project = models.Project.objects.get(id=request.data['id'])

            project.delete()
            prepare.project_end(project)

            return Response(response.PROJECT_DELETE_SUCCESS)
        except ObjectDoesNotExist:
            return Response(response.SYSTEM_ERROR)

    @method_decorator(request_log(level='INFO'))
    def single(self, request, **kwargs):
        """
        得到单个项目相关统计信息
        """
        pk = kwargs.pop('pk')

        try:
            queryset = models.Project.objects.get(id=pk)
        except ObjectDoesNotExist:
            return Response(response.PROJECT_NOT_EXISTS)

        serializer = self.get_serializer(queryset, many=False)

        project_info = prepare.get_project_detail(pk)
        project_info.update(serializer.data)

        return Response(project_info)