Example #1
0
File: export.py Project: happz/tmt
def create_nitrate_case(test):
    """ Create new nitrate case """
    import_nitrate()

    # Get category from Makefile
    try:
        with open('Makefile', encoding='utf-8') as makefile_file:
            makefile = makefile_file.read()
        category = re.search(r'echo\s+"Type:\s*(.*)"', makefile, re.M).group(1)
    # Default to 'Sanity' if Makefile or Type not found
    except (IOError, AttributeError):
        category = 'Sanity'

    # Create the new test case
    summary = test.node.get('extra-summary', test.summary)
    category = nitrate.Category(name=category, product=DEFAULT_PRODUCT)
    testcase = nitrate.TestCase(summary=summary, category=category)
    echo(style(f"Test case '{testcase.identifier}' created.", fg='blue'))
    return testcase
Example #2
0
 def reset_to_id(self, test_id):
     """reset current state to a test_case loaded by the id"""
     logging.debug("resetting to id: %s", test_id)
     # synchronize previous case run if any
     self.sync()
     try:
         test_case = nitrate.TestCase(id=test_id)
         if self.test_case == test_case:
             logging.debug("already at the same id %d", test_id)
         else:
             # new case id
             if test_case in self.result_map:
                 logging.debug("new test_case loaded for id %d", test_id)
                 self.reset(test_case)
             else:
                 logging.info("skipped; id %d not in plan", test_id)
                 self.reset()
     except nitrate.NitrateError as e:
         logging.warning("unmatched test id: %s; error: %s", test_id, e)
         self.reset()
Example #3
0
File: export.py Project: pkis/tmt
def create_nitrate_case(test):
    """ Create new nitrate case """
    import_nitrate()

    # Get category from Makefile
    try:
        with open('Makefile', encoding='utf-8') as makefile_file:
            makefile = makefile_file.read()
        category = re.search(r'echo\s+"Type:\s*(.*)"', makefile, re.M).group(1)
    # Default to 'Sanity' if Makefile or Type not found
    except (IOError, AttributeError):
        category = 'Sanity'

    # Create the new test case
    remote_dirname = re.sub('.git$', '', os.path.basename(test.fmf_id['url']))
    if not remote_dirname:
        raise ConvertError("Unable to find git remote url.")
    summary = test.node.get('extra-summary', (remote_dirname or "") +
                            (test.name or "") + ' - ' + (test.summary or ""))
    category = nitrate.Category(name=category, product=DEFAULT_PRODUCT)
    testcase = nitrate.TestCase(summary=summary, category=category)
    echo(style(f"Test case '{testcase.identifier}' created.", fg='blue'))
    return testcase
Example #4
0
File: export.py Project: happz/tmt
def export_to_nitrate(test, create, general):
    """ Export fmf metadata to nitrate test cases """
    import_nitrate()

    new_test_created = False
    # Check nitrate test case
    try:
        nitrate_id = test.node.get('extra-nitrate')[3:]
        nitrate_case = nitrate.TestCase(int(nitrate_id))
        echo(style(f"Test case '{nitrate_case.identifier}' found.", fg='blue'))
    except TypeError:
        # Create a new nitrate test case
        if create:
            nitrate_case = create_nitrate_case(test)
            new_test_created = True
        else:
            raise ConvertError("Nitrate test case id not found.")

    # Summary
    summary = test.node.get('extra-summary',
                            test.node.get('extra-task', test.summary))
    if summary:
        nitrate_case.summary = summary
        echo(style('summary: ', fg='green') + summary)
    else:
        raise ConvertError("Nitrate case summary could not be determined.")

    # Script
    if test.node.get('extra-task'):
        nitrate_case.script = test.node.get('extra-task')
        echo(style('script: ', fg='green') + test.node.get('extra-task'))

    # Components
    # First remove any components that are already there
    nitrate_case.components.clear()
    # Then add fmf ones
    if test.component:
        echo(style('components: ', fg='green') + ' '.join(test.component))
        for component in test.component:
            try:
                nitrate_case.components.add(
                    nitrate.Component(name=component,
                                      product=DEFAULT_PRODUCT.id))
            except nitrate.xmlrpc_driver.NitrateError as error:
                log.debug(error)
                echo(style(f"Failed to add component '{component}'.",
                           fg='red'))
            if general:
                try:
                    general_plan = find_general_plan(component)
                    nitrate_case.testplans.add(general_plan)
                except nitrate.NitrateError as error:
                    log.debug(error)
                    echo(
                        style(
                            f"Failed to link general test plan for '{component}'.",
                            fg='red'))

    # Tags
    nitrate_case.tags.clear()
    # Convert 'tier' attribute into a Tier tag
    if test.tier is not None:
        test.tag.append(f"Tier{test.tier}")
    # Add special fmf-export tag
    test.tag.append('fmf-export')
    nitrate_case.tags.add([nitrate.Tag(tag) for tag in test.tag])
    echo(style('tags: ', fg='green') + ' '.join(set(test.tag)))

    # Default tester
    if test.contact:
        # Need to pick one value, so picking the first contact
        email_address = email.utils.parseaddr(test.contact[0])[1]
        # TODO handle nitrate user not existing and other possible exceptions
        nitrate_case.tester = nitrate.User(email_address)
        echo(style('default tester: ', fg='green') + email_address)

    # Duration
    nitrate_case.time = test.duration
    echo(style('estimated time: ', fg='green') + test.duration)

    # Status
    current_status = nitrate_case.status
    # Enable enabled tests
    if test.enabled:
        nitrate_case.status = nitrate.CaseStatus('CONFIRMED')
        echo(style('status: ', fg='green') + 'CONFIRMED')
    # Disable disabled tests which are CONFIRMED
    elif current_status == nitrate.CaseStatus('CONFIRMED'):
        nitrate_case.status = nitrate.CaseStatus('DISABLED')
        echo(style('status: ', fg='green') + 'DISABLED')
    # Keep disabled tests in their states
    else:
        echo(style('status: ', fg='green') + str(current_status))

    # Environment
    if test.environment:
        environment = ' '.join(tmt.utils.shell_variables(test.environment))
        nitrate_case.arguments = environment
        echo(style('arguments: ', fg='green') + environment)
    else:
        # FIXME unable clear to set empty arguments
        # (possibly error in xmlrpc, BZ#1805687)
        nitrate_case.arguments = ' '
        echo(style('arguments: ', fg='green') + "' '")

    # Structured Field
    struct_field = tmt.utils.StructuredField(nitrate_case.notes)
    echo(style('Structured Field: ', fg='green'))

    # Mapping of structured field sections to fmf case attributes
    section_to_attr = {
        'relevancy': test.relevancy,
        'description': test.summary,
        'purpose-file': test.description,
        'hardware': test.node.get('extra-hardware'),
        'pepa': test.node.get('extra-pepa'),
    }
    for section, attribute in section_to_attr.items():
        if attribute is None:
            try:
                struct_field.remove(section)
            except tmt.utils.StructuredFieldError:
                pass
        else:
            struct_field.set(section, attribute)
            echo(style(section + ': ', fg='green') + attribute.strip())

    # fmf identifer
    fmf_id = test.fmf_id
    struct_field.set('fmf', yaml.dump(fmf_id))
    echo(style('fmf id:\n', fg='green') + yaml.dump(fmf_id).strip())

    # Warning
    if WARNING not in struct_field.header():
        struct_field.header(WARNING + struct_field.header())
        echo(style('Added warning about porting to case notes.', fg='green'))

    # Saving case.notes with edited StructField
    nitrate_case.notes = struct_field.save()

    # Update nitrate test case
    nitrate_case.update()
    echo(
        style("Test case '{0}' successfully exported to nitrate.".format(
            nitrate_case.identifier),
              fg='magenta'))

    # Write id of newly created nitrate case to its file
    if new_test_created:
        fmf_file_path = test.node.sources[-1]
        try:
            with open(fmf_file_path, encoding='utf-8') as fmf_file:
                content = yaml.safe_load(fmf_file)
        except IOError:
            raise ConvertError("Unable to open '{0}'.".format(fmf_file_path))

        content['extra-nitrate'] = nitrate_case.identifier
        tmt.convert.write(fmf_file_path, content)
Example #5
0
File: export.py Project: pkis/tmt
def export_to_nitrate(test):
    """ Export fmf metadata to nitrate test cases """
    import_nitrate()
    new_test_created = False

    # Check command line options
    create = test.opt('create')
    general = test.opt('general')
    duplicate = test.opt('duplicate')
    link_bugzilla = test.opt('bugzilla')

    if link_bugzilla:
        import_bugzilla()
        try:
            bz_instance = bugzilla.Bugzilla(url=BUGZILLA_XMLRPC_URL)
        except Exception as exc:
            log.debug(traceback.format_exc())
            raise ConvertError("Couldn't initialize the Bugzilla client.",
                               original=exc)
        if not bz_instance.logged_in:
            raise ConvertError(
                "Not logged to Bugzilla, check `man bugzilla` section "
                "'AUTHENTICATION CACHE AND API KEYS'.")

    # Check nitrate test case
    try:
        nitrate_id = test.node.get('extra-nitrate')[3:]
        nitrate_case = nitrate.TestCase(int(nitrate_id))
        nitrate_case.summary  # Make sure we connect to the server now
        echo(style(f"Test case '{nitrate_case.identifier}' found.", fg='blue'))
    except TypeError:
        # Create a new nitrate test case
        if create:
            nitrate_case = None
            # Check for existing Nitrate tests with the same fmf id
            if not duplicate:
                testcases = _nitrate_find_fmf_testcases(test)
                try:
                    # Select the first found testcase if any
                    nitrate_case = next(testcases)
                except StopIteration:
                    pass
            if not nitrate_case:
                nitrate_case = create_nitrate_case(test)
            new_test_created = True
            # Newly created tmt tests have special format summary
            test._metadata['extra-summary'] = nitrate_case.summary
        else:
            raise ConvertError(f"Nitrate test case id not found for {test}"
                               " (You can use --create option to enforce"
                               " creating testcases)")
    except (nitrate.NitrateError, gssapi.raw.misc.GSSError) as error:
        raise ConvertError(error)

    # Summary
    summary = (test._metadata.get('extra-summary')
               or test._metadata.get('extra-task') or test.summary
               or test.name)
    if summary:
        nitrate_case.summary = summary
        echo(style('summary: ', fg='green') + summary)
    else:
        raise ConvertError("Nitrate case summary could not be determined.")

    # Script
    if test.node.get('extra-task'):
        nitrate_case.script = test.node.get('extra-task')
        echo(style('script: ', fg='green') + test.node.get('extra-task'))

    # Components
    # First remove any components that are already there
    nitrate_case.components.clear()
    if general:
        # Remove also all general plans linked to testcase
        for nitrate_plan in [plan for plan in nitrate_case.testplans]:
            if nitrate_plan.type.name == "General":
                nitrate_case.testplans.remove(nitrate_plan)
    # Then add fmf ones
    if test.component:
        echo(style('components: ', fg='green') + ' '.join(test.component))
        for component in test.component:
            try:
                nitrate_case.components.add(
                    nitrate.Component(name=component,
                                      product=DEFAULT_PRODUCT.id))
            except nitrate.xmlrpc_driver.NitrateError as error:
                log.debug(error)
                echo(style(f"Failed to add component '{component}'.",
                           fg='red'))
            if general:
                try:
                    general_plan = find_general_plan(component)
                    nitrate_case.testplans.add(general_plan)
                except nitrate.NitrateError as error:
                    log.debug(error)
                    echo(
                        style(
                            f"Failed to link general test plan for '{component}'.",
                            fg='red'))

    # Tags
    nitrate_case.tags.clear()
    # Convert 'tier' attribute into a Tier tag
    if test.tier is not None:
        test.tag.append(f"Tier{test.tier}")
    # Add special fmf-export tag
    test.tag.append('fmf-export')
    nitrate_case.tags.add([nitrate.Tag(tag) for tag in test.tag])
    echo(style('tags: ', fg='green') + ' '.join(set(test.tag)))

    # Default tester
    if test.contact:
        # Need to pick one value, so picking the first contact
        email_address = email.utils.parseaddr(test.contact[0])[1]
        # TODO handle nitrate user not existing and other possible exceptions
        nitrate_case.tester = nitrate.User(email_address)
        echo(style('default tester: ', fg='green') + email_address)

    # Duration
    nitrate_case.time = test.duration
    echo(style('estimated time: ', fg='green') + test.duration)

    # Manual
    nitrate_case.automated = not test.manual
    echo(style('automated: ', fg='green') + ['auto', 'manual'][test.manual])

    # Status
    current_status = nitrate_case.status
    # Enable enabled tests
    if test.enabled:
        nitrate_case.status = nitrate.CaseStatus('CONFIRMED')
        echo(style('status: ', fg='green') + 'CONFIRMED')
    # Disable disabled tests which are CONFIRMED
    elif current_status == nitrate.CaseStatus('CONFIRMED'):
        nitrate_case.status = nitrate.CaseStatus('DISABLED')
        echo(style('status: ', fg='green') + 'DISABLED')
    # Keep disabled tests in their states
    else:
        echo(style('status: ', fg='green') + str(current_status))

    # Environment
    if test.environment:
        environment = ' '.join(tmt.utils.shell_variables(test.environment))
        nitrate_case.arguments = environment
        echo(style('arguments: ', fg='green') + environment)
    else:
        # FIXME unable clear to set empty arguments
        # (possibly error in xmlrpc, BZ#1805687)
        nitrate_case.arguments = ' '
        echo(style('arguments: ', fg='green') + "' '")

    # Structured Field
    struct_field = tmt.utils.StructuredField(nitrate_case.notes)
    echo(style('Structured Field: ', fg='green'))

    # Mapping of structured field sections to fmf case attributes
    section_to_attr = {
        'description': test.summary,
        'purpose-file': test.description,
        'hardware': test.node.get('extra-hardware'),
        'pepa': test.node.get('extra-pepa'),
    }
    for section, attribute in section_to_attr.items():
        if attribute is None:
            try:
                struct_field.remove(section)
            except tmt.utils.StructuredFieldError:
                pass
        else:
            struct_field.set(section, attribute)
            echo(style(section + ': ', fg='green') + attribute.strip())

    # fmf identifer
    fmf_id = tmt.utils.dict_to_yaml(test.fmf_id)
    struct_field.set('fmf', fmf_id)
    echo(style('fmf id:\n', fg='green') + fmf_id.strip())

    # Warning
    if WARNING not in struct_field.header():
        struct_field.header(WARNING + struct_field.header())
        echo(style('Add migration warning to the test case notes.',
                   fg='green'))

    # Saving case.notes with edited StructField
    nitrate_case.notes = struct_field.save()

    # Export manual test instructions from *.md file to nitrate as html
    md_path = return_markdown_file()
    if os.path.exists(md_path):
        step, expect, setup, cleanup = convert_manual_to_nitrate(md_path)
        nitrate.User()._server.TestCase.store_text(nitrate_case.id, step,
                                                   expect, setup, cleanup)
        echo(style(f"manual steps:", fg='green') + f" found in {md_path}")

    # Append id of newly created nitrate case to its file
    if new_test_created:
        echo(style(f"Append the nitrate test case id.", fg='green'))
        try:
            with test.node as data:
                data["extra-nitrate"] = nitrate_case.identifier
        except AttributeError:
            # FIXME: Remove this deprecated code after fmf support
            # for storing modified data is released long enough
            file_path = test.node.sources[-1]
            try:
                with open(file_path, encoding='utf-8', mode='a+') as file:
                    file.write(f"extra-nitrate: {nitrate_case.identifier}\n")
            except IOError:
                raise ConvertError("Unable to open '{0}'.".format(file_path))

    # List of bugs test verifies
    verifies_bug_ids = []
    for link in test.link:
        try:
            verifies_bug_ids.append(
                int(re.search(RE_BUGZILLA_URL, link['verifies']).group(1)))
        except Exception as err:
            log.debug(err)

    # Add bugs to the Nitrate case
    for bug_id in verifies_bug_ids:
        nitrate_case.bugs.add(nitrate.Bug(bug=int(bug_id)))

    # Update nitrate test case
    nitrate_case.update()
    echo(
        style("Test case '{0}' successfully exported to nitrate.".format(
            nitrate_case.identifier),
              fg='magenta'))

    # Optionally link Bugzilla to Nitrate case
    if link_bugzilla and verifies_bug_ids:
        try:
            bz_set_coverage(bz_instance, verifies_bug_ids,
                            int(nitrate_case.id))
            echo(
                style("Linked to Bugzilla: {}.".format(" ".join(
                    [f"BZ#{bz_id}" for bz_id in verifies_bug_ids])),
                      fg='magenta'))
        except Exception as err:
            raise ConvertError("Couldn't update bugs", original=err)
Example #6
0
    return parser.parse_args()


# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  Main
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

if __name__ == "__main__":
    (options, arguments) = parse_options()

    # Create test cases
    cases = []
    for case_count in range(options.cases):
        testcase = nitrate.TestCase(
            name="Test Case {0}".format(case_count + 1),
            category=CATEGORY,
            product=PRODUCT,
            summary="Test Case {0}".format(case_count + 1),
            status=CASESTATUS)
        # Add a couple of random tags and the default tester
        testcase.tags.add([random.choice(TAGS) for counter in range(10)])
        testcase.tester = random.choice(TESTERS)
        testcase.update()
        cases.append(testcase)

    # Create master test plan (parent of all)
    master = nitrate.TestPlan(name=MASTER_TESTPLAN_NAME,
                              product=PRODUCT,
                              version=VERSION,
                              type=PLANTYPE)
    nitrate.info("* {0}".format(master))
    master.testcases.add(cases)
Example #7
0
                                name="python / rhel-6.2.0 / ER#11359",
                                type="Release",
                                product="Red Hat Enterprise Linux 6",
                                version="6.2")

# Link all automated test cases from the general plan
info("Linking automated test cases from the general plan")
for testcase in general_plan:
    if testcase.automated:
        release_plan.testcases.add(testcase)
release_plan.update()

# Create a new test case
info("Creating a new test case")
testcase = nitrate.TestCase(summary="New performance test",
                            product="Red Hat Enterprise Linux 6",
                            category="Performance",
                            script="/CoreOS/python/Performance/base")

# Set status, priority, default tester, add tags, attach bugs, link plans
info("Setting status, priority, tester, tags, bugs and plans")
testcase.status = nitrate.CaseStatus("CONFIRMED")
testcase.priority = nitrate.Priority("P1")
testcase.tester = nitrate.User("psplicha")
testcase.tags.add(nitrate.Tag("Tier1"))
testcase.bugs.add(nitrate.Bug(bug=123))
testcase.testplans.add([general_plan, release_plan])
testcase.update()

# List all general plan's children including their status
info("Listing child test plans of the general test plan")
for testplan in general_plan.children: