Example #1
0
 def validate(self, value):
     super(DurationField, self).validate(value)
     try:
         from tcms.xmlrpc.utils import pre_process_estimated_time
         pre_process_estimated_time(value)
     except ValueError:
         raise forms.ValidationError(self.error_messages['invalid'])
Example #2
0
 def test_pre_process_estimated_time_with_upper_string(self):
     try:
         U.pre_process_estimated_time("1D13H22M54S")
     except ValueError as e:
         self.assertEqual(str(e), 'Invaild estimated_time format.')
     except Exception:
         self.fail("Unexcept error occurs.")
     else:
         self.fail("Missing validations.")
Example #3
0
 def test_pre_process_estimated_time_with_upper_string(self):
     try:
         U.pre_process_estimated_time("1D13H22M54S")
     except ValueError as e:
         self.assertEqual(str(e), 'Invaild estimated_time format.')
     except Exception:
         self.fail("Unexcept error occurs.")
     else:
         self.fail("Missing validations.")
Example #4
0
 def test_pre_process_estimated_time_with_symbols(self):
     try:
         U.pre_process_estimated_time("aa@bb@cc")
     except ValueError as e:
         self.assertEqual(str(e), 'Invaild estimated_time format.')
     except Exception:
         self.fail("Unexcept error occurs.")
     else:
         self.fail("Missing validations.")
Example #5
0
 def test_pre_process_estimated_time_with_symbols(self):
     try:
         U.pre_process_estimated_time("aa@bb@cc")
     except ValueError as e:
         self.assertEqual(str(e), 'Invaild estimated_time format.')
     except Exception:
         self.fail("Unexcept error occurs.")
     else:
         self.fail("Missing validations.")
Example #6
0
 def test_pre_process_estimated_time(self):
     bad_args = ([], (), {}, True, False, 0, 1, -1)
     for arg in bad_args:
         try:
             U.pre_process_estimated_time(arg)
         except ValueError as e:
             self.assertEqual(str(e), 'Invaild estimated_time format.')
         except Exception:
             self.fail("Unexcept error occurs.")
         else:
             self.fail("Missing validations.")
Example #7
0
 def test_pre_process_estimated_time(self):
     bad_args = ([], (), {}, True, False, 0, 1, -1)
     for arg in bad_args:
         try:
             U.pre_process_estimated_time(arg)
         except ValueError as e:
             self.assertEqual(str(e), 'Invaild estimated_time format.')
         except Exception:
             self.fail("Unexcept error occurs.")
         else:
             self.fail("Missing validations.")
Example #8
0
    def test_pre_process_estimated_time_with_time_string(self):
        try:
            time = U.pre_process_estimated_time("13:22:54")
        except Exception:
            self.fail("Unexcept error occurs.")
        else:
            self.assertEqual(time, "13h22m54s")

        try:
            time = U.pre_process_estimated_time("1d13h22m54s")
        except Exception:
            self.fail("Unexcept error occurs.")
        else:
            self.assertEqual(time, "1d13h22m54s")
Example #9
0
    def test_pre_process_estimated_time_with_time_string(self):
        try:
            time = U.pre_process_estimated_time("13:22:54")
        except Exception:
            self.fail("Unexcept error occurs.")
        else:
            self.assertEqual(time, "13h22m54s")

        try:
            time = U.pre_process_estimated_time("1d13h22m54s")
        except Exception:
            self.fail("Unexcept error occurs.")
        else:
            self.assertEqual(time, "1d13h22m54s")
Example #10
0
def update(case_id, values, **kwargs):
    """
    .. function:: XML-RPC TestCase.update(case_id, values)

        Update the fields of the selected test case.

        :param case_id: PK of TestCase to be modified
        :type case_id: int
        :param values: Field values for :class:`tcms.testcases.models.TestCase`.
                       The special keys ``setup``, ``breakdown``, ``action`` and
                       ``effect`` are recognized and will cause update of the underlying
                       :class:`tcms.testcases.models.TestCaseText` object!
        :type values: dict
        :return: Serialized :class:`tcms.testcases.models.TestCase` object
        :rtype: dict
        :raises: TestCase.DoesNotExist if object specified by PK doesn't exist
        :raises: PermissionDenied if missing *testcases.change_testcase* permission
    """
    if values.get('estimated_time'):
        values['estimated_time'] = pre_process_estimated_time(
            values.get('estimated_time'))

    form = UpdateCaseForm(values)

    if values.get('category') and not values.get('product'):
        raise ValueError('Product ID is required for category')

    if values.get('product'):
        form.populate(product_id=values['product'])

    if form.is_valid():
        tc = TestCase.objects.get(pk=case_id)
        for key in values.keys():
            # only modify attributes that were passed via parameters
            # skip attributes which are Many-to-Many relations
            if key not in ['component', 'tag'] and hasattr(tc, key):
                setattr(tc, key, form.cleaned_data[key])
        tc.save()

        # if we're updating the text if any one of these parameters was
        # specified
        if any(x in ['setup', 'action', 'effect', 'breakdown']
               for x in values.keys()):
            action = form.cleaned_data.get('action', '').strip()
            effect = form.cleaned_data.get('effect', '').strip()
            setup = form.cleaned_data.get('setup', '').strip()
            breakdown = form.cleaned_data.get('breakdown', '').strip()
            author = kwargs.get(REQUEST_KEY).user

            tc.add_text(
                author=author,
                action=action,
                effect=effect,
                setup=setup,
                breakdown=breakdown,
            )
    else:
        raise ValueError(form_errors_to_list(form))

    return tc.serialize()
Example #11
0
def filter(query):
    """
    .. function:: XML-RPC TestCase.filter(query)

        Perform a search and return the resulting list of test cases
        augmented with their latest ``text``.

        :param query: Field lookups for :class:`tcms.testcases.models.TestCase`
        :type query: dict
        :return: Serialized list of :class:`tcms.testcases.models.TestCase` objects.
                 The key ``text`` holds a the latest version of a serialized
                 :class:`tcms.testcases.models.TestCaseText` object!
        :rtype: list(dict)
    """
    if query.get('estimated_time'):
        query['estimated_time'] = timedelta2int(
            pre_process_estimated_time(query.get('estimated_time')))

    results = []
    for case in TestCase.objects.filter(**query):
        serialized_case = case.serialize()
        serialized_case['text'] = case.latest_text().serialize()
        results.append(serialized_case)

    return results
Example #12
0
def update(request, case_ids, values):
    """Updates the fields of the selected case or cases.

                 $values   - Hash of keys matching TestCase fields and the new values
                             to set each field to.

    :param case_ids: give one or more case IDs. It could be an integer, a
        string containing comma separated IDs, or a list of int each of them is
        a case ID.
    :type case_ids: int, str or list
    :param dict values: a mapping containing these case data to update.

        * case_status: (ini) optional
        * product: (ini) optional (Required if changes category)
        * category: (ini) optional
        * priority: (ini) optional
        * default_tester: (str or int) optional (str - user_name, int - user_id)
        * estimated_time: (str) optional (2h30m30s(recommend) or HH:MM:SS
        * is_automated: (ini) optional (0 - Manual, 1 - Auto, 2 - Both)
        * is_automated_proposed: (bool) optional
        * script: (str) optional
        * arguments: (str) optional
        * summary: (str) optional
        * requirement: (str) optional
        * alias: (str) optional
        * notes: (str) optional
        * extra_link: (str) optional (reference link)

    :return: a list of mappings of updated :class:`TestCase`.
    :rtype: list(dict)

    Example::

        # Update alias to 'tcms' for case 1 and 2
        TestCase.update([1, 2], {'alias': 'tcms'})
    """
    from tcms.core import forms
    from tcms.xmlrpc.forms import UpdateCaseForm

    if values.get('estimated_time'):
        values['estimated_time'] = pre_process_estimated_time(values.get('estimated_time'))

    form = UpdateCaseForm(values)

    if values.get('category') and not values.get('product'):
        raise ValueError('Product ID is required for category')

    if values.get('product'):
        form.populate(product_id=values['product'])

    if form.is_valid():
        tcs = TestCase.update(
            case_ids=pre_process_ids(value=case_ids),
            values=form.cleaned_data,
        )
    else:
        raise ValueError(forms.errors_to_list(form))

    query = {'pk__in': tcs.values_list('pk', flat=True)}
    return TestCase.to_xmlrpc(query)
Example #13
0
def update(request, case_ids, values):
    """Updates the fields of the selected case or cases.

                 $values   - Hash of keys matching TestCase fields and the new values
                             to set each field to.

    :param case_ids: give one or more case IDs. It could be an integer, a
        string containing comma separated IDs, or a list of int each of them is
        a case ID.
    :type case_ids: int, str or list
    :param dict values: a mapping containing these case data to update.

        * case_status: (ini) optional
        * product: (ini) optional (Required if changes category)
        * category: (ini) optional
        * priority: (ini) optional
        * default_tester: (str or int) optional (str - user_name, int - user_id)
        * estimated_time: (str) optional (2h30m30s(recommend) or HH:MM:SS
        * is_automated: (ini) optional (0 - Manual, 1 - Auto, 2 - Both)
        * is_automated_proposed: (bool) optional
        * script: (str) optional
        * arguments: (str) optional
        * summary: (str) optional
        * requirement: (str) optional
        * alias: (str) optional
        * notes: (str) optional
        * extra_link: (str) optional (reference link)

    :return: a list of mappings of updated :class:`TestCase`.
    :rtype: list(dict)

    Example::

        # Update alias to 'tcms' for case 1 and 2
        >>> TestCase.update([1, 2], {'alias': 'tcms'})
    """
    from tcms.core import forms
    from tcms.xmlrpc.forms import UpdateCaseForm

    if values.get('estimated_time'):
        values['estimated_time'] = pre_process_estimated_time(values.get('estimated_time'))

    form = UpdateCaseForm(values)

    if values.get('category') and not values.get('product'):
        raise ValueError('Product ID is required for category')

    if values.get('product'):
        form.populate(product_id=values['product'])

    if form.is_valid():
        tcs = TestCase.update(
            case_ids=pre_process_ids(value=case_ids),
            values=form.cleaned_data,
        )
    else:
        raise ValueError(forms.errors_to_list(form))

    query = {'pk__in': tcs.values_list('pk', flat=True)}
    return TestCase.to_xmlrpc(query)
Example #14
0
def create(values, **kwargs):
    """
    .. function:: XML-RPC TestCase.create(values)

        Create a new TestCase object and store it in the database.

        :param values: Field values for :class:`tcms.testcases.models.TestCase`
        :type values: dict
        :return: Serialized :class:`tcms.testcases.models.TestCase` object
        :rtype: dict
        :raises: PermissionDenied if missing *testcases.add_testcase* permission

        Minimal test case parameters::

            >>> values = {
                'category': 135,
                'product': 61,
            'summary': 'Testing XML-RPC',
            'priority': 1,
            }
            >>> TestCase.create(values)
    """
    request = kwargs.get(REQUEST_KEY)

    if not (values.get('category') or values.get('summary')):
        raise ValueError()

    if values.get('estimated_time'):
        values['estimated_time'] = pre_process_estimated_time(
            values.get('estimated_time'))

    form = NewCaseForm(values)
    form.populate(values.get('product'))

    if form.is_valid():
        # Create the case
        tc = TestCase.create(author=request.user, values=form.cleaned_data)

        # Add case text to the case
        tc.add_text(
            action=form.cleaned_data['action'] or '',
            effect=form.cleaned_data['effect'] or '',
            setup=form.cleaned_data['setup'] or '',
            breakdown=form.cleaned_data['breakdown'] or '',
        )

        # Add tag to the case
        for tag in string_to_list(values.get('tag', [])):
            t, c = TestTag.objects.get_or_create(name=tag)
            tc.add_tag(tag=t)
    else:
        # Print the errors if the form is not passed validation.
        raise ValueError(form_errors_to_list(form))

    result = tc.serialize()
    result['text'] = tc.latest_text().serialize()

    return result
Example #15
0
def filter(request, query):
    """
    Description: Performs a search and returns the resulting list of test cases.

    Params:      $query - Hash: keys must match valid search fields.

        +------------------------------------------------------------------+
        |                 Case Search Parameters                           |
        +------------------------------------------------------------------+
        |        Key          |          Valid Values                      |
        | author              | A bugzilla login (email address)           |
        | attachment          | ForeignKey: Attchment                      |
        | alias               | String                                     |
        | case_id             | Integer                                    |
        | case_status         | ForeignKey: Case Stat                      |
        | category            | ForeignKey: Category                       |
        | component           | ForeignKey: Component                      |
        | default_tester      | ForeignKey: Auth.User                      |
        | estimated_time      | String: 2h30m30s(recommend) or HH:MM:SS    |
        | plan                | ForeignKey: Test Plan                      |
        | priority            | ForeignKey: Priority                       |
        | category__product   | ForeignKey: Product                        |
        | summary             | String                                     |
        | tags                | ForeignKey: Tags                           |
        | create_date         | Datetime                                   |
        | is_automated        | 1: Only show current 0: show not current   |
        | script              | Text                                       |
        +------------------------------------------------------------------+

    Returns:     Array: Matching test cases are retuned in a list of hashes.

    Example:
    # Get all of cases contain 'TCMS' in summary
    >>> TestCase.filter({'summary__icontain': 'TCMS'})
    # Get all of cases create by xkuang
    >>> TestCase.filter({'author__username': '******'})
    # Get all of cases the author name starts with x
    >>> TestCase.filter({'author__username__startswith': 'x'})
    # Get all of cases belong to the plan 137
    >>> TestCase.filter({'plan__plan_id': 137})
    # Get all of cases belong to the plan create by xkuang
    >>> TestCase.filter({'plan__author__username': '******'})
    # Get cases with ID 12345, 23456, 34567 - Here is only support array so far.
    >>> TestCase.filter({'case_id__in': [12345, 23456, 34567]})
    """
    if query.get('estimated_time'):
        query['estimated_time'] = timedelta2int(
            pre_process_estimated_time(query.get('estimated_time'))
        )

    return TestCase.to_xmlrpc(query)
Example #16
0
def filter_count(request, values={}):
    """Performs a search and returns the resulting count of cases.

    :param dict values: a mapping containing same criteria with
        :meth:`TestCase.filter <tcms.xmlrpc.api.testcase.filter>`.
    :return: the number of matching cases.
    :rtype: int

    .. seealso:: Examples of :meth:`TestCase.filter <tcms.xmlrpc.api.testcase.filter>`.
    """

    if values.get('estimated_time'):
        values['estimated_time'] = timedelta2int(
            pre_process_estimated_time(values.get('estimated_time')))

    return distinct_count(TestCase, values)
Example #17
0
def filter(request, query):
    """Performs a search and returns the resulting list of test cases.

    :param dict query: a mapping containing these criteria.

        * author: A Bugzilla login (email address)
        * attachments: ForeignKey: Attachment
        * alias: (str)
        * case_id: (int)
        * case_status: ForeignKey: Case Stat
        * category: ForeignKey: :class:`Category`
        * component: ForeignKey: :class:`Component`
        * default_tester: ForeignKey: ``Auth.User``
        * estimated_time: String: 2h30m30s(recommend) or HH:MM:SS
        * plan: ForeignKey: :class:`TestPlan`
        * priority: ForeignKey: :class:`Priority`
        * category__product: ForeignKey: :class:`Product`
        * summary: (str)
        * tags: ForeignKey: :class:`Tags`
        * create_date: Datetime
        * is_automated: 1: Only show current 0: show not current
        * script: (str)

    :return: list of mappings of found :class:`TestCase`.
    :rtype: list

    Example::

        # Get all of cases contain 'TCMS' in summary
        TestCase.filter({'summary__icontain': 'TCMS'})
        # Get all of cases create by xkuang
        TestCase.filter({'author__username': '******'})
        # Get all of cases the author name starts with x
        TestCase.filter({'author__username__startswith': 'x'})
        # Get all of cases belong to the plan 1
        TestCase.filter({'plan__plan_id': 1})
        # Get all of cases belong to the plan create by xkuang
        TestCase.filter({'plan__author__username': '******'})
        # Get cases with ID 12345, 23456, 34567 - Here is only support array so far.
        TestCase.filter({'case_id__in': [12345, 23456, 34567]})
    """
    if query.get('estimated_time'):
        query['estimated_time'] = timedelta2int(
            pre_process_estimated_time(query.get('estimated_time'))
        )
    deprecate_critetion_attachment(query)
    return TestCase.to_xmlrpc(query)
Example #18
0
def filter(request, query):
    """Performs a search and returns the resulting list of test cases.

    :param dict query: a mapping containing these criteria.

        * author: A Bugzilla login (email address)
        * attachment: ForeignKey: Attachment
        * alias: (str)
        * case_id: (int)
        * case_status: ForeignKey: Case Stat
        * category: ForeignKey: :class:`Category`
        * component: ForeignKey: :class:`Component`
        * default_tester: ForeignKey: ``Auth.User``
        * estimated_time: String: 2h30m30s(recommend) or HH:MM:SS
        * plan: ForeignKey: :class:`TestPlan`
        * priority: ForeignKey: :class:`Priority`
        * category__product: ForeignKey: :class:`Product`
        * summary: (str)
        * tags: ForeignKey: :class:`Tags`
        * create_date: Datetime
        * is_automated: 1: Only show current 0: show not current
        * script: (str)

    :return: list of mappings of found :class:`TestCase`.
    :rtype: list

    Example::

        # Get all of cases contain 'TCMS' in summary
        >>> TestCase.filter({'summary__icontain': 'TCMS'})
        # Get all of cases create by xkuang
        >>> TestCase.filter({'author__username': '******'})
        # Get all of cases the author name starts with x
        >>> TestCase.filter({'author__username__startswith': 'x'})
        # Get all of cases belong to the plan 1
        >>> TestCase.filter({'plan__plan_id': 1})
        # Get all of cases belong to the plan create by xkuang
        >>> TestCase.filter({'plan__author__username': '******'})
        # Get cases with ID 12345, 23456, 34567 - Here is only support array so far.
        >>> TestCase.filter({'case_id__in': [12345, 23456, 34567]})
    """
    if query.get('estimated_time'):
        query['estimated_time'] = timedelta2int(
            pre_process_estimated_time(query.get('estimated_time'))
        )

    return TestCase.to_xmlrpc(query)
Example #19
0
def filter_count(request, values={}):
    """Performs a search and returns the resulting count of cases.

    :param dict values: a mapping containing same criteria with
        :meth:`TestCase.filter <tcms.xmlrpc.api.testcase.filter>`.
    :return: the number of matching cases.
    :rtype: int

    .. seealso:: Examples of :meth:`TestCase.filter <tcms.xmlrpc.api.testcase.filter>`.
    """

    if values.get('estimated_time'):
        values['estimated_time'] = timedelta2int(
            pre_process_estimated_time(values.get('estimated_time'))
        )

    return distinct_count(TestCase, values)
Example #20
0
def filter_count(values={}):
    """
    Description: Performs a search and returns the resulting count of cases.

    Params:      $values - Hash: keys must match valid search fields (see filter).

    Returns:     Integer - total matching cases.

    Example:
    # See TestCase.filter()
    """

    if values.get('estimated_time'):
        values['estimated_time'] = timedelta2int(
            pre_process_estimated_time(values.get('estimated_time')))

    return distinct_count(TestCase, values)
Example #21
0
def filter_count(request, values={}):
    """
    Description: Performs a search and returns the resulting count of cases.

    Params:      $values - Hash: keys must match valid search fields (see filter).

    Returns:     Integer - total matching cases.

    Example:
    # See TestCase.filter()
    """

    if values.get('estimated_time'):
        values['estimated_time'] = timedelta2int(
            pre_process_estimated_time(values.get('estimated_time'))
        )

    return distinct_count(TestCase, values)
Example #22
0
def update(request, run_ids, values):
    """Updates the fields of the selected test run.

    :param run_ids: give one or more run IDs. It could be an integer, a
        string containing comma separated IDs, or a list of int each of them is
        a run ID.
    :type run_ids: int, str or list
    :param dict values: a mapping containing these data to update specified
        runs.

        * plan: (int) TestPlan.plan_id
        * product: (int) Product.id
        * build: (int) Build.id
        * manager: (int) Auth.User.id
        * default_tester: Intege Auth.User.id
        * summary: (str)
        * estimated_time: (TimeDelta) in format ``2h30m30s`` which is recommended or ``HH:MM:SS``.
        * product_version: (int)
        * plan_text_version: (int)
        * notes: (str)
        * status: (int) 0:RUNNING 1:FINISHED

    :return: list of mappings of the updated test runs.
    :rtype: list[dict]

    .. versionchanged:: 4.5
       Argument ``errata_id`` is removed.

    Example::

        # Update status to finished for run 1 and 2
        TestRun.update([1, 2], {'status': 1})
    """
    from datetime import datetime
    from tcms.core import forms
    from tcms.testruns.forms import XMLRPCUpdateRunForm

    if (values.get('product_version') and not values.get('product')):
        raise ValueError('Field "product" is required by product_version')

    if values.get('estimated_time'):
        values['estimated_time'] = pre_process_estimated_time(
            values.get('estimated_time'))

    form = XMLRPCUpdateRunForm(values)
    if values.get('product_version'):
        form.populate(product_id=values['product'])

    if form.is_valid():
        trs = TestRun.objects.filter(pk__in=pre_process_ids(value=run_ids))
        _values = dict()
        if form.cleaned_data['plan']:
            _values['plan'] = form.cleaned_data['plan']

        if form.cleaned_data['build']:
            _values['build'] = form.cleaned_data['build']

        if form.cleaned_data['manager']:
            _values['manager'] = form.cleaned_data['manager']

        if 'default_tester' in values:
            default_tester = form.cleaned_data['default_tester']
            if values.get('default_tester') and default_tester:
                _values['default_tester'] = default_tester
            else:
                _values['default_tester'] = None

        if form.cleaned_data['summary']:
            _values['summary'] = form.cleaned_data['summary']

        if values.get('estimated_time') is not None:
            _values['estimated_time'] = form.cleaned_data['estimated_time']

        if form.cleaned_data['product_version']:
            _values['product_version'] = form.cleaned_data['product_version']

        if 'notes' in values:
            if values['notes'] in (None, ''):
                _values['notes'] = values['notes']
            if form.cleaned_data['notes']:
                _values['notes'] = form.cleaned_data['notes']

        if form.cleaned_data['plan_text_version']:
            _values['plan_text_version'] = form.cleaned_data[
                'plan_text_version']

        if isinstance(form.cleaned_data['status'], int):
            if form.cleaned_data['status']:
                _values['stop_date'] = datetime.now()
            else:
                _values['stop_date'] = None

        trs.update(**_values)
    else:
        raise ValueError(forms.errors_to_list(form))

    query = {'pk__in': trs.values_list('pk', flat=True)}
    return TestRun.to_xmlrpc(query)
Example #23
0
    def test_pre_process_estimated_time_with_time_string(self):
        time = U.pre_process_estimated_time("13:22:54")
        self.assertEqual(time, "13h22m54s")

        time = U.pre_process_estimated_time("1d13h22m54s")
        self.assertEqual(time, "1d13h22m54s")
Example #24
0
def create(request, values):
    """Creates a new Test Run object and stores it in the database.

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

        * plan: (int) **Required** ID of test plan
        * build: (int)/(str) **Required** ID of Build
        * manager: (int) **Required** ID of run manager
        * summary: (str) **Required**
        * product: (int) **Required** ID of product
        * product_version: (int) **Required** ID of product version
        * default_tester: (int) optional ID of run default tester
        * plan_text_version: (int) optional
        * estimated_time: (str) optional, could be in format ``2h30m30s``, which is recommended or ``HH:MM:SS``.
        * notes: (str) optional
        * status: (int) optional 0:RUNNING 1:STOPPED  (default 0)
        * case: list or (str) optional list of case ids to add to the run
        * tag: list or (str) optional list of tag to add to the run

    :return: a mapping representing newly created :class:`TestRun`.
    :rtype: dict

    .. versionchanged:: 4.5
       Argument ``errata_id`` is removed.

    Example::

        values = {
            'build': 2,
            'manager': 1,
            'plan': 1,
            'product': 1,
            'product_version': 2,
            'summary': 'Testing XML-RPC for TCMS',
        }
        TestRun.create(values)
    """
    from datetime import datetime
    from tcms.core import forms
    from tcms.testruns.forms import XMLRPCNewRunForm

    if not values.get('product'):
        raise ValueError('Value of product is required')
    # TODO: XMLRPC only accept HH:MM:SS rather than DdHhMm

    if values.get('estimated_time'):
        values['estimated_time'] = pre_process_estimated_time(
            values.get('estimated_time'))

    if values.get('case'):
        values['case'] = pre_process_ids(value=values['case'])

    form = XMLRPCNewRunForm(values)
    form.populate(product_id=values['product'])

    if form.is_valid():
        tr = TestRun.objects.create(
            product_version=form.cleaned_data['product_version'],
            plan_text_version=form.cleaned_data['plan_text_version'],
            stop_date=form.cleaned_data['status'] and datetime.now() or None,
            summary=form.cleaned_data['summary'],
            notes=form.cleaned_data['notes'],
            estimated_time=form.cleaned_data['estimated_time'],
            plan=form.cleaned_data['plan'],
            build=form.cleaned_data['build'],
            manager=form.cleaned_data['manager'],
            default_tester=form.cleaned_data['default_tester'],
        )

        if form.cleaned_data['case']:
            for c in form.cleaned_data['case']:
                tr.add_case_run(case=c)
                del c

        if form.cleaned_data['tag']:
            tags = form.cleaned_data['tag']
            if isinstance(tags, str):
                tags = [c.strip() for c in tags.split(',') if c]

            for tag in tags:
                t, c = TestTag.objects.get_or_create(name=tag)
                tr.add_tag(tag=t)
                del tag, t, c
    else:
        raise ValueError(forms.errors_to_list(form))

    return tr.serialize()
Example #25
0
def create(request, values):
    """Creates a new Test Run object and stores it in the database.

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

        * plan: (int) **Required** ID of test plan
        * build: (int)/(str) **Required** ID of Build
        * errata_id: (int) optional ID of Errata
        * manager: (int) **Required** ID of run manager
        * summary: (str) **Required**
        * product: (int) **Required** ID of product
        * product_version: (int) **Required** ID of product version
        * default_tester: (int) optional ID of run default tester
        * plan_text_version: (int) optional
        * estimated_time: (str) optional, could be in format ``2h30m30s``, which is recommended or ``HH:MM:SS``.
        * notes: (str) optional
        * status: (int) optional 0:RUNNING 1:STOPPED  (default 0)
        * case: list or (str) optional list of case ids to add to the run
        * tag: list or (str) optional list of tag to add to the run

    :return: a mapping representing newly created :class:`TestRun`.
    :rtype: dict

    Example::

        >>> values = {
                'build': 2,
                'manager': 1,
                'plan': 1,
                'errata_id': 2,
                'product': 1,
                'product_version': 2,
                'summary': 'Testing XML-RPC for TCMS',
            }
        >>> TestRun.create(values)
    """
    from datetime import datetime
    from tcms.core import forms
    from tcms.testruns.forms import XMLRPCNewRunForm

    if not values.get('product'):
        raise ValueError('Value of product is required')
    # TODO: XMLRPC only accept HH:MM:SS rather than DdHhMm

    if values.get('estimated_time'):
        values['estimated_time'] = pre_process_estimated_time(
            values.get('estimated_time'))

    if values.get('case'):
        values['case'] = pre_process_ids(value=values['case'])

    form = XMLRPCNewRunForm(values)
    form.populate(product_id=values['product'])

    if form.is_valid():
        tr = TestRun.objects.create(
            product_version=form.cleaned_data['product_version'],
            plan_text_version=form.cleaned_data['plan_text_version'],
            stop_date=form.cleaned_data['status'] and datetime.now() or None,
            summary=form.cleaned_data['summary'],
            notes=form.cleaned_data['notes'],
            estimated_time=form.cleaned_data['estimated_time'],
            plan=form.cleaned_data['plan'],
            build=form.cleaned_data['build'],
            errata_id=form.cleaned_data['errata_id'],
            manager=form.cleaned_data['manager'],
            default_tester=form.cleaned_data['default_tester'],
        )

        if form.cleaned_data['case']:
            for c in form.cleaned_data['case']:
                tr.add_case_run(case=c)
                del c

        if form.cleaned_data['tag']:
            tags = form.cleaned_data['tag']
            if isinstance(tags, str):
                tags = [c.strip() for c in tags.split(',') if c]

            for tag in tags:
                t, c = TestTag.objects.get_or_create(name=tag)
                tr.add_tag(tag=t)
                del tag, t, c
    else:
        raise ValueError(forms.errors_to_list(form))

    return tr.serialize()
Example #26
0
def create(request, values):
    """Creates a new Test Case object and stores it in the database.

    :param values: a mapping or list of mappings containing these case
        information for creation.

        * product: (int) **Required** ID of Product
        * category: (int) **Required** ID of Category
        * priority: (int) **Required** ID of Priority
        * summary: (str) **Required**
        * case_status: (int) optional ID of case status
        * plan Array/Str/Int optional ID or List of plan_ids
        * component: (int)/str optional ID of Priority
        * default_tester: (str) optional Login of tester
        * estimated_time: (str) optional 2h30m30s(recommend) or HH:MM:SS Format|
        * is_automated: (int) optional 0: Manual, 1: Auto, 2: Both
        * is_automated_proposed: (bool) optional Default 0
        * script: (str) optional
        * arguments: (str) optional
        * requirement: (str) optional
        * alias: (str) optional Must be unique
        * action: (str) optional
        * effect: (str) optional Expected Result
        * setup: (str) optional
        * breakdown: (str) optional
        * tag Array/str optional String Comma separated
        * bug Array/str optional String Comma separated
        * extra_link: (str) optional reference link

    :return: a mapping of newly created test case if a single case was created,
        or a list of mappings of created cases if more than one are created.
    :rtype: dict of list[dict]

    Example::

        # Minimal test case parameters
        values = {
            'category': 1,
            'product': 1,
            'summary': 'Testing XML-RPC',
            'priority': 1,
        }
        TestCase.create(values)
    """
    from tcms.core import forms
    from tcms.xmlrpc.forms import NewCaseForm

    if not (values.get('category') or values.get('summary')):
        raise ValueError()

    values['component'] = pre_process_ids(values.get('component', []))
    values['plan'] = pre_process_ids(values.get('plan', []))
    values['bug'] = pre_process_ids(values.get('bug', []))
    if values.get('estimated_time'):
        values['estimated_time'] = pre_process_estimated_time(values.get('estimated_time'))

    form = NewCaseForm(values)
    form.populate(values.get('product'))

    if form.is_valid():
        # Create the case
        tc = TestCase.create(author=request.user, values=form.cleaned_data)

        # Add case text to the case
        tc.add_text(
            action=form.cleaned_data['action'] or '',
            effect=form.cleaned_data['effect'] or '',
            setup=form.cleaned_data['setup'] or '',
            breakdown=form.cleaned_data['breakdown'] or '',
        )

        # Add the case to specific plans
        for p in form.cleaned_data['plan']:
            tc.add_to_plan(plan=p)
            del p

        # Add components to the case
        for c in form.cleaned_data['component']:
            tc.add_component(component=c)
            del c

        # Add tag to the case
        for tag in TestTag.string_to_list(values.get('tag', [])):
            t, c = TestTag.objects.get_or_create(name=tag)
            tc.add_tag(tag=t)
    else:
        # Print the errors if the form is not passed validation.
        raise ValueError(forms.errors_to_list(form))

    return get(request, tc.case_id)
Example #27
0
def update(run_id, values):
    """
    .. function:: XML-RPC TestRun.update(run_id, values)

        Update the selected TestRun

        :param run_id: PK of TestRun to modify
        :type run_id: int
        :param values: Field values for :class:`tcms.testruns.models.TestRun`
        :type values: dict
        :return: Serialized :class:`tcms.testruns.models.TestRun` object
        :raises: PermissionDenied if missing *testruns.change_testrun* permission
        :raises: ValueError if data validations fail
    """
    if (values.get('product_version') and not values.get('product')):
        raise ValueError('Field "product" is required by product_version')

    if values.get('estimated_time'):
        values['estimated_time'] = pre_process_estimated_time(
            values.get('estimated_time'))

    form = XMLRPCUpdateRunForm(values)
    if values.get('product_version'):
        form.populate(product_id=values['product'])

    if form.is_valid():
        tr = TestRun.objects.get(pk=run_id)
        if form.cleaned_data['plan']:
            tr.plan = form.cleaned_data['plan']

        if form.cleaned_data['build']:
            tr.build = form.cleaned_data['build']

        if form.cleaned_data['manager']:
            tr.manager = form.cleaned_data['manager']

        if 'default_tester' in values:
            if values.get('default_tester') and \
                    form.cleaned_data['default_tester']:
                tr.default_tester = form.cleaned_data['default_tester']
            else:
                tr.default_tester = None

        if form.cleaned_data['summary']:
            tr.summary = form.cleaned_data['summary']

        if values.get('estimated_time') is not None:
            tr.estimated_time = form.cleaned_data['estimated_time']

        if form.cleaned_data['product_version']:
            tr.product_version = form.cleaned_data['product_version']

        if 'notes' in values:
            if values['notes'] in (None, ''):
                tr.notes = values['notes']
            if form.cleaned_data['notes']:
                tr.notes = form.cleaned_data['notes']

        if form.cleaned_data['plan_text_version']:
            tr.plan_text_version = form.cleaned_data['plan_text_version']

        if isinstance(form.cleaned_data['status'], int):
            if form.cleaned_data['status']:
                tr.stop_date = datetime.now()
            else:
                tr.stop_date = None

        tr.save()
    else:
        raise ValueError(form_errors_to_list(form))

    return tr.serialize()
Example #28
0
def create(values):
    """
    .. function:: XML-RPC TestRun.create(values)

        Create new TestRun object and store it in the database.

        :param values: Field values for :class:`tcms.testruns.models.TestRun`
        :type values: dict
        :return: Serialized :class:`tcms.testruns.models.TestRun` object
        :raises: PermissionDenied if missing *testruns.add_testrun* permission
        :raises: ValueError if data validations fail

        Example::

            >>> values = {'build': 384,
                'manager': 137,
                'plan': 137,
                'product': 61,
                'product_version': 93,
                'summary': 'Testing XML-RPC for TCMS',
            }
            >>> TestRun.create(values)
    """
    if not values.get('product'):
        raise ValueError('Value of product is required')
    # TODO: XMLRPC only accept HH:MM:SS rather than DdHhMm

    if values.get('estimated_time'):
        values['estimated_time'] = pre_process_estimated_time(
            values.get('estimated_time'))

    form = XMLRPCNewRunForm(values)
    form.populate(product_id=values['product'])

    if form.is_valid():
        tr = TestRun.objects.create(
            product_version=form.cleaned_data['product_version'],
            plan_text_version=form.cleaned_data['plan_text_version'],
            stop_date=form.cleaned_data['status'] and datetime.now() or None,
            summary=form.cleaned_data['summary'],
            notes=form.cleaned_data['notes'],
            estimated_time=form.cleaned_data['estimated_time'],
            plan=form.cleaned_data['plan'],
            build=form.cleaned_data['build'],
            manager=form.cleaned_data['manager'],
            default_tester=form.cleaned_data['default_tester'],
        )

        if form.cleaned_data['tag']:
            tags = form.cleaned_data['tag']
            if isinstance(tags, str):
                tags = [c.strip() for c in tags.split(',') if c]

            for tag in tags:
                t, c = TestTag.objects.get_or_create(name=tag)
                tr.add_tag(tag=t)
                del tag, t, c
    else:
        raise ValueError(form_errors_to_list(form))

    return tr.serialize()
Example #29
0
def create(request, values):
    """
    Description: Creates a new Test Run object and stores it in the database.

    Params:      $values - Hash: A reference to a hash with keys and values
                           matching the fields of the test run to be created.
      +-------------------+----------------+-----------+---------------------------------------+
      | Field             | Type           | Null      | Description                           |
      +-------------------+----------------+-----------+---------------------------------------+
      | plan              | Integer        | Required  | ID of test plan                       |
      | build             | Integer/String | Required  | ID of Build                           |
      | errata_id         | Integer        | Optional  | ID of Errata                          |
      | manager           | Integer        | Required  | ID of run manager                     |
      | summary           | String         | Required  |                                       |
      | product           | Integer        | Required  | ID of product                         |
      | product_version   | Integer        | Required  | ID of product version                 |
      | default_tester    | Integer        | Optional  | ID of run default tester              |
      | plan_text_version | Integer        | Optional  |                                       |
      | estimated_time    | String         | Optional  | 2h30m30s(recommend) or HH:MM:SS Format|
      | notes             | String         | Optional  |                                       |
      | status            | Integer        | Optional  | 0:RUNNING 1:STOPPED  (default 0)      |
      | case              | Array/String   | Optional  | list of case ids to add to the run    |
      | tag               | Array/String   | Optional  | list of tag to add to the run         |
      +-------------------+----------------+-----------+---------------------------------------+

    Returns:     The newly created object hash.

    Example:
    >>> values = {'build': 384,
        'manager': 137,
        'plan': 137,
        'errata_id': 124,
        'product': 61,
        'product_version': 93,
        'summary': 'Testing XML-RPC for TCMS',
    }
    >>> TestRun.create(values)
    """
    from datetime import datetime
    from tcms.core import forms
    from tcms.testruns.forms import XMLRPCNewRunForm

    if not values.get('product'):
        raise ValueError('Value of product is required')
    # TODO: XMLRPC only accept HH:MM:SS rather than DdHhMm

    if values.get('estimated_time'):
        values['estimated_time'] = pre_process_estimated_time(
            values.get('estimated_time'))

    if values.get('case'):
        values['case'] = pre_process_ids(value=values['case'])

    form = XMLRPCNewRunForm(values)
    form.populate(product_id=values['product'])

    if form.is_valid():
        tr = TestRun.objects.create(
            product_version=form.cleaned_data['product_version'],
            plan_text_version=form.cleaned_data['plan_text_version'],
            stop_date=form.cleaned_data['status'] and datetime.now() or None,
            summary=form.cleaned_data['summary'],
            notes=form.cleaned_data['notes'],
            estimated_time=form.cleaned_data['estimated_time'],
            plan=form.cleaned_data['plan'],
            build=form.cleaned_data['build'],
            errata_id=form.cleaned_data['errata_id'],
            manager=form.cleaned_data['manager'],
            default_tester=form.cleaned_data['default_tester'],
        )

        if form.cleaned_data['case']:
            for c in form.cleaned_data['case']:
                tr.add_case_run(case=c)
                del c

        if form.cleaned_data['tag']:
            tags = form.cleaned_data['tag']
            if isinstance(tags, str):
                tags = [c.strip() for c in tags.split(',') if c]

            for tag in tags:
                t, c = TestTag.objects.get_or_create(name=tag)
                tr.add_tag(tag=t)
                del tag, t, c
    else:
        raise ValueError(forms.errors_to_list(form))

    return tr.serialize()
Example #30
0
def update(request, run_ids, values):
    """Updates the fields of the selected test run.

    :param run_ids: give one or more run IDs. It could be an integer, a
        string containing comma separated IDs, or a list of int each of them is
        a run ID.
    :type run_ids: int, str or list
    :param dict values: a mapping containing these data to update specified
        runs.

        * plan: (int) TestPlan.plan_id
        * product: (int) Product.id
        * build: (int) Build.id
        * errata_id: (int) Errata.id
        * manager: (int) Auth.User.id
        * default_tester: Intege Auth.User.id
        * summary: (str)
        * estimated_time: (TimeDelta) in format ``2h30m30s`` which is recommended or ``HH:MM:SS``.
        * product_version: (int)
        * plan_text_version: (int)
        * notes: (str)
        * status: (int) 0:RUNNING 1:FINISHED

    :return: list of mappings of the updated test runs.
    :rtype: list[dict]

    Example::

        # Update status to finished for run 1 and 2
        >>> TestRun.update([1, 2], {'status': 1})
    """
    from datetime import datetime
    from tcms.core import forms
    from tcms.testruns.forms import XMLRPCUpdateRunForm

    if (values.get('product_version') and not values.get('product')):
        raise ValueError('Field "product" is required by product_version')

    if values.get('estimated_time'):
        values['estimated_time'] = pre_process_estimated_time(
            values.get('estimated_time'))

    form = XMLRPCUpdateRunForm(values)
    if values.get('product_version'):
        form.populate(product_id=values['product'])

    if form.is_valid():
        trs = TestRun.objects.filter(pk__in=pre_process_ids(value=run_ids))
        _values = dict()
        if form.cleaned_data['plan']:
            _values['plan'] = form.cleaned_data['plan']

        if form.cleaned_data['build']:
            _values['build'] = form.cleaned_data['build']

        if form.cleaned_data['errata_id']:
            _values['errata_id'] = form.cleaned_data['errata_id']

        if form.cleaned_data['manager']:
            _values['manager'] = form.cleaned_data['manager']

        if 'default_tester' in values:
            if values.get('default_tester') and \
                    form.cleaned_data['default_tester']:
                _values['default_tester'] = form.cleaned_data['default_tester']
            else:
                _values['default_tester'] = None

        if form.cleaned_data['summary']:
            _values['summary'] = form.cleaned_data['summary']

        if values.get('estimated_time') is not None:
            _values['estimated_time'] = form.cleaned_data['estimated_time']

        if form.cleaned_data['product_version']:
            _values['product_version'] = form.cleaned_data['product_version']

        if 'notes' in values:
            if values['notes'] in (None, ''):
                _values['notes'] = values['notes']
            if form.cleaned_data['notes']:
                _values['notes'] = form.cleaned_data['notes']

        if form.cleaned_data['plan_text_version']:
            _values['plan_text_version'] = form.cleaned_data[
                'plan_text_version']

        if isinstance(form.cleaned_data['status'], int):
            if form.cleaned_data['status']:
                _values['stop_date'] = datetime.now()
            else:
                _values['stop_date'] = None

        trs.update(**_values)
    else:
        raise ValueError(forms.errors_to_list(form))

    query = {'pk__in': trs.values_list('pk', flat=True)}
    return TestRun.to_xmlrpc(query)
Example #31
0
 def test_pre_process_estimated_time_with_symbols(self):
     with self.assertRaisesRegex(ValueError,
                                 'Invalid estimated_time format.'):
         U.pre_process_estimated_time("aa@bb@cc")
Example #32
0
def update(request, run_ids, values):
    """
    Description: Updates the fields of the selected test run.

    Params:      $run_ids - Integer/Array/String: An integer or alias representing the ID in the database,
                            an array of run_ids, or a string of comma separated run_ids.

                 $values - Hash of keys matching TestRun fields and the new values
                           to set each field to. See params of TestRun.create for description
    +-------------------+----------------+--------------------------------+
    | Field             | Type           | Description                    |
    +-------------------+----------------+--------------------------------+
    | plan              | Integer        | TestPlan.plan_id               |
    | product           | Integer        | Product.id                     |
    | build             | Integer        | Build.id                       |
    | errata_id         | Integer        | Errata.id                      |
    | manager           | Integer        | Auth.User.id                   |
    | default_tester    | Intege         | Auth.User.id                   |
    | summary           | String         |                                |
    | estimated_time    | TimeDelta      | 2h30m30s(recommend) or HH:MM:SS|
    | product_version   | Integer        |                                |
    | plan_text_version | Integer        |                                |
    | notes             | String         |                                |
    | status            | Integer        | 0:RUNNING 1:FINISHED           |
    +-------------------+----------------+ -------------------------------+
    Returns:     Hash: The updated test run object.

    Example:
    # Update status to finished for run 1193 and 1194
    >>> TestRun.update([1193, 1194], {'status': 1})
    """
    from datetime import datetime
    from tcms.core import forms
    from tcms.testruns.forms import XMLRPCUpdateRunForm

    if (values.get('product_version') and not values.get('product')):
        raise ValueError('Field "product" is required by product_version')

    if values.get('estimated_time'):
        values['estimated_time'] = pre_process_estimated_time(
            values.get('estimated_time'))

    form = XMLRPCUpdateRunForm(values)
    if values.get('product_version'):
        form.populate(product_id=values['product'])

    if form.is_valid():
        trs = TestRun.objects.filter(pk__in=pre_process_ids(value=run_ids))
        _values = dict()
        if form.cleaned_data['plan']:
            _values['plan'] = form.cleaned_data['plan']

        if form.cleaned_data['build']:
            _values['build'] = form.cleaned_data['build']

        if form.cleaned_data['errata_id']:
            _values['errata_id'] = form.cleaned_data['errata_id']

        if form.cleaned_data['manager']:
            _values['manager'] = form.cleaned_data['manager']

        if 'default_tester' in values:
            if values.get('default_tester') and \
                    form.cleaned_data['default_tester']:
                _values['default_tester'] = form.cleaned_data['default_tester']
            else:
                _values['default_tester'] = None

        if form.cleaned_data['summary']:
            _values['summary'] = form.cleaned_data['summary']

        if values.get('estimated_time') is not None:
            _values['estimated_time'] = form.cleaned_data['estimated_time']

        if form.cleaned_data['product_version']:
            _values['product_version'] = form.cleaned_data['product_version']

        if 'notes' in values:
            if values['notes'] in (None, ''):
                _values['notes'] = values['notes']
            if form.cleaned_data['notes']:
                _values['notes'] = form.cleaned_data['notes']

        if form.cleaned_data['plan_text_version']:
            _values['plan_text_version'] = form.cleaned_data[
                'plan_text_version']

        if isinstance(form.cleaned_data['status'], int):
            if form.cleaned_data['status']:
                _values['stop_date'] = datetime.now()
            else:
                _values['stop_date'] = None

        trs.update(**_values)
    else:
        raise ValueError(forms.errors_to_list(form))

    query = {'pk__in': trs.values_list('pk', flat=True)}
    return TestRun.to_xmlrpc(query)
Example #33
0
 def test_pre_process_estimated_time(self):
     bad_args = ([], (), {})
     for arg in bad_args:
         with self.assertRaisesRegex(ValueError,
                                     'Invalid estimated_time format.'):
             U.pre_process_estimated_time(arg)
Example #34
0
 def test_pre_process_estimated_time_with_empty(self):
     time = U.pre_process_estimated_time("")
     self.assertEqual('', time)
Example #35
0
 def test_pre_process_estimated_time_with_string(self):
     with self.assertRaisesRegex(ValueError,
                                 'Invalid estimated_time format.'):
         U.pre_process_estimated_time("aa:bb:cc")
Example #36
0
 def test_pre_process_estimated_time_with_empty(self):
     time = U.pre_process_estimated_time("")
     self.assertEqual('', time)
Example #37
0
def create(request, values):
    """
    Description: Creates a new Test Run object and stores it in the database.

    Params:      $values - Hash: A reference to a hash with keys and values
                           matching the fields of the test run to be created.
      +-------------------+----------------+-----------+---------------------------------------+
      | Field             | Type           | Null      | Description                           |
      +-------------------+----------------+-----------+---------------------------------------+
      | plan              | Integer        | Required  | ID of test plan                       |
      | build             | Integer/String | Required  | ID of Build                           |
      | manager           | Integer        | Required  | ID of run manager                     |
      | summary           | String         | Required  |                                       |
      | product           | Integer        | Required  | ID of product                         |
      | product_version   | Integer        | Required  | ID of product version                 |
      | default_tester    | Integer        | Optional  | ID of run default tester              |
      | plan_text_version | Integer        | Optional  |                                       |
      | estimated_time    | String         | Optional  | 2h30m30s(recommend) or HH:MM:SS Format|
      | notes             | String         | Optional  |                                       |
      | status            | Integer        | Optional  | 0:RUNNING 1:STOPPED  (default 0)      |
      | case              | Array/String   | Optional  | list of case ids to add to the run    |
      | tag               | Array/String   | Optional  | list of tag to add to the run         |
      +-------------------+----------------+-----------+---------------------------------------+

    Returns:     The newly created object hash.

    Example:
    >>> values = {'build': 384,
        'manager': 137,
        'plan': 137,
        'product': 61,
        'product_version': 93,
        'summary': 'Testing XML-RPC for TCMS',
    }
    >>> TestRun.create(values)
    """
    from datetime import datetime
    from tcms.core import forms
    from tcms.testruns.forms import XMLRPCNewRunForm

    if not values.get('product'):
        raise ValueError('Value of product is required')
    # TODO: XMLRPC only accept HH:MM:SS rather than DdHhMm

    if values.get('estimated_time'):
        values['estimated_time'] = pre_process_estimated_time(
            values.get('estimated_time'))

    if values.get('case'):
        values['case'] = pre_process_ids(value=values['case'])

    form = XMLRPCNewRunForm(values)
    form.populate(product_id=values['product'])

    if form.is_valid():
        tr = TestRun.objects.create(
            product_version=form.cleaned_data['product_version'],
            plan_text_version=form.cleaned_data['plan_text_version'],
            stop_date=form.cleaned_data['status'] and datetime.now() or None,
            summary=form.cleaned_data['summary'],
            notes=form.cleaned_data['notes'],
            estimated_time=form.cleaned_data['estimated_time'],
            plan=form.cleaned_data['plan'],
            build=form.cleaned_data['build'],
            manager=form.cleaned_data['manager'],
            default_tester=form.cleaned_data['default_tester'],
        )

        if form.cleaned_data['case']:
            for c in form.cleaned_data['case']:
                tr.add_case_run(case=c)
                del c

        if form.cleaned_data['tag']:
            tags = form.cleaned_data['tag']
            if isinstance(tags, str):
                tags = [c.strip() for c in tags.split(',') if c]

            for tag in tags:
                t, c = TestTag.objects.get_or_create(name=tag)
                tr.add_tag(tag=t)
                del tag, t, c
    else:
        raise ValueError(forms.errors_to_list(form))

    return tr.serialize()
Example #38
0
def create(request, values):
    """Creates a new Test Case object and stores it in the database.

    :param values: a mapping or list of mappings containing these case
        information for creation.

        * product: (int) **Required** ID of Product
        * category: (int) **Required** ID of Category
        * priority: (int) **Required** ID of Priority
        * summary: (str) **Required**
        * case_status: (int) optional ID of case status
        * plan Array/Str/Int optional ID or List of plan_ids
        * component: (int)/str optional ID of Priority
        * default_tester: (str) optional Login of tester
        * estimated_time: (str) optional 2h30m30s(recommend) or HH:MM:SS Format|
        * is_automated: (int) optional 0: Manual, 1: Auto, 2: Both
        * is_automated_proposed: (bool) optional Default 0
        * script: (str) optional
        * arguments: (str) optional
        * requirement: (str) optional
        * alias: (str) optional Must be unique
        * action: (str) optional
        * effect: (str) optional Expected Result
        * setup: (str) optional
        * breakdown: (str) optional
        * tag Array/str optional String Comma separated
        * bug Array/str optional String Comma separated
        * extra_link: (str) optional reference link

    :return: a mapping of newly created test case if a single case was created,
        or a list of mappings of created cases if more than one are created.
    :rtype: dict of list[dict]

    Example::

        # Minimal test case parameters
        >>> values = {
                'category': 1,
                'product': 1,
                'summary': 'Testing XML-RPC',
                'priority': 1,
            }
        >>> TestCase.create(values)
    """
    from tcms.core import forms
    from tcms.xmlrpc.forms import NewCaseForm

    if not (values.get('category') or values.get('summary')):
        raise ValueError()

    values['component'] = pre_process_ids(values.get('component', []))
    values['plan'] = pre_process_ids(values.get('plan', []))
    values['bug'] = pre_process_ids(values.get('bug', []))
    if values.get('estimated_time'):
        values['estimated_time'] = pre_process_estimated_time(values.get('estimated_time'))

    form = NewCaseForm(values)
    form.populate(values.get('product'))

    if form.is_valid():
        # Create the case
        tc = TestCase.create(author=request.user, values=form.cleaned_data)

        # Add case text to the case
        tc.add_text(
            action=form.cleaned_data['action'] or '',
            effect=form.cleaned_data['effect'] or '',
            setup=form.cleaned_data['setup'] or '',
            breakdown=form.cleaned_data['breakdown'] or '',
        )

        # Add the case to specific plans
        for p in form.cleaned_data['plan']:
            tc.add_to_plan(plan=p)
            del p

        # Add components to the case
        for c in form.cleaned_data['component']:
            tc.add_component(component=c)
            del c

        # Add tag to the case
        for tag in TestTag.string_to_list(values.get('tag', [])):
            t, c = TestTag.objects.get_or_create(name=tag)
            tc.add_tag(tag=t)
    else:
        # Print the errors if the form is not passed validation.
        raise ValueError(forms.errors_to_list(form))

    return get(request, tc.case_id)
Example #39
0
def update(request, run_ids, values):
    """
    Description: Updates the fields of the selected test run.

    Params:      $run_ids - Integer/Array/String: An integer or alias representing the ID in the database,
                            an array of run_ids, or a string of comma separated run_ids.

                 $values - Hash of keys matching TestRun fields and the new values
                           to set each field to. See params of TestRun.create for description
    +-------------------+----------------+--------------------------------+
    | Field             | Type           | Description                    |
    +-------------------+----------------+--------------------------------+
    | plan              | Integer        | TestPlan.plan_id               |
    | product           | Integer        | Product.id                     |
    | build             | Integer        | Build.id                       |
    | manager           | Integer        | Auth.User.id                   |
    | default_tester    | Intege         | Auth.User.id                   |
    | summary           | String         |                                |
    | estimated_time    | TimeDelta      | 2h30m30s(recommend) or HH:MM:SS|
    | product_version   | Integer        |                                |
    | plan_text_version | Integer        |                                |
    | notes             | String         |                                |
    | status            | Integer        | 0:RUNNING 1:FINISHED           |
    +-------------------+----------------+ -------------------------------+
    Returns:     Hash: The updated test run object.

    Example:
    # Update status to finished for run 1193 and 1194
    >>> TestRun.update([1193, 1194], {'status': 1})
    """
    from datetime import datetime
    from tcms.core import forms
    from tcms.testruns.forms import XMLRPCUpdateRunForm

    if (values.get('product_version') and not values.get('product')):
        raise ValueError('Field "product" is required by product_version')

    if values.get('estimated_time'):
        values['estimated_time'] = pre_process_estimated_time(
            values.get('estimated_time'))

    form = XMLRPCUpdateRunForm(values)
    if values.get('product_version'):
        form.populate(product_id=values['product'])

    if form.is_valid():
        trs = TestRun.objects.filter(pk__in=pre_process_ids(value=run_ids))
        _values = dict()
        if form.cleaned_data['plan']:
            _values['plan'] = form.cleaned_data['plan']

        if form.cleaned_data['build']:
            _values['build'] = form.cleaned_data['build']

        if form.cleaned_data['manager']:
            _values['manager'] = form.cleaned_data['manager']

        if 'default_tester' in values:
            if values.get('default_tester') and \
                    form.cleaned_data['default_tester']:
                _values['default_tester'] = form.cleaned_data['default_tester']
            else:
                _values['default_tester'] = None

        if form.cleaned_data['summary']:
            _values['summary'] = form.cleaned_data['summary']

        if values.get('estimated_time') is not None:
            _values['estimated_time'] = form.cleaned_data['estimated_time']

        if form.cleaned_data['product_version']:
            _values['product_version'] = form.cleaned_data['product_version']

        if 'notes' in values:
            if values['notes'] in (None, ''):
                _values['notes'] = values['notes']
            if form.cleaned_data['notes']:
                _values['notes'] = form.cleaned_data['notes']

        if form.cleaned_data['plan_text_version']:
            _values['plan_text_version'] = form.cleaned_data[
                'plan_text_version']

        if isinstance(form.cleaned_data['status'], int):
            if form.cleaned_data['status']:
                _values['stop_date'] = datetime.now()
            else:
                _values['stop_date'] = None

        trs.update(**_values)
    else:
        raise ValueError(forms.errors_to_list(form))

    query = {'pk__in': trs.values_list('pk', flat=True)}
    return TestRun.to_xmlrpc(query)
Example #40
0
 def test_pre_process_estimated_time_with_bad_form(self):
     with self.assertRaisesRegex(ValueError,
                                 'Invalid estimated_time format.'):
         U.pre_process_estimated_time("aaaaaa")
Example #41
0
def update(request, case_ids, values):
    """
    Description: Updates the fields of the selected case or cases.

    Params:      $case_ids - Integer/String/Array
                             Integer: A single TestCase ID.
                             String:  A comma separates string of TestCase IDs for batch
                                      processing.
                             Array:   An array of case IDs for batch mode processing

                 $values   - Hash of keys matching TestCase fields and the new values
                             to set each field to.

    Returns:  Array: an array of case hashes. If the update on any particular
                     case failed, the has will contain a ERROR key and the
                     message as to why it failed.
        +-----------------------+----------------+-----------------------------------------+
        | Field                 | Type           | Null                                    |
        +-----------------------+----------------+-----------------------------------------+
        | case_status           | Integer        | Optional                                |
        | product               | Integer        | Optional(Required if changes category)  |
        | category              | Integer        | Optional                                |
        | priority              | Integer        | Optional                                |
        | default_tester        | String/Integer | Optional(str - user_name, int - user_id)|
        | estimated_time        | String         | Optional(2h30m30s(recommend) or HH:MM:SS|
        | is_automated          | Integer        | Optional(0 - Manual, 1 - Auto, 2 - Both)|
        | is_automated_proposed | Boolean        | Optional                                |
        | script                | String         | Optional                                |
        | arguments             | String         | Optional                                |
        | summary               | String         | Optional                                |
        | requirement           | String         | Optional                                |
        | alias                 | String         | Optional                                |
        | notes                 | String         | Optional                                |
        | extra_link            | String         | Optional(reference link)
        +-----------------------+----------------+-----------------------------------------+

    Example:
    # Update alias to 'tcms' for case 12345 and 23456
    >>> TestCase.update([12345, 23456], {'alias': 'tcms'})
    """
    from tcms.core import forms
    from tcms.xmlrpc.forms import UpdateCaseForm

    if values.get('estimated_time'):
        values['estimated_time'] = pre_process_estimated_time(values.get('estimated_time'))

    form = UpdateCaseForm(values)

    if values.get('category') and not values.get('product'):
        raise ValueError('Product ID is required for category')

    if values.get('product'):
        form.populate(product_id=values['product'])

    if form.is_valid():
        tcs = TestCase.update(
            case_ids=pre_process_ids(value=case_ids),
            values=form.cleaned_data,
        )
    else:
        raise ValueError(forms.errors_to_list(form))

    query = {'pk__in': tcs.values_list('pk', flat=True)}
    return TestCase.to_xmlrpc(query)
Example #42
0
def create(request, values):
    """
    Description: Creates a new Test Case object and stores it in the database.

    Params:      $values - Array/Hash: A reference to a hash or array of hashes with keys and values
                 matching the fields of the test case to be created.
      +----------------------------+----------------+-----------+---------------------------------------+
      | Field                      | Type           | Null      | Description                           |
      +----------------------------+----------------+-----------+---------------------------------------+
      | product                    | Integer        | Required  | ID of Product                         |
      | category                   | Integer        | Required  | ID of Category                        |
      | priority                   | Integer        | Required  | ID of Priority                        |
      | summary                    | String         | Required  |                                       |
      | case_status                | Integer        | Optional  | ID of case status                     |
      | plan                       | Array/Str/Int  | Optional  | ID or List of plan_ids                |
      | component                  | Integer/String | Optional  | ID of Priority                        |
      | default_tester             | String         | Optional  | Login of tester                       |
      | estimated_time             | String         | Optional  | 2h30m30s(recommend) or HH:MM:SS Format|
      | is_automated               | Integer        | Optional  | 0: Manual, 1: Auto, 2: Both           |
      | is_automated_proposed      | Boolean        | Optional  | Default 0                             |
      | script                     | String         | Optional  |                                       |
      | arguments                  | String         | Optional  |                                       |
      | requirement                | String         | Optional  |                                       |
      | alias                      | String         | Optional  | Must be unique                        |
      | action                     | String         | Optional  |                                       |
      | effect                     | String         | Optional  | Expected Result                       |
      | setup                      | String         | Optional  |                                       |
      | breakdown                  | String         | Optional  |                                       |
      | tag                        | Array/String   | Optional  | String Comma separated                |
      | bug                        | Array/String   | Optional  | String Comma separated                |
      | extra_link                 | String         | Optional  | reference link                        |
      +----------------------------+----------------+-----------+---------------------------------------+

    Returns:     Array/Hash: The newly created object hash if a single case was created, or
                             an array of objects if more than one was created. If any single case threw an
                             error during creation, a hash with an ERROR key will be set in its place.

    Example:
    # Minimal test case parameters
    >>> values = {
        'category': 135,
        'product': 61,
        'summary': 'Testing XML-RPC',
        'priority': 1,
    }
    >>> TestCase.create(values)
    """
    from tcms.core import forms
    from tcms.xmlrpc.forms import NewCaseForm

    if not (values.get('category') or values.get('summary')):
        raise ValueError()

    values['component'] = pre_process_ids(values.get('component', []))
    values['plan'] = pre_process_ids(values.get('plan', []))
    values['bug'] = pre_process_ids(values.get('bug', []))
    if values.get('estimated_time'):
        values['estimated_time'] = pre_process_estimated_time(values.get('estimated_time'))

    form = NewCaseForm(values)
    form.populate(values.get('product'))

    if form.is_valid():
        # Create the case
        tc = TestCase.create(author=request.user, values=form.cleaned_data)

        # Add case text to the case
        tc.add_text(
            action=form.cleaned_data['action'] or '',
            effect=form.cleaned_data['effect'] or '',
            setup=form.cleaned_data['setup'] or '',
            breakdown=form.cleaned_data['breakdown'] or '',
        )

        # Add the case to specific plans
        for p in form.cleaned_data['plan']:
            tc.add_to_plan(plan=p)
            del p

        # Add components to the case
        for c in form.cleaned_data['component']:
            tc.add_component(component=c)
            del c

        # Add tag to the case
        for tag in TestTag.string_to_list(values.get('tag', [])):
            t, c = TestTag.objects.get_or_create(name=tag)
            tc.add_tag(tag=t)
    else:
        # Print the errors if the form is not passed validation.
        raise ValueError(forms.errors_to_list(form))

    return get(request, tc.case_id)
Example #43
0
    def test_pre_process_estimated_time_with_time_string(self):
        time = U.pre_process_estimated_time("13:22:54")
        self.assertEqual(time, "13h22m54s")

        time = U.pre_process_estimated_time("1d13h22m54s")
        self.assertEqual(time, "1d13h22m54s")
Example #44
0
 def test_pre_process_estimated_time_with_upper_string(self):
     with self.assertRaisesRegex(ValueError,
                                 'Invalid estimated_time format.'):
         U.pre_process_estimated_time("1D13H22M54S")
Example #45
0
 def test_pre_process_estimated_time_with_mhs(self):
     with self.assertRaisesRegex(ValueError, 'Invaild estimated_time format.'):
         U.pre_process_estimated_time("ambhcs")