Exemplo n.º 1
0
    def add_issue(self,
                  issue_key,
                  issue_tracker,
                  summary=None,
                  description=None,
                  case_run=None,
                  link_external_tracker=False):
        """Add issue to case or case run

        :param str issue_key: issue key to add.
        :param issue_tracker: to which the issue is added.
        :type issue_tracker: :class:`IssueTracker`
        :param str summary: issue's summary. It's optional.
        :param str description: a longer description for the issue. It's
            optional.
        :param case_run: If specified, that means issue is added to a test case
            run and also associated with this case. If omitted, it just means
            issue is added to this case only.
        :type case_run: :class:`TestCaseRun`
        :param bool link_external_tracker: whether to add the issue to issue
            tracker's external tracker just after issue is added. Default to
            not to do that.
        :return: newly created issue. If issue already exists (checking the
            existence of issue key), nothing changes and just return
            immediately with None.
        :rtype: :class:`Issue`
        :raises ValueError: if passed case run is not associated with this case.

        .. versionchanged:: 4.2
           ``bug_id`` is replaced with ``issue_key``. ``bug_system_id`` is
           replaced with ``issue_tracker``.
        """
        if case_run and case_run.case != self:
            raise ValueError(
                'Case run {} is not associated with case {}'.format(
                    case_run, self))

        existing_issue = Issue.objects.filter(
            issue_key=issue_key,
            tracker=issue_tracker).only('issue_key').first()
        if existing_issue is not None:
            log.info('Issue %s already exist. Skip add.', issue_key)
            return existing_issue

        issue = Issue(issue_key=issue_key,
                      tracker=issue_tracker,
                      case=self,
                      case_run=case_run,
                      summary=summary,
                      description=description)
        issue.full_clean()
        issue.save()

        if link_external_tracker:
            service = find_service(issue_tracker)
            service.add_external_tracker(issue_key)

        return issue
Exemplo n.º 2
0
def attach_issue(request, values):
    """Add one or more issues to the selected test cases.

    :param dict values: a mapping containing these data to create a test run.

        * issue_key: (str) **Required** the issue key.
        * case_run: (int) **Required** ID of Case
        * tracker: (int) **Required** ID of issue tracker that issue should
          belong to.
        * summary: (str) optional issue's summary
        * description: (str) optional issue' description

    :return: a list which is empty on success or a list of mappings with
        failure codes if a failure occured.
    :rtype: list

    Example::

        # Attach an issue 67890 to case run 12345
        TestCaseRun.attach_issue({
                'case_run': [12345],
                'issue_key': '67890',
                'tracker': 1,
                'summary': 'Testing TCMS',
                'description': 'Just foo and bar',
            })

    .. versionchanged:: 4.2
       Some arguments passed via ``values`` are changed. ``case_run_id`` is
       changed to ``case_run``, ``bug_id`` is changed to ``issue_key``,
       ``bz_system_id`` is changed to ``tracker``. ``issue_key`` accepts string
       instead of integer. ``case_run`` within ``values`` must be a list of
       test case ids.
    """
    if isinstance(values, dict):
        values = [
            values,
        ]

    for value in values:
        form = CaseRunIssueForm(value)
        if form.is_valid():
            service = find_service(form.cleaned_data['tracker'])
            issue_key = form.cleaned_data['issue_key']
            summary = form.cleaned_data['summary']
            description = form.cleaned_data['description']
            case_runs = form.cleaned_data['case_run']
            for case_run in case_runs:
                service.add_issue(issue_key,
                                  case_run.case,
                                  case_run=case_run,
                                  summary=summary,
                                  description=description)
        else:
            raise ValueError(form_error_messags_to_list(form))
Exemplo n.º 3
0
def attach_issue(request, values):
    """Add one or more issues to the selected test cases.

    :param dict values: a mapping containing these data to create a test run.

        * issue_key: (str) **Required** the issue key.
        * case_run: (int) **Required** ID of Case
        * tracker: (int) **Required** ID of issue tracker that issue should
          belong to.
        * summary: (str) optional issue's summary
        * description: (str) optional issue' description

    :return: a list which is empty on success or a list of mappings with
        failure codes if a failure occured.
    :rtype: list

    Example::

        # Attach an issue 67890 to case run 12345
        >>> TestCaseRun.attach_issue({
                'case_run': [12345],
                'issue_key': '67890',
                'tracker': 1,
                'summary': 'Testing TCMS',
                'description': 'Just foo and bar',
            })

    .. versionchanged:: 4.2
       Some arguments passed via ``values`` are changed. ``case_run_id`` is
       changed to ``case_run``, ``bug_id`` is changed to ``issue_key``,
       ``bz_system_id`` is changed to ``tracker``. ``issue_key`` accepts string
       instead of integer. ``case_run`` within ``values`` must be a list of
       test case ids.
    """
    if isinstance(values, dict):
        values = [values, ]

    for value in values:
        form = CaseRunIssueForm(value)
        if form.is_valid():
            service = find_service(form.cleaned_data['tracker'])
            issue_key = form.cleaned_data['issue_key']
            summary = form.cleaned_data['summary']
            description = form.cleaned_data['description']
            case_runs = form.cleaned_data['case_run']
            for case_run in case_runs:
                service.add_issue(
                    issue_key,
                    case_run.case,
                    case_run=case_run,
                    summary=summary,
                    description=description)
        else:
            raise ValueError(form_error_messags_to_list(form))
Exemplo n.º 4
0
    def add_issue(self, issue_key, issue_tracker,
                  summary=None, description=None,
                  case_run=None, link_external_tracker=False):
        """Add issue to case or case run

        :param str issue_key: issue key to add.
        :param issue_tracker: to which the issue is added.
        :type issue_tracker: :class:`IssueTracker`
        :param str summary: issue's summary. It's optional.
        :param str description: a longer description for the issue. It's
            optional.
        :param case_run: If specified, that means issue is added to a test case
            run and also associated with this case. If omitted, it just means
            issue is added to this case only.
        :type case_run: :class:`TestCaseRun`
        :param bool link_external_tracker: whether to add the issue to issue
            tracker's external tracker just after issue is added. Default to
            not to do that.
        :return: newly created issue. If issue already exists (checking the
            existence of issue key), nothing changes and just return
            immediately with None.
        :rtype: :class:`Issue`
        :raises ValueError: if passed case run is not associated with this case.

        .. versionchanged:: 4.2
           ``bug_id`` is replaced with ``issue_key``. ``bug_system_id`` is
           replaced with ``issue_tracker``.
        """
        if case_run and case_run.case != self:
            raise ValueError('Case run {} is not associated with case {}'
                             .format(case_run, self))

        existing_issue = Issue.objects.filter(
            issue_key=issue_key, tracker=issue_tracker
        ).only('issue_key').first()
        if existing_issue is not None:
            log.info('Issue %s already exist. Skip add.', issue_key)
            return existing_issue

        issue = Issue(issue_key=issue_key,
                      tracker=issue_tracker,
                      case=self,
                      case_run=case_run,
                      summary=summary,
                      description=description)
        issue.full_clean()
        issue.save()

        if link_external_tracker:
            service = find_service(issue_tracker)
            service.add_external_tracker(issue_key)

        return issue
Exemplo n.º 5
0
        def add(self):
            # TODO: make a migration for the permission
            if not self.request.user.has_perm('issuetracker.add_issue'):
                return JsonResponse({'messages': ['Permission denied.']},
                                    status=http.HTTPStatus.FORBIDDEN)

            form = CaseRunIssueForm(request.GET)

            if not form.is_valid():
                msgs = form_error_messags_to_list(form)
                return JsonResponse({'messages': msgs},
                                    status=http.HTTPStatus.BAD_REQUEST)

            service = find_service(form.cleaned_data['tracker'])
            issue_key = form.cleaned_data['issue_key']
            link_et = form.cleaned_data['link_external_tracker']
            case_runs = form.cleaned_data['case_run']

            # FIXME: maybe, make sense to validate in the form.
            if not all(case_run.run_id == self.run.pk
                       for case_run in case_runs):
                return JsonResponse(
                    {
                        'messages':
                        [f'Not all case runs belong to run {self.run.pk}.']
                    },
                    status=http.HTTPStatus.BAD_REQUEST)

            try:
                for case_run in case_runs:
                    service.add_issue(issue_key,
                                      case_run.case,
                                      case_run=case_run,
                                      add_case_to_issue=link_et)
            except ValidationError as e:
                logger.exception(
                    'Failed to add issue to case run %s. Error reported: %s',
                    form.case_run.pk, str(e))
                return JsonResponse({'messages': [str(e)]},
                                    status=http.HTTPStatus.BAD_REQUEST)

            return self.run_issues_info(case_runs)
Exemplo n.º 6
0
        def add(self):
            # TODO: make a migration for the permission
            if not self.request.user.has_perm('issuetracker.add_issue'):
                return JsonResponse({'messages': ['Permission denied.']},
                                    status=http_client.FORBIDDEN)

            form = CaseRunIssueForm(request.GET)

            if not form.is_valid():
                msgs = form_error_messags_to_list(form)
                return JsonResponse({'messages': msgs}, status=http_client.BAD_REQUEST)

            service = find_service(form.cleaned_data['tracker'])
            issue_key = form.cleaned_data['issue_key']
            link_et = form.cleaned_data['link_external_tracker']
            case_runs = form.cleaned_data['case_run']

            # FIXME: maybe, make sense to validate in the form.
            if not all(case_run.run_id == self.run.pk for case_run in case_runs):
                return JsonResponse(
                    {'messages': [
                        'Not all case runs belong to run {}.'.format(self.run.pk)
                    ]},
                    status=http_client.BAD_REQUEST)

            try:
                for case_run in case_runs:
                    service.add_issue(issue_key,
                                      case_run.case,
                                      case_run=case_run,
                                      add_case_to_issue=link_et)
            except ValidationError as e:
                logger.exception(
                    'Failed to add issue to case run %s. Error reported: %s',
                    form.case_run.pk, str(e))
                return JsonResponse({'messages': [str(e)]}, status=http_client.BAD_REQUEST)

            return self.run_issues_info(case_runs)
Exemplo n.º 7
0
 def test_find_the_service(self):
     srv = services.find_service(self.issue_tracker_2)
     self.assertTrue(isinstance(srv, services.IssueTrackerService))
     self.assertEqual(self.issue_tracker_2, srv.tracker_model)
Exemplo n.º 8
0
    def get_context_data(self, **kwargs):
        """Generate report for specific TestRun

        There are four data source to generate this report.
        1. TestRun
        2. Test case runs included in the TestRun
        3. Comments associated with each test case run
        4. Statistics
        5. Issues
        """
        run_id = int(self.kwargs['run_id'])
        run = TestRun.objects.select_related('manager', 'plan').get(pk=run_id)
        case_runs = (TestCaseRun.objects.filter(run=run).select_related(
            'case_run_status', 'case', 'tested_by',
            'case__category').only('close_date', 'case_run_status__name',
                                   'case__category__name', 'case__summary',
                                   'case__is_automated',
                                   'case__is_automated_proposed',
                                   'tested_by__username'))
        comments = self.get_caseruns_comments(run.pk)

        run_stats = stats_case_runs_status([run.pk])[run.pk]

        run_issues = Issue.objects.filter(
            case_run__run=run_id).select_related('tracker')

        by_case_run_pk = attrgetter('case_run.pk')
        issues_by_case_run = {
            case_run_id:
            [(item.issue_key, item.get_absolute_url()) for item in issues]
            for case_run_id, issues in itertools.groupby(
                sorted(run_issues, key=by_case_run_pk), by_case_run_pk)
        }

        manual_count = 0
        automated_count = 0
        manual_automated_count = 0

        case_run: TestCaseRun
        for case_run in case_runs:
            case_run.display_issues = issues_by_case_run.get(case_run.pk, ())
            user_comments = comments.get(case_run.pk, [])
            case_run.user_comments = user_comments

            is_automated = case_run.case.is_automated
            if is_automated == 1:
                automated_count += 1
            elif is_automated == 0:
                manual_count += 1
            else:
                manual_automated_count += 1

        display_issues_by_tracker = [
            (tracker.name, find_service(tracker).make_issues_display_url(
                sorted(map(attrgetter('issue_key'), issues))))
            for tracker, issues in itertools.groupby(
                sorted(run_issues, key=attrgetter('tracker.pk')),
                attrgetter('tracker'))
        ]
        display_issues_by_tracker.sort(key=itemgetter(0))

        run_issues_display_info = [(issue.issue_key, issue.get_absolute_url())
                                   for issue in run_issues]

        context = super().get_context_data(**kwargs)
        context.update({
            'test_run': run,
            'test_case_runs': case_runs,
            'display_issues_by_tracker': display_issues_by_tracker,
            'test_case_runs_count': len(case_runs),
            'test_case_run_issues': run_issues_display_info,
            'test_case_run_mode_stats': {
                'manual': manual_count,
                'automated': automated_count,
                'manual_automated': manual_automated_count,
            },
            'test_run_stats': run_stats,
        })

        return context
Exemplo n.º 9
0
 def get_redirect_url(self, *args, **kwargs):
     case_run_id = self.kwargs['case_run_id']
     tracker_id = int(self.request.GET['issueTrackers'])
     case_run = get_object_or_404(TestCaseRun, pk=case_run_id)
     bz_model = IssueTracker.objects.get(pk=tracker_id)
     return find_service(bz_model).make_issue_report_url(case_run)
Exemplo n.º 10
0
 def test_find_the_service(self):
     srv = services.find_service(self.issue_tracker_2)
     self.assertTrue(isinstance(srv, services.IssueTrackerService))
     self.assertEqual(self.issue_tracker_2, srv.tracker_model)