Beispiel #1
0
def is_open_bz(issue, data=None):
    """Check if specific BZ is open consulting a cached `data` dict or
    calling Bugzilla REST API.

    Arguments:
        issue {str} -- The BZ reference e.g: BZ:123456
        data {dict} -- Issue data indexed by <handler>:<number> or None
    """

    bz = try_from_cache(issue, data)
    if bz.get("is_open") is not None:  # bug has been already processed
        return bz["is_open"]

    bz = follow_duplicates(bz)

    # BZ is explicitly in OPEN status
    if bz.get('status') in OPEN_STATUSES:
        return True

    # BZ is CLOSED/WONTFIX so considered not fixed yet, BZ is open
    if bz.get('status') in CLOSED_STATUSES and bz.get('resolution') in WONTFIX_RESOLUTIONS:
        return True

    # BZ is CLOSED with a resolution in (ERRATA, CURRENT_RELEASE, ...)
    # server.version is higher or equal than BZ version
    # Consider fixed,  BZ is not open
    return get_sat_version() < extract_min_version(bz)
def test_positive_recommended_repos(session, module_org):
    """list recommended repositories using
     On/Off 'Recommended Repositories' toggle.

    :id: 1ae197d5-88ba-4bb1-8ecf-4da5013403d7

    :expectedresults:

           1. Shows repositories as per On/Off 'Recommended Repositories'.
           2. Check last Satellite version Capsule/Tools repos do not exist.

    :CaseLevel: Integration

    :BZ: 1776108
    """
    manifests.upload_manifest_locked(module_org.id)
    with session:
        session.organization.select(module_org.name)
        rrepos_on = session.redhatrepository.read(recommended_repo='on')
        assert REPOSET['rhel7'] in [repo['name'] for repo in rrepos_on]
        v = get_sat_version()
        sat_version = f'{v.major}.{v.minor}'
        cap_tool_repos = [
            repo['name'] for repo in rrepos_on
            if 'Tools' in repo['name'] or 'Capsule' in repo['name']
        ]
        cap_tools_repos = [
            repo for repo in cap_tool_repos if repo.split()[4] != sat_version
        ]
        assert not cap_tools_repos, 'Tools/Capsule repos do not match with Satellite version'
        rrepos_off = session.redhatrepository.read(recommended_repo='off')
        assert REPOSET['fdrh8'] in [repo['name'] for repo in rrepos_off]
        assert len(rrepos_off) > len(rrepos_on)
Beispiel #3
0
def pytest_collection_modifyitems(session, items, config):
    """Add markers and user_properties for testimony token metadata

    user_properties is used by the junit plugin, and thus by many test report systems
    Handle test function/class/module/session scope metadata coming from test docblocks
    Apply user_properties, ibutsu metadata, and pytest markers

    Markers for metadata use the testimony token name as the mark name
    The value of the token for the mark is the first mark arg

    Control test collection for custom options related to testimony metadata

    """
    # get RHEL version of the satellite
    rhel_version = get_sat_rhel_version().base_version
    sat_version = get_sat_version().base_version
    snap_version = settings.server.version.get('snap', '')

    # split the option string and handle no option, single option, multiple
    # config.getoption(default) doesn't work like you think it does, hence or ''
    importance = [
        i for i in (config.getoption('importance') or '').split(',') if i != ''
    ]
    component = [
        c for c in (config.getoption('component') or '').split(',') if c != ''
    ]
    assignee = [
        a for a in (config.getoption('assignee') or '').split(',') if a != ''
    ]

    selected = []
    deselected = []
    logger.info('Processing test items to add testimony token markers')
    for item in items:
        if item.nodeid.startswith(
                'tests/robottelo/') and 'test_junit' not in item.nodeid:
            # Unit test, no testimony markers
            continue

        # apply the marks for importance, component, and assignee
        # Find matches from docstrings starting at smallest scope
        item_docstrings = [
            d for d in map(inspect.getdoc, (item.function,
                                            getattr(item, 'cls', None),
                                            item.module)) if d is not None
        ]
        item_mark_names = [m.name for m in item.iter_markers()]
        for docstring in item_docstrings:
            # Add marker starting at smallest docstring scope
            # only add the mark if it hasn't already been applied at a lower scope
            doc_component = component_regex.findall(docstring)
            if doc_component and 'component' not in item_mark_names:
                item.add_marker(pytest.mark.component(doc_component[0]))
            doc_importance = importance_regex.findall(docstring)
            if doc_importance and 'importance' not in item_mark_names:
                item.add_marker(pytest.mark.importance(doc_importance[0]))
            doc_assignee = assignee_regex.findall(docstring)
            if doc_assignee and 'assignee' not in item_mark_names:
                item.add_marker(pytest.mark.assignee(doc_assignee[0]))

        # add markers as user_properties so they are recorded in XML properties of the report
        for marker in item.iter_markers():
            item.user_properties.append(
                (marker.name, next(iter(marker.args), None)))
        item.user_properties.append(("BaseOS", rhel_version))
        item.user_properties.append(("SatelliteVersion", sat_version))
        item.user_properties.append(("SnapVersion", snap_version))
        item.user_properties.append(
            ("start_time",
             datetime.datetime.utcnow().strftime(FMT_XUNIT_TIME)))

        # add custom ibutsu metadata fields for test case grouping and heatmaps
        if hasattr(item, "_ibutsu"):
            item._ibutsu["data"]["metadata"].update({
                # TODO Work with ibutsu team, better mechanism for defining 'special' data
                # TODO Add sat version to this item data at test execution time
                "component":
                item.get_closest_marker('component').args[0]
            })

        # exit early if no filters were passed
        if importance or component or assignee:
            # Filter test collection based on CLI options for filtering
            # filters should be applied together
            # such that --component Repository --importance Critical --assignee jsmith
            # only collects tests which have all three of these marks

            # https://github.com/pytest-dev/pytest/issues/1373  Will make this way easier
            # testimony requires both importance and component, this will blow up if its forgotten
            importance_marker = item.get_closest_marker('importance').args[0]
            if importance and importance_marker not in importance:
                logger.debug(
                    f'Deselected test {item.nodeid} due to "--importance {importance}",'
                    f'test has importance mark: {importance_marker}')
                deselected.append(item)
                continue
            component_marker = item.get_closest_marker('component').args[0]
            if component and component_marker not in component:
                logger.debug(
                    f'Deselected test {item.nodeid} due to "--component {component}",'
                    f'test has component mark: {component_marker}')
                deselected.append(item)
                continue
            assignee_marker = item.get_closest_marker('assignee').args[0]
            if assignee and assignee_marker not in assignee:
                logger.debug(
                    f'Deselected test {item.nodeid} due to "--assignee {assignee}",'
                    f'test has assignee mark: {assignee_marker}')
                deselected.append(item)
                continue

            selected.append(item)

    # selected will be empty if no filter option was passed, defaulting to full items list
    items[:] = selected if deselected else items
    config.hook.pytest_deselected(items=deselected)
Beispiel #4
0
def pytest_collection_modifyitems(items, config):
    """
    Collects and modifies test collection based on the pytest options to select the tests marked as
    failed/skipped and user-specific tests in Report Portal
    """
    rp_url = settings.report_portal.portal_url or config.getini('rp_endpoint')
    rp_uuid = config.getini('rp_uuid') or settings.report_portal.api_key
    # prefer dynaconf setting before ini config as pytest-reportportal plugin uses default value
    # for `rp_launch` if none is set there
    rp_launch_name = settings.report_portal.launch_name or config.getini('rp_launch')
    rp_project = config.getini('rp_project') or settings.report_portal.project
    fail_args = config.getoption('only_failed', False)
    skip_arg = config.getoption('only_skipped', False)
    user_arg = config.getoption('user', False)
    ref_launch_uuid = config.getoption('rp_reference_launch_uuid', None) or config.getoption(
        'rp_rerun_of', None
    )
    tests = []
    if not any([fail_args, skip_arg, user_arg]):
        return
    rp = ReportPortal(rp_url=rp_url, rp_api_key=rp_uuid, rp_project=rp_project)

    if ref_launch_uuid:
        logger.info(f'Fetching A reference Report Portal launch {ref_launch_uuid}')
        ref_launches = rp.get_launches(uuid=ref_launch_uuid)
        if not ref_launches:
            raise LaunchError(
                f'Provided reference launch {ref_launch_uuid} was not found or is not finished'
            )
    else:
        sat_release = get_sat_version().base_version
        sat_snap = settings.server.version.get('snap', '')
        if not all([sat_release, sat_snap, (len(sat_release.split('.')) == 3)]):
            raise pytest.UsageError(
                '--failed|skipped-only requires a reference launch id or'
                ' a full satellite version (x.y.z-a.b) to be provided.'
                f' sat_release: {sat_release}, sat_snap: {sat_snap} were provided instead'
            )
        sat_version = f'{sat_release}-{sat_snap}'
        logger.info(
            f'Fetching A reference Report Portal launch by Satellite version: {sat_version}'
        )

        ref_launches = rp.get_launches(name=rp_launch_name, sat_version=sat_version)
        if not ref_launches:
            raise LaunchError(
                f'No suitable Report portal launches for name: {rp_launch_name}'
                f' and version: {sat_version} found'
            )

    test_args = {}
    test_args.setdefault('status', list())
    if skip_arg:
        test_args['status'].append('SKIPPED')
    if fail_args:
        test_args['status'].append('FAILED')
        if not fail_args == 'all':
            defect_types = fail_args.split(',')
            allowed_args = [*rp.defect_types.keys()]
            if not set(defect_types).issubset(set(allowed_args)):
                raise pytest.UsageError(
                    'Incorrect values to pytest option \'--only-failed\' are provided as '
                    f'\'{fail_args}\'. It should be none/one/mix of {allowed_args}'
                )
            test_args['defect_types'] = defect_types
    if user_arg:
        test_args['user'] = user_arg
    test_args['paths'] = config.args
    for ref_launch in ref_launches:
        _validate_launch(ref_launch)
        tests.extend(rp.get_tests(launch=ref_launch, **test_args))
    # remove inapplicable tests from the current test collection
    deselected = [
        i
        for i in items
        if f'{i.location[0]}.{i.location[2]}'.replace('::', '.')
        not in [t['name'].replace('::', '.') for t in tests]
    ]
    selected = list(set(items) - set(deselected))
    logger.debug(
        f'Selected {len(selected)} and deselected {len(deselected)} tests based on latest/given-/ '
        'launch test results.'
    )
    config.hook.pytest_deselected(items=deselected)
    items[:] = selected