コード例 #1
0
ファイル: views.py プロジェクト: MrSenko/Nitrate
    def _report_data_context(self):
        data = {}
        form = self._get_search_form()

        if form.is_valid():
            summary_header_data = super(CustomDetailReport,
                                        self)._report_data_context()
            data.update(summary_header_data)

            build_ids = [build['build'] for build in data['builds']]

            status_matrix = self.walk_matrix_row_by_row(
                self._data.generate_status_matrix(build_ids)
            )

            status_ids = (TestCaseRunStatus.id_failed(),)
            failed_case_runs = self.read_case_runs(build_ids, status_ids)

            status_ids = (TestCaseRunStatus.id_blocked(),)
            blocked_case_runs = self.read_case_runs(build_ids, status_ids)

            data.update({
                'status_matrix': status_matrix,
                'failed_case_runs': failed_case_runs,
                'blocked_case_runs': blocked_case_runs,
            })
        else:
            data['report_errors'] = form.errors

        data['form'] = form
        return data
コード例 #2
0
ファイル: views.py プロジェクト: tkdchen/Nitrate
    def _report_data_context(self):
        data = {}
        form = self._get_search_form()

        if form.is_valid():
            summary_header_data = super(CustomDetailReport,
                                        self)._report_data_context()
            data.update(summary_header_data)

            build_ids = [build.pk for build in data['builds']]
            # TODO: remove this after upgrading MySQL-python to 1.2.5
            build_ids = tuple(workaround_single_value_for_in_clause(build_ids))

            status_matrix = self.walk_matrix_row_by_row(
                self._data.generate_status_matrix(build_ids))

            # TODO: remove this after upgrading MySQL-python to 1.2.5
            status_ids = workaround_single_value_for_in_clause(
                (TestCaseRunStatus.name_to_id('FAILED'),))
            failed_case_runs = self.read_case_runs(build_ids, status_ids)
            # TODO: remove this after upgrading MySQL-python to 1.2.5
            status_ids = workaround_single_value_for_in_clause(
                (TestCaseRunStatus.name_to_id('BLOCKED'),))
            blocked_case_runs = self.read_case_runs(build_ids, status_ids)

            data.update({
                'status_matrix': status_matrix,
                'failed_case_runs': failed_case_runs,
                'blocked_case_runs': blocked_case_runs,
            })
        else:
            data['report_errors'] = form.errors

        data['form'] = form
        return data
コード例 #3
0
ファイル: views.py プロジェクト: zumbi/Nitrate
    def _report_data_context(self):
        data = {}
        form = self._get_search_form()

        if form.is_valid():
            summary_header_data = super(CustomDetailReport,
                                        self)._report_data_context()
            data.update(summary_header_data)

            build_ids = [build.pk for build in data['builds']]
            # TODO: remove this after upgrading MySQL-python to 1.2.5
            build_ids = workaround_single_value_for_in_clause(build_ids)

            status_matrix = self.walk_matrix_row_by_row(
                self._data.generate_status_matrix(build_ids))

            # TODO: remove this after upgrading MySQL-python to 1.2.5
            status_ids = workaround_single_value_for_in_clause(
                (TestCaseRunStatus.id_failed(), ))
            failed_case_runs = self.read_case_runs(build_ids, status_ids)
            # TODO: remove this after upgrading MySQL-python to 1.2.5
            status_ids = workaround_single_value_for_in_clause(
                (TestCaseRunStatus.id_blocked(), ))
            blocked_case_runs = self.read_case_runs(build_ids, status_ids)

            data.update({
                'status_matrix': status_matrix,
                'failed_case_runs': failed_case_runs,
                'blocked_case_runs': blocked_case_runs,
            })
        else:
            data['report_errors'] = form.errors

        data['form'] = form
        return data
コード例 #4
0
    def _report_data_context(self):
        data = {}
        form = self._get_search_form()

        if form.is_valid():
            summary_header_data = super(CustomDetailReport,
                                        self)._report_data_context()
            data.update(summary_header_data)

            build_ids = [build['build'] for build in data['builds']]

            status_matrix = self.walk_matrix_row_by_row(
                self._data.generate_status_matrix(build_ids)
            )

            status_ids = (TestCaseRunStatus.id_failed(),)
            failed_case_runs = self.read_case_runs(build_ids, status_ids)

            status_ids = (TestCaseRunStatus.id_blocked(),)
            blocked_case_runs = self.read_case_runs(build_ids, status_ids)

            data.update({
                'status_matrix': status_matrix,
                'failed_case_runs': failed_case_runs,
                'blocked_case_runs': blocked_case_runs,
            })
        else:
            data['report_errors'] = form.errors

        data['form'] = form
        return data
コード例 #5
0
ファイル: views.py プロジェクト: artjoman/Nitrate
def calculate_associated_data(runs: QuerySet) -> None:
    """Calculate associated data and set to each run in place

    The associated data include:

    * completed progress of each test run
    * the environment of each test run
    """
    run_ids = [run.pk for run in runs]
    qs = (TestCaseRun.objects.filter(
        case_run_status=TestCaseRunStatus.name_to_id('FAILED'),
        run__in=run_ids).values('run', 'case_run_status').annotate(
            count=Count('pk')).order_by('run', 'case_run_status'))
    failure_subtotal = magic_convert(qs, key_name='run', value_name='count')

    completed_status_ids = TestCaseRunStatus.completed_status_ids()
    qs = (TestCaseRun.objects.filter(
        case_run_status__in=completed_status_ids, run__in=run_ids).values(
            'run', 'case_run_status').annotate(count=Count('pk')).order_by(
                'run', 'case_run_status'))
    completed_subtotal = {
        run_id: sum((item['count'] for item in stats_rows))
        for run_id, stats_rows in itertools.groupby(qs.iterator(),
                                                    key=itemgetter('run'))
    }

    qs = (TestCaseRun.objects.filter(run__in=run_ids).values('run').annotate(
        cases_count=Count('case')))
    cases_subtotal = magic_convert(qs,
                                   key_name='run',
                                   value_name='cases_count')

    # Relative env groups to runs
    result = (TCMSEnvGroup.objects.filter(plans__run__in=run_ids).values(
        'plans__run', 'name'))
    runs_env_groups = {item['plans__run']: item['name'] for item in result}

    for run in runs:
        run_id = run.pk
        cases_count = cases_subtotal.get(run_id, 0)
        if cases_count:
            completed_percent = completed_subtotal.get(
                run_id, 0) * 1.0 / cases_count * 100
            failure_percent = failure_subtotal.get(run_id,
                                                   0) * 1.0 / cases_count * 100
        else:
            completed_percent = failure_percent = 0

        run.associated_data = {
            'stats': {
                'cases': cases_count,
                'completed_percent': completed_percent,
                'failure_percent': failure_percent,
            },
            'env_group': runs_env_groups.get(run_id),
        }
コード例 #6
0
    def get_context_data(self, **kwargs):
        data = super(TestingReportCaseRuns, self).get_context_data(**kwargs)

        query_args = self.request.GET
        form = self._get_form(query_args)

        if form.is_valid():
            test_case_runs = self.get_case_runs(form)
            status_names = TestCaseRunStatus.get_names()
            priority_values = Priority.get_values()

            testers_ids, assignees_ids = self._get_testers_assignees_ids(
                test_case_runs)
            testers = self.get_related_testers(testers_ids)
            assignees = self.get_related_assignees(assignees_ids)

            data['test_case_runs_count'] = len(test_case_runs)
            data['test_case_runs'] = self.walk_case_runs(test_case_runs,
                                                         status_names,
                                                         priority_values,
                                                         testers,
                                                         assignees)
        else:
            data['form_errors'] = form.errors

        return data
コード例 #7
0
ファイル: views.py プロジェクト: tkdchen/Nitrate
    def get_context_data(self, **kwargs):
        data = super(TestingReportCaseRuns, self).get_context_data(**kwargs)

        query_args = self.request.GET
        form = self._get_form(query_args)

        if form.is_valid():
            test_case_runs = self.get_case_runs(form)
            status_names = TestCaseRunStatus.as_dict()
            priority_values = Priority.get_values()

            testers_ids, assignees_ids = self._get_testers_assignees_ids(
                test_case_runs)
            testers = self.get_related_testers(testers_ids)
            assignees = self.get_related_assignees(assignees_ids)

            data['test_case_runs_count'] = len(test_case_runs)
            data['test_case_runs'] = self.walk_case_runs(test_case_runs,
                                                         status_names,
                                                         priority_values,
                                                         testers,
                                                         assignees)
        else:
            data['form_errors'] = form.errors

        return data
コード例 #8
0
def filter(query):  # pylint: disable=redefined-builtin
    """
    .. function:: XML-RPC TestCaseRunStatus.filter(query)

        Search and return the list of test case run statuses.

        :param query: Field lookups for :class:`tcms.testruns.models.TestCaseRunStatus`
        :type query: dict
        :return: Serialized list of :class:`tcms.testruns.models.TestCaseRunStatus` objects
        :rtype: list(dict)
    """
    return TestCaseRunStatus.to_xmlrpc(query)
コード例 #9
0
    def walk_case_runs():
        """Walking case runs for helping rendering case runs table"""
        priorities = dict(Priority.objects.values_list('pk', 'value'))
        testers, assignees = open_run_get_users(test_case_runs)
        comments_subtotal = open_run_get_comments_subtotal(
            [cr.pk for cr in test_case_runs])
        case_run_status = TestCaseRunStatus.get_names()

        for case_run in test_case_runs:
            yield (case_run, testers.get(case_run.tested_by_id, None),
                   assignees.get(case_run.assignee_id, None),
                   priorities.get(case_run.case.priority_id),
                   case_run_status[case_run.case_run_status_id],
                   comments_subtotal.get(case_run.pk, 0))
コード例 #10
0
    def walk_case_runs(self, test_case_runs):
        # todo: this is the same method as in testruns/views.py

        status_names = TestCaseRunStatus.get_names()
        priority_values = dict(Priority.objects.values_list('pk', 'value'))

        testers_ids, assignees_ids = _get_testers_assignees_ids(test_case_runs)
        testers = self.get_related_users(testers_ids)
        assignees = self.get_related_users(assignees_ids)

        for case_run in test_case_runs:
            status_name = status_names[case_run.case_run_status_id]
            priority_value = priority_values[case_run.case.priority_id]
            tester_username = testers.get(case_run.tested_by_id, None)
            assignee_username = assignees.get(case_run.assignee_id, None)
            yield case_run, status_name, priority_value, (
                case_run.assignee_id, assignee_username), (
                    case_run.tested_by_id, tester_username)
コード例 #11
0
ファイル: testcaserun.py プロジェクト: zhangqiusheng/Nitrate
def get_case_run_status(request, id=None):
    """
    Params:      $case_run_status_id - Integer(Optional): ID of the status to return

    Returns:     Hash: Matching case run status object hash when your specific the case_run_status_id
                       or return all of case run status.
                       It will return error the case run status you specific id not found.

    Example:
    # Get all of case run status
    >>> TestCaseRun.get_case_run_status()
    # Get case run status by ID 1
    >>> TestCaseRun.get_case_run_status(1)
    """
    if id:
        return TestCaseRunStatus.objects.get(id=id).serialize()

    return TestCaseRunStatus.to_xmlrpc()
コード例 #12
0
ファイル: testcaserun.py プロジェクト: Aaln1986/Nitrate
def get_case_run_status(request, id=None):
    """
    Params:      $case_run_status_id - Integer(Optional): ID of the status to return

    Returns:     Hash: Matching case run status object hash when your specific the case_run_status_id
                       or return all of case run status.
                       It will return error the case run status you specific id not found.

    Example:
    # Get all of case run status
    >>> TestCaseRun.get_case_run_status()
    # Get case run status by ID 1
    >>> TestCaseRun.get_case_run_status(1)
    """
    if id:
        return TestCaseRunStatus.objects.get(id=id).serialize()

    return TestCaseRunStatus.to_xmlrpc()
コード例 #13
0
ファイル: views.py プロジェクト: artjoman/Nitrate
    def walk_case_runs():
        """Walking case runs for helping rendering case runs table"""
        priorities = Priority.get_values()
        testers, assignees = open_run_get_users(tcrs)
        comments_subtotal = open_run_get_comments_subtotal(
            [cr.pk for cr in tcrs])
        case_run_status = TestCaseRunStatus.as_dict()
        issues_subtotal = tr.subtotal_issues_by_case_run()

        for case_run in tcrs:
            yield (
                case_run,
                testers.get(case_run.tested_by_id, None),
                assignees.get(case_run.assignee_id, None),
                priorities.get(case_run.case.priority_id),
                case_run_status[case_run.case_run_status_id],
                comments_subtotal.get(case_run.pk, 0),
                issues_subtotal.get(case_run.pk, 0),
            )
コード例 #14
0
ファイル: testcaserun.py プロジェクト: zumbi/Nitrate
def get_case_run_status(request, case_run_status_id=None):
    """Get case run status

    :param int case_run_status_id: optional case run status ID.
    :return: a mapping representing a case run status of specified ID.
        Otherwise, a list of mappings of all case run status will be returned,
        if ``case_run_status_id`` is omitted.
    :rtype: dict or list[dict]

    Example::

        # Get all of case run status
        >>> TestCaseRun.get_case_run_status()
        # Get case run status by ID 1
        >>> TestCaseRun.get_case_run_status(1)
    """
    if case_run_status_id:
        return TestCaseRunStatus.objects.get(pk=case_run_status_id).serialize()

    return TestCaseRunStatus.to_xmlrpc()
コード例 #15
0
ファイル: testcaserun.py プロジェクト: tkdchen/Nitrate
def get_case_run_status(request, case_run_status_id=None):
    """Get case run status

    :param int case_run_status_id: optional case run status ID.
    :return: a mapping representing a case run status of specified ID.
        Otherwise, a list of mappings of all case run status will be returned,
        if ``case_run_status_id`` is omitted.
    :rtype: dict or list[dict]

    Example::

        # Get all of case run status
        >>> TestCaseRun.get_case_run_status()
        # Get case run status by ID 1
        >>> TestCaseRun.get_case_run_status(1)
    """
    if case_run_status_id:
        return TestCaseRunStatus.objects.get(pk=case_run_status_id).serialize()

    return TestCaseRunStatus.to_xmlrpc()
コード例 #16
0
ファイル: data.py プロジェクト: hangnhat57/Kiwi
    def case_runs_filter_criteria(form):
        filter_criteria = {}

        priority = form.cleaned_data['priority']
        if priority:
            filter_criteria['case__priority__pk'] = priority

        tester = form.cleaned_data['tester']
        if tester is not None:
            if tester == 0:
                filter_criteria['tested_by'] = None
            else:
                filter_criteria['tested_by__pk'] = tester

        status = form.cleaned_data['status']
        if status:
            status_id = TestCaseRunStatus.get_names_ids()[status.upper()]
            filter_criteria['case_run_status'] = status_id

        return filter_criteria
コード例 #17
0
ファイル: data.py プロジェクト: MrSenko/Nitrate
    def case_runs_filter_criteria(self, form):
        filter_criteria = {}

        priority = form.cleaned_data['priority']
        if priority:
            filter_criteria['case__priority__pk'] = priority

        tester = form.cleaned_data['tester']
        if tester is not None:
            if tester == 0:
                filter_criteria['tested_by'] = None
            else:
                filter_criteria['tested_by__pk'] = tester

        status = form.cleaned_data['status']
        if status:
            status_id = TestCaseRunStatus.get_names_ids()[status.upper()]
            filter_criteria['case_run_status'] = status_id

        return filter_criteria
コード例 #18
0
def update_case_run_status(request):
    """Update Case Run status."""
    now = datetime.datetime.now()

    data = request.POST.copy()
    ctype = data.get("content_type")
    vtype = data.get('value_type', 'str')
    object_pk_str = data.get("object_pk")
    field = data.get('field')
    value = data.get('value')

    object_pk = [int(a) for a in object_pk_str.split(',')]

    if not field or not value or not object_pk or not ctype:
        return JsonResponseBadRequest({
            'message':
            'Following fields are required - '
            'content_type, object_pk, field and value.'
        })

    # Convert the value type
    # FIXME: Django bug here: update() keywords must be strings
    field = str(field)

    value, error = get_value_by_type(value, vtype)
    if error:
        return JsonResponseBadRequest({'message': error})
    has_perms = check_permission(request, ctype)
    if not has_perms:
        return JsonResponseForbidden({'message': 'Permission Denied.'})

    model = utils.get_model(ctype)
    targets = model._default_manager.filter(pk__in=object_pk)

    if not targets:
        return JsonResponseBadRequest({'message': 'No record found'})
    if not hasattr(targets[0], field):
        return JsonResponseBadRequest(
            {'message': f'{ctype} has no field {field}'})

    if hasattr(targets[0], 'log_action'):
        for t in targets:
            try:
                t.log_action(who=request.user,
                             field=field,
                             original_value=getattr(t, field),
                             new_value=TestCaseRunStatus.id_to_name(value))
            except (AttributeError, User.DoesNotExist):
                pass
    objects_update(targets, **{field: value})

    if hasattr(model, 'mail_scene'):
        from tcms.core.mailto import mailto

        mail_context = model.mail_scene(
            objects=targets,
            field=field,
            value=value,
            ctype=ctype,
            object_pk=object_pk,
        )
        if mail_context:
            mail_context['context']['user'] = request.user
            mailto(**mail_context)

    # Special hacking for updating test case run status
    if ctype == 'testruns.testcaserun' and field == 'case_run_status':
        for t in targets:
            field = 'close_date'
            t.log_action(who=request.user,
                         field=field,
                         original_value=getattr(t, field) or '',
                         new_value=now)
            if t.tested_by != request.user:
                field = 'tested_by'
                t.log_action(who=request.user,
                             field=field,
                             original_value=getattr(t, field) or '',
                             new_value=request.user)

            field = 'assignee'
            try:
                assignee = t.assginee
                if assignee != request.user:
                    t.log_action(who=request.user,
                                 field=field,
                                 original_value=getattr(t, field) or '',
                                 new_value=request.user)
                    # t.assignee = request.user
                t.save()
            except (AttributeError, User.DoesNotExist):
                pass
        targets.update(close_date=now, tested_by=request.user)

    return JsonResponse({})
コード例 #19
0
ファイル: ajax.py プロジェクト: rmoorman/Kiwi
def update_case_run_status(request):
    '''
    Update Case Run status.
    '''
    now = datetime.datetime.now()

    data = request.POST.copy()
    ctype = data.get("content_type")
    vtype = data.get('value_type', 'str')
    object_pk_str = data.get("object_pk")
    field = data.get('field')
    value = data.get('value')

    object_pk = [int(a) for a in object_pk_str.split(',')]

    if not field or not value or not object_pk or not ctype:
        return say_no('Following fields are required - content_type, '
                      'object_pk, field and value.')

    # Convert the value type
    # FIXME: Django bug here: update() keywords must be strings
    field = str(field)

    value, error = get_value_by_type(value, vtype)
    if error:
        return say_no(error)
    has_perms = check_permission(request, ctype)
    if not has_perms:
        return say_no('Permission Dinied.')

    model = apps.get_model(*ctype.split(".", 1))
    targets = model._default_manager.filter(pk__in=object_pk)

    if not targets:
        return say_no('No record found')
    if not hasattr(targets[0], field):
        return say_no('%s has no field %s' % (ctype, field))

    if hasattr(targets[0], 'log_action'):
        for t in targets:
            try:
                t.log_action(who=request.user,
                             action='Field {} changed from {} to {}.'.format(
                                 field,
                                 getattr(t, field),
                                 TestCaseRunStatus.id_to_string(value),
                             ))
            except (AttributeError, User.DoesNotExist):
                pass
    objects_update(targets, **{field: value})

    if hasattr(model, 'mail_scene'):
        from tcms.core.utils.mailto import mailto

        mail_context = model.mail_scene(
            objects=targets,
            field=field,
            value=value,
            ctype=ctype,
            object_pk=object_pk,
        )
        if mail_context:
            mail_context['context']['user'] = request.user
            try:
                mailto(**mail_context)
            except Exception:
                pass

    # Special hacking for updating test case run status
    if ctype == 'testruns.testcaserun' and field == 'case_run_status':
        for t in targets:
            field = 'close_date'
            t.log_action(who=request.user,
                         action='Field %s changed from %s to %s.' %
                         (field, getattr(t, field), now))
            if t.tested_by != request.user:
                field = 'tested_by'
                t.log_action(who=request.user,
                             action='Field %s changed from %s to %s.' %
                             (field, getattr(t, field), request.user))

            field = 'assignee'
            try:
                assignee = t.assginee
                if assignee != request.user:
                    t.log_action(who=request.user,
                                 action='Field %s changed from %s to %s.' %
                                 (field, getattr(t, field), request.user))
                    # t.assignee = request.user
                t.save()
            except (AttributeError, User.DoesNotExist):
                pass
        targets.update(close_date=now, tested_by=request.user)

    return HttpResponse(json.dumps({'rc': 0, 'response': 'ok'}))
コード例 #20
0
ファイル: views.py プロジェクト: zumbi/Nitrate
    def _report_data_context(self):
        form = self._get_search_form()
        context = {'form': form}

        if not form.is_valid():
            context.update({'builds': ()})
            return context

        _data = self.data_class(form)
        self._data = _data

        builds = _data._get_builds()
        build_ids = [build.pk for build in builds]

        # TODO: remove this after upgrading MySQL-python to 1.2.5
        build_ids = workaround_single_value_for_in_clause(build_ids)

        if build_ids:
            # Summary header data
            runs_subtotal = _data.runs_subtotal()
            plans_subtotal = _data.plans_subtotal()
            case_runs_subtotal = _data.case_runs_subtotal()
            isautomated_subtotal = _data.cases_isautomated_subtotal()

            # Staus matrix used to render progress bar for each build
            case_runs_status_matrix = _data.status_matrix()

            status_names_ids = TestCaseRunStatus.get_names_ids()
            # FIXME: this would raise KeyError once status names are modified
            # to other ones.
            passed_id = status_names_ids['PASSED']
            failed_id = status_names_ids['FAILED']

            for build in builds:
                bid = build.pk
                build.runs_count = runs_subtotal.get(bid, 0)
                build.plans_count = plans_subtotal.get(bid, 0)
                build.case_runs_count = case_runs_subtotal.get(bid, 0)

                status_subtotal = case_runs_status_matrix.get(bid, {})
                passed_count = status_subtotal.get(passed_id, 0)
                failed_count = status_subtotal.get(failed_id, 0)

                c = case_runs_subtotal.get(bid, 0)

                if c:
                    build.passed_case_runs_percent = passed_count * 100.0 / c
                    build.failed_case_runs_percent = failed_count * 100.0 / c
                else:
                    build.passed_case_runs_percent = .0
                    build.failed_case_runs_percent = .0

                build.passed_case_runs_count = passed_count
                build.failed_case_runs_count = failed_count
                build.case_runs_count = c

            context.update({
                # TODO: replace following three TOTAL key lookup with total
                # method invocation.
                'total_runs_count': runs_subtotal.get('TOTAL', 0),
                'total_plans_count': plans_subtotal.get('TOTAL', 0),
                'total_count': isautomated_subtotal.get('TOTAL', 0),
                'manual_count': isautomated_subtotal.get(0, 0),
                'auto_count': isautomated_subtotal.get(1, 0),
                'both_count': isautomated_subtotal.get(2, 0),
            })

        context.update({'builds': builds})
        return context
コード例 #21
0
def load_runs_of_one_plan(request,
                          plan_id,
                          template_name='plan/common/json_plan_runs.txt'):
    """A dedicated view to return a set of runs of a plan

    This view is used in a plan detail page, for the contained testrun tab. It
    replaces the original solution, with a paginated resultset in return,
    serves as a performance healing. Also, in order for user to locate the
    data, it accepts field lookup parameters collected from the filter panel
    in the UI.
    """
    column_names = [
        '',
        'run_id',
        'summary',
        'manager__username',
        'default_tester__username',
        'start_date',
        'build__name',
        'stop_date',
        'total_num_caseruns',
        'failure_caseruns_percent',
        'successful_caseruns_percent',
    ]

    test_plan = TestPlan.objects.get(plan_id=plan_id)
    form = PlanFilterRunForm(request.GET)

    if form.is_valid():
        queryset = test_plan.run.filter(**form.cleaned_data)
        queryset = queryset.select_related('build', 'manager',
                                           'default_tester').order_by('-pk')

        data_table_result = DataTableResult(request.GET, queryset,
                                            column_names)
        response_data = data_table_result.get_response_data()
        searched_runs = response_data['querySet']

        # Get associated statistics data
        run_filters = dict(('run__{0}'.format(key), value)
                           for key, value in form.cleaned_data.items())

        query_set = TestCaseRun.objects.filter(
            case_run_status=TestCaseRunStatus.id_failed(),
            **run_filters).values('run', 'case_run_status').annotate(
                count=Count('pk')).order_by('run', 'case_run_status')
        failure_subtotal = magic_convert(query_set,
                                         key_name='run',
                                         value_name='count')

        query_set = TestCaseRun.objects.filter(
            case_run_status=TestCaseRunStatus.id_passed(),
            **run_filters).values('run', 'case_run_status').annotate(
                count=Count('pk')).order_by('run', 'case_run_status')
        success_subtotal = magic_convert(query_set,
                                         key_name='run',
                                         value_name='count')

        query_set = TestCaseRun.objects.filter(
            **run_filters).values('run').annotate(
                count=Count('case')).order_by('run')
        cases_subtotal = magic_convert(query_set,
                                       key_name='run',
                                       value_name='count')

        for run in searched_runs:
            run_id = run.pk
            cases_count = cases_subtotal.get(run_id, 0)
            if cases_count:
                failure_percent = failure_subtotal.get(
                    run_id, 0) * 1.0 / cases_count * 100
                success_percent = success_subtotal.get(
                    run_id, 0) * 1.0 / cases_count * 100
            else:
                failure_percent = success_percent = 0
            run.nitrate_stats = {
                'cases': cases_count,
                'failure_percent': failure_percent,
                'success_percent': success_percent,
            }
    else:
        response_data = {
            'sEcho': int(request.GET.get('sEcho', 0)),
            'iTotalRecords': 0,
            'iTotalDisplayRecords': 0,
            'querySet': TestRun.objects.none(),
        }

    json_data = render_to_string(template_name, response_data, request=request)
    return HttpResponse(json_data, content_type='application/json')
コード例 #22
0
ファイル: views.py プロジェクト: tkdchen/Nitrate
    def _report_data_context(self):
        form = self._get_search_form()
        context = {'form': form}

        if not form.is_valid():
            context.update({'builds': ()})
            return context

        _data = self.data_class(form)
        self._data = _data

        builds = _data._get_builds()
        build_ids = [build.pk for build in builds]

        # TODO: remove this after upgrading MySQL-python to 1.2.5
        build_ids = workaround_single_value_for_in_clause(build_ids)

        if build_ids:
            # Summary header data
            runs_subtotal = _data.runs_subtotal()
            plans_subtotal = _data.plans_subtotal()
            case_runs_subtotal = _data.case_runs_subtotal()
            isautomated_subtotal = _data.cases_isautomated_subtotal()

            # Staus matrix used to render progress bar for each build
            case_runs_status_matrix = _data.status_matrix()

            # FIXME: this would raise KeyError once status names are modified
            # to other ones.
            passed_id = TestCaseRunStatus.name_to_id('PASSED')
            failed_id = TestCaseRunStatus.name_to_id('FAILED')

            for build in builds:
                bid = build.pk
                build.runs_count = runs_subtotal.get(bid, 0)
                build.plans_count = plans_subtotal.get(bid, 0)
                build.case_runs_count = case_runs_subtotal.get(bid, 0)

                status_subtotal = case_runs_status_matrix.get(bid, {})
                passed_count = status_subtotal.get(passed_id, 0)
                failed_count = status_subtotal.get(failed_id, 0)

                c = case_runs_subtotal.get(bid, 0)

                if c:
                    build.passed_case_runs_percent = passed_count * 100.0 / c
                    build.failed_case_runs_percent = failed_count * 100.0 / c
                else:
                    build.passed_case_runs_percent = .0
                    build.failed_case_runs_percent = .0

                build.passed_case_runs_count = passed_count
                build.failed_case_runs_count = failed_count
                build.case_runs_count = c

            context.update({
                # method invocation.
                'total_runs_count': runs_subtotal.total,
                'total_plans_count': plans_subtotal.total,
                'total_count': isautomated_subtotal.total,
                'manual_count': isautomated_subtotal.get(0, 0),
                'auto_count': isautomated_subtotal.get(1, 0),
                'both_count': isautomated_subtotal.get(2, 0),
            })

        context.update({'builds': builds})
        return context
コード例 #23
0
ファイル: ajax.py プロジェクト: tkdchen/Nitrate
def update_case_run_status(request):
    """Update Case Run status."""
    now = datetime.datetime.now()

    data = request.POST.copy()
    ctype = data.get("content_type")
    vtype = data.get('value_type', 'str')
    object_pk_str = data.get("object_pk")
    field = data.get('field')
    value = data.get('value')

    object_pk = [int(a) for a in object_pk_str.split(',')]

    if not field or not value or not object_pk or not ctype:
        return say_no(
            'Following fields are required - content_type, '
            'object_pk, field and value.')

    # Convert the value type
    # FIXME: Django bug here: update() keywords must be strings
    field = str(field)

    value, error = get_value_by_type(value, vtype)
    if error:
        return say_no(error)
    has_perms = check_permission(request, ctype)
    if not has_perms:
        return say_no('Permission Dinied.')

    model = utils.get_model(ctype)
    targets = model._default_manager.filter(pk__in=object_pk)

    if not targets:
        return say_no('No record found')
    if not hasattr(targets[0], field):
        return say_no('%s has no field %s' % (ctype, field))

    if hasattr(targets[0], 'log_action'):
        for t in targets:
            try:
                t.log_action(
                    who=request.user,
                    field=field,
                    original_value=getattr(t, field),
                    new_value=TestCaseRunStatus.id_to_name(value))
            except (AttributeError, User.DoesNotExist):
                pass
    objects_update(targets, **{field: value})

    if hasattr(model, 'mail_scene'):
        from tcms.core.utils.mailto import mailto

        mail_context = model.mail_scene(
            objects=targets, field=field, value=value, ctype=ctype,
            object_pk=object_pk,
        )
        if mail_context:
            mail_context['context']['user'] = request.user
            mailto(**mail_context)

    # Special hacking for updating test case run status
    if ctype == 'testruns.testcaserun' and field == 'case_run_status':
        for t in targets:
            field = 'close_date'
            t.log_action(
                who=request.user,
                field=field,
                original_value=getattr(t, field) or '',
                new_value=now)
            if t.tested_by != request.user:
                field = 'tested_by'
                t.log_action(
                    who=request.user,
                    field=field,
                    original_value=getattr(t, field) or '',
                    new_value=request.user)

            field = 'assignee'
            try:
                assignee = t.assginee
                if assignee != request.user:
                    t.log_action(
                        who=request.user,
                        field=field,
                        original_value=getattr(t, field) or '',
                        new_value=request.user)
                    # t.assignee = request.user
                t.save()
            except (AttributeError, User.DoesNotExist):
                pass
        targets.update(close_date=now, tested_by=request.user)

    return HttpResponse(json.dumps({'rc': 0, 'response': 'ok'}))