def test_custom_workitem(self):
     tc2 = TestCase(project_id=DEFAULT_PROJ, work_item_id=self.TEST_CASE_ID)
     self.assertIsNotNone(tc2.caseautomation)
     with self.assertRaises(PylarionLibException):
         tc2.caseautomation = "bad"
     tc2.caseautomation = "automated"
     # check for shared memory issue
     self.assertNotEqual(self.tc.caseautomation, tc2.caseautomation)
     req = Requirement()
     with self.assertRaises(PylarionLibException):
         req.reqtype = "bad"
     req.reqtype = 'functional'
 def test_006_create_work_item(self):
     tc = TestCase()
     tc.title = "regression"
     tc.description = "regression document test"
     tc.status = "draft"
     tc.caseimportance = "high"
     tc.caselevel = "component"
     tc.caseautomation = "notautomated"
     tc.caseposneg = "positive"
     tc.testtype = "functional"
     tc.subtype1 = "-"
     doc = Document(uri=self.doc_create.uri)
     wi = doc.create_work_item(None, tc)
     doc_wis = doc.get_work_items(None, True)
     doc_wi_ids = [doc_wi.work_item_id for doc_wi in doc_wis]
     self.assertIn(wi.work_item_id, doc_wi_ids)
     global WI_ID
     WI_ID = wi.work_item_id
Beispiel #3
0
def to_done(context, issue_id):
    '''Validate and update fields across Jira, Gerrit and Polarion using \
    ADMIN_USER credentials.

    Args:
        context (dict): A dict of form {'caller': 'CALLER_NAME'}
        issue_id (str): Jira Issue ID for fields updation

    Raises:
        InvalidParamsError: If 'issue_id' param is missing from JSON-RPC \
        request.

    ### Example (JSON-RPC request):
        {"jsonrpc": "2.0", "method":"to_done", "params": {"issue_id":
        "JIRA_ISSUE_ID", "id": "INTEGER/STRING"}
    '''

    # Holds all the info required to perform below operations
    info_dict = {}

    # Jira
    try:
        issue = jira.issue(issue_id, fields='summary,comment,assignee')
    except JIRAError as err:
        raise ApiError('Jira Error', -32000,
                       f'{err.status_code}: {err.text}') from err

    if issue.fields.assignee.name != context['caller']:
        raise ApiError('Not an assignee', -3200,
                       'This issue is not assigned to you')

    summary = issue.fields.summary
    info_dict['pol_id'] = summary[0:summary.find('\t')]

    comment = issue.fields.comment.comments[-1].body
    # Expects comment body as below
    # rb: 12345
    # fn: test_function_1 test_function_2
    info_dict['rb'] = re.search(r'rb: (\d+)', comment).group(0)

    # One polarion test may correspond to many 'test_' functions in worst case
    temp_fns = re.findall(r'(test_\w+)', comment)
    if not (info_dict['rb'] and temp_fns):
        raise ApiError(
            'Malformed comment body', -32000, 'Comment expression '
            'should be of form: rb: 12345\nfn: test_func_1 test_func_2')

    # Gerrit
    resp = gerrit.get(f'/changes/?q={info_dict["rb"]}')
    if resp:
        info_dict['rb_status'] = resp[0]['status']
        change_id = resp[0]['change_id']
        info_dict['fn_path'] = []
    else:
        raise ApiError(
            'Gerrit error', -32000,
            f'No patch exists in Gerrit with id: {info_dict["rb"]}')

    # Take note of test_script and function name if it is actually merged
    if info_dict['rb_status'] == 'MERGED':
        resp = gerrit.get(f'/changes/{change_id}/revisions/current/files')

        for each_file in resp.keys():
            # Don't store 'COMMIT_MSG'
            if each_file.startswith('tests'):
                # Read it's content for 'test_' functions
                file_name = each_file.replace('/', '%2F')
                # TODO: Is there a way to query only test functions without
                # reading whole file?
                resp = (
                    gerrit.get(
                        f'/changes/{change_id}/revisions/current/files/{file_name}/content'  # noqa
                    ))
                if resp:
                    # Take note of all 'test_' functions in the file
                    all_fns = re.findall(r'def (test_\w+)', resp)
                    for fn in all_fns:
                        # Check 'test_' function from file matches any function
                        # given in Jira comment and take note of the file path
                        if fn in temp_fns:
                            info_dict['fn_path'].append((fn, each_file))
        if len(info_dict['fn_path']) != temp_fns:
            raise ApiError('Patch function doesn\'t exist', -32000,
                           f'{temp_fns} doesn\'t exist in {info_dict["rb"]}')
    else:
        raise ApiError('Gerrit error', -32000,
                       f'RB: {info_dict["rb"]} is not merged')

    # Polarion
    try:
        testcase = TestCase(work_item_id=info_dict['pol_id'])
    except Exception as excep:
        raise ApiError('Polarion error', -32000, str(excep)) from excep
    if testcase.caseautomation != 'automated':
        testcase.caseautomation = 'automated'
        setattr(testcase, 'testcase-automation_id',
                ' '.join(entry[0] for entry in info_dict['fn_path']))
        script_path = '\n'.join(
            POL_MARKUP.format(entry[1]) for entry in info_dict['fn_path'])
        testcase.automation_script = script_path
        try:
            testcase.update()
        except Exception as excep:
            raise ApiError('Polarion error', -32000, str(excep)) from excep
    else:
        raise ApiError(
            'Polarion error', -32000, f'{info_dict["id"]} is '
            'already marked as "automated" in Polarion')

    # Jira
    # Transistion to 'Done' state
    # Example: To get what transistions are possible for current Jira project
    # >>> trans = jira.transitions(issue)
    # >>> available = [(t['id'], t['name']) for t in trans]; print(available)
    # >>> [('21', 'In Progress'), ('31', 'Done'), ('51', 'To Do'), ('61', 'In
    # Review')]
    # >>> jira_state = [num[0] for num in available if num[1] == 'Done' ][0]
    try:
        jira.transition_issue(issue, '31')
    except JIRAError as err:
        raise ApiError(
            'Jira Error', -32000,
            ('Polarion fields are updated but mark Jira manually to '
             '"Done", error:' + str(err))) from err

    # Add JIRA comment with gathered info if update is successful
    body = '\n'.join(
        str(key) + ': ' + str(value) for key, value in info_dict.items()
        if key not in ('rb', 'pol_id'))
    body += f'\nGerrit: {ENV.GERRIT_URL}/{info_dict["rb"]}'
    body += f'\nPolarion: {ENV.POLARION_URL}/#/project/{ENV.POLARION_PROJECT}/workitem?id={info_dict["pol_id"]}'  # noqa
    body += '\nGerrit status is verified and Polarion fields are updated'

    try:
        jira.add_comment(issue, body)
    except JIRAError as err:
        raise ApiError(
            'Jira Error', -32000,
            ('Polarion and Jira fields are updated but unable to add Jira '
             'comment' + str(err))) from err

    return 'Gerrit fields are validated, Jira and Polarion fields are updated'