Beispiel #1
0
def get_decorated_bugs():  # pragma: no cover
    """Using Robozilla parser, get all IDs from skip_if_bug_open decorator
    and return the dictionary containing fetched data.

    Important information is stored on `bug_data` key::
        bugs[BUG_ID]['bug_data']['resolution|status|flags|whiteboard']
    """

    if not settings.configured:
        settings.configure()

    # look for settings bugzilla credentials
    # any way Parser bugzilla reader will check for exported environment names
    # BUGZILLA_USER_NAME and BUGZILLA_USER_PASSWORD if no credentials was
    # supplied
    bz_reader_options = {}
    bz_credentials = {}
    if setting_is_set('bugzilla'):
        bz_credentials = settings.bugzilla.get_credentials()

    bz_reader_options['credentials'] = bz_credentials
    parser = Parser(BASE_PATH, filters=[BZDecorator],
                    reader_options=bz_reader_options)
    bugs = parser.parse()
    return bugs
Beispiel #2
0
def get_deselect_bug_ids(bugs=None, log=None):  # pragma: no cover
    """returns the IDs of bugs to be deselected from test collection"""

    if not settings.configured:
        settings.configure()

    if settings.bugzilla.wontfix_lookup is not True:
        return []

    if log is None:
        log = log_debug

    log('Fetching WONTFIX BZs on Bugzilla API...')
    bugs = bugs or get_decorated_bugs()
    wontfixes = []
    for bug_id, data in bugs.items():
        bug_data = data.get('bug_data')
        # when not authenticated, private bugs will have no bug data
        if bug_data:
            if bug_data['resolution'] in ('WONTFIX', 'CANTFIX', 'DEFERRED'):
                wontfixes.append(bug_id)
        else:
            log('bug data for bug id "{}" was not retrieved,'
                ' please review bugzilla credentials'.format(bug_id))
    return wontfixes
Beispiel #3
0
 def setUpClass(cls):  # noqa
     super(TestCase, cls).setUpClass()
     if not settings.configured:
         settings.configure()
     cls.logger = logging.getLogger('robottelo')
     # NOTE: longMessage defaults to True in Python 3.1 and above
     cls.longMessage = True
Beispiel #4
0
def pytest_collection_modifyitems(items, config):
    """ called after collection has been performed, may filter or re-order
    the items in-place.

    Deselecting all tests skipped due to WONTFIX BZ.
    """
    if not settings.configured:
        settings.configure()

    if settings.bugzilla.wontfix_lookup is not True:
        # if lookup is disable return all collection unmodified
        log('Deselect of WONTFIX BZs is disabled in settings')
        return items

    deselected_items = []
    wontfix_ids = pytest.bugzilla.wontfix_ids
    decorated_functions = group_by_key(pytest.bugzilla.decorated_functions)

    log("Found WONTFIX in decorated tests %s" % wontfix_ids)
    log("Collected %s test cases" % len(items))

    for item in items:
        name = get_func_name(item.function)
        bug_ids = decorated_functions.get(name)
        if bug_ids:
            for bug_id in bug_ids:
                if bug_id in wontfix_ids:
                    deselected_items.append(item)
                    log("Deselected test %s due to WONTFIX" % name)
                    break

    config.hook.pytest_deselected(items=deselected_items)
    items[:] = [item for item in items if item not in deselected_items]
Beispiel #5
0
def filtered_datapoint(func):
    """Overrides the data creator functions in this class to return 1 value and
    transforms data dictionary to pytest's parametrize acceptable format for
    new style generators.

    If run_one_datapoint=false, return the entire data set. (default: False)
    If run_one_datapoint=true, return a random data.

    """
    if not settings.configured:
        settings.configure()

    @wraps(func)
    def func_wrapper(*args, **kwargs):
        """Perform smoke test attribute check"""
        dataset = func(*args, **kwargs)
        if isinstance(dataset, dict):
            # New UI tests are written using pytest, update dict to support pytest's parametrize
            if ('ui' in args or kwargs.get('interface') == 'ui'
                    and settings.ui.webdriver == 'chrome'):
                # Chromedriver only supports BMP chars
                utf8 = dataset.pop('utf8', None)
                if utf8:
                    dataset['utf8'] = gen_utf8(len(utf8), smp=False)
            if settings.robottelo.run_one_datapoint:
                key = random.choice(list(dataset.keys()))
                dataset = {key: dataset[key]}
        else:
            # Otherwise use list for backwards compatibility
            dataset = list(dataset)
            if settings.robottelo.run_one_datapoint:
                dataset = [random.choice(dataset)]
        return dataset

    return func_wrapper
Beispiel #6
0
def pytest_collection_modifyitems(items, config):
    """ called after collection has been performed, may filter or re-order
    the items in-place.

    Deselecting all tests skipped due to WONTFIX BZ.
    """
    if not settings.configured:
        settings.configure()

    if settings.bugzilla.wontfix_lookup is not True:
        # if lookup is disable return all collection unmodified
        log('Deselect of WONTFIX BZs is disabled in settings')
        return items

    deselected_items = []
    wontfix_ids = pytest.bugzilla.wontfix_ids
    decorated_functions = group_by_key(pytest.bugzilla.decorated_functions)

    log("Found WONTFIX in decorated tests %s" % wontfix_ids)
    log("Collected %s test cases" % len(items))

    for item in items:
        name = get_func_name(item.function)
        bug_ids = decorated_functions.get(name)
        if bug_ids:
            for bug_id in bug_ids:
                if bug_id in wontfix_ids:
                    deselected_items.append(item)
                    log("Deselected test %s due to WONTFIX" % name)
                    break

    config.hook.pytest_deselected(items=deselected_items)
    items[:] = [item for item in items if item not in deselected_items]
Beispiel #7
0
def pytest_collection_modifyitems(items, config):
    """ called after collection has been performed, may filter or re-order
    the items in-place.

    Deselecting all tests skipped due to WONTFIX BZ.
    """
    if not settings.configured:
        settings.configure()

    if settings.bugzilla.wontfix_lookup is not True:
        # if lookup is disable return all collection unmodified
        log('BZ deselect is disabled in settings')
        return items

    deselected_items = []
    decorated_functions = group_by_key(pytest.bugzilla.decorated_functions)

    log("Collected %s test cases" % len(items))

    for item in items:
        name = get_func_name(item.function, test_item=item)
        bug_ids = list(decorated_functions.get(name, []))
        bug_ids.extend(_extract_setup_class_ids(item))
        if any(bug_id in pytest.bugzilla.removal_ids for bug_id in bug_ids):
            deselected_items.append(item)
            log("Deselected test %s" % name)

    config.hook.pytest_deselected(items=deselected_items)
    items[:] = [item for item in items if item not in deselected_items]
Beispiel #8
0
 def setUpClass(cls):  # noqa
     super(TestCase, cls).setUpClass()
     if not settings.configured:
         settings.configure()
     cls.logger = logging.getLogger('robottelo')
     # NOTE: longMessage defaults to True in Python 3.1 and above
     cls.longMessage = True
Beispiel #9
0
def pytest_collection_modifyitems(items, config):
    """ called after collection has been performed, may filter or re-order
    the items in-place.

    Deselecting all tests skipped due to WONTFIX BZ.
    """
    if not settings.configured:
        settings.configure()

    if settings.bugzilla.wontfix_lookup is not True:
        # if lookup is disable return all collection unmodified
        log('BZ deselect is disabled in settings')
        return items

    deselected_items = []
    decorated_functions = group_by_key(pytest.bugzilla.decorated_functions)

    log("Collected %s test cases" % len(items))

    for item in items:
        name = get_func_name(item.function, test_item=item)
        bug_ids = list(decorated_functions.get(name, []))
        bug_ids.extend(_extract_setup_class_ids(item))
        if any(bug_id in pytest.bugzilla.removal_ids for bug_id in bug_ids):
            deselected_items.append(item)
            log("Deselected test %s" % name)

    config.hook.pytest_deselected(items=deselected_items)
    items[:] = [item for item in items if item not in deselected_items]
Beispiel #10
0
def get_decorated_bugs():  # pragma: no cover
    """Using Robozilla parser, get all IDs from skip_if_bug_open decorator
    and return the dictionary containing fetched data.

    Important information is stored on `bug_data` key::
        bugs[BUG_ID]['bug_data']['resolution|status|flags|whiteboard']
    """

    if not settings.configured:
        settings.configure()

    # look for settings bugzilla credentials
    # any way Parser bugzilla reader will check for exported environment names
    # BUGZILLA_USER_NAME and BUGZILLA_USER_PASSWORD if no credentials was
    # supplied
    bz_reader_options = {}
    bz_credentials = {}
    if setting_is_set('bugzilla'):
        bz_credentials = settings.bugzilla.get_credentials()

    bz_reader_options['credentials'] = bz_credentials
    parser = Parser(BASE_PATH, filters=[BZDecorator],
                    reader_options=bz_reader_options)
    bugs = parser.parse()
    return bugs
Beispiel #11
0
 def __init__(self):
     """Configure the settings and initiate report portal properties"""
     if not settings.configured:
         settings.configure()
     self.rp_url = settings.report_portal.rp_url
     self.rp_project = settings.report_portal.rp_project
     self.rp_api_key = settings.report_portal.rp_key
Beispiel #12
0
 def setUpClass(cls):  # noqa
     super().setUpClass()
     if not settings.configured:
         settings.configure()
     cls.logger = logging.getLogger('robottelo')
     cls.logger.info(f'Started setUpClass: {cls.__module__}/{cls.__name__}')
     # NOTE: longMessage defaults to True in Python 3.1 and above
     cls.longMessage = True
     cls.foreman_user = settings.server.admin_username
     cls.foreman_password = settings.server.admin_password
Beispiel #13
0
def setting_is_set(option):
    """Return either ``True`` or ``False`` if a Robottelo section setting is
    set or not respectively.
    """
    if not settings.configured:
        settings.configure()
    # Example: `settings.clients`
    if getattr(settings, option).validate():
        return False
    return True
Beispiel #14
0
def setting_is_set(option):
    """Return either ``True`` or ``False`` if a Robottelo section setting is
    set or not respectively.
    """
    if not settings.configured:
        settings.configure()
    # Example: `settings.clients`
    if getattr(settings, option).validate():
        return False
    return True
Beispiel #15
0
def browse(entity, browser, host):
    """Opens a page in defined browser for interaction:\n
    All parameters defaults to what is in robottelo.properties file.\n
        example: $ manage ui browse activationkey\n
                 Opens a browser in ActivationKey scope and gives you
                 interactive shell to play with the page\n
    """
    settings.configure()
    if host:
        settings.server.hostname = host
    current_browser = _get_browser(browser)
    with Session(current_browser) as session:  # noqa

        ui_crud = _import_ui_crud()
        # Make all UI CRUD entities available in a dict
        # each entity initialized with current_browser instance
        ui_entities = {name.lower(): crud_class(current_browser) for name, crud_class in ui_crud.items()}
        if entity:
            # if entity name specified navigate to the page
            # example: manage ui browse user
            ui_entities[entity.lower()].navigate_to_entity()

        # gets all functions from ui.factory module which starts with 'make_'
        ui_factory_members = getmembers(ui_factory, lambda i: callable(i) and i.__name__.startswith("make"))
        # Usually we need to pass the `session` as 1st argument
        # e.g `make_user(session, username='******')`
        # using `partial` we make session the default 1st argument
        # it allows the use as: `make_user(username='******')
        # and `session` is implicit there.
        ui_factory_functions = {name: partial(function, session=session) for name, function in ui_factory_members}

        # now we "inject" the factories and entities under `session.ui`
        session.ui = Storage(ui_entities, ui_factory_functions)

        # The same for nailgun.entities.* under `session.api`
        session.api = Storage(dict(getmembers(entities)))

        def close():
            """Hook to close the session and browser atexit it also flushes
            the session history content to the specified file
            """
            session.close()
            # FIXME: if --out=/path/to/file should save session history
            # see ipython.readthedocs.io/en/stable/config/options/terminal.html

        extra_vars = {
            "session": session,
            "browser": current_browser,
            "current_browser": current_browser,
            "host": settings.server.hostname,
            "api_factory": entities,
            "ui_factory": ui_factory,
        }

        create_shell("ipython", extra_vars=extra_vars, exit_hooks=[close])
Beispiel #16
0
 def setUpClass(cls):  # noqa
     super(TestCase, cls).setUpClass()
     if not settings.configured:
         settings.configure()
     cls.logger = logging.getLogger('robottelo')
     cls.logger.info('Started setUpClass: {0}/{1}'.format(
         cls.__module__, cls.__name__))
     # NOTE: longMessage defaults to True in Python 3.1 and above
     cls.longMessage = True
     cls.foreman_user = settings.server.admin_username
     cls.foreman_password = settings.server.admin_password
Beispiel #17
0
def config_picker():
    """Return a dict with config for robozilla.decorators
    it is implemented because `settings` object can't be configured
    at module level, so we make it lazy by this function"""
    if not settings.configured:
        settings.configure()
    config = {'upstream': settings.upstream}
    if setting_is_set('bugzilla'):
        config['bz_credentials'] = settings.bugzilla.get_credentials()
        config['wontfix_lookup'] = settings.bugzilla.wontfix_lookup
    return config
Beispiel #18
0
def config_picker():
    """Return a dict with config for robozilla.decorators
    it is implemented because `settings` object can't be configured
    at module level, so we make it lazy by this function"""
    if not settings.configured:
        settings.configure()
    config = {'upstream': settings.upstream}
    if setting_is_set('bugzilla'):
        config['bz_credentials'] = settings.bugzilla.get_credentials()
        config['wontfix_lookup'] = settings.bugzilla.wontfix_lookup
    return config
Beispiel #19
0
 def wrapper(*args, **kwargs):
     if not settings.configured:
         settings.configure()
     missing = []
     for option in options:
         # Example: `settings.clients`
         if getattr(settings, option).validate():
             # List of all sections that are not fully configured
             missing.append(option)
     if not missing:
         return func(*args, **kwargs)
     raise unittest2.SkipTest(
         'Missing configuration for: {0}.'.format(', '.join(missing)))
Beispiel #20
0
 def wrapper(*args, **kwargs):
     if not settings.configured:
         settings.configure()
     missing = []
     for option in options:
         # Example: `settings.clients`
         if getattr(settings, option).validate():
             # List of all sections that are not fully configured
             missing.append(option)
     if not missing:
         return func(*args, **kwargs)
     raise unittest2.SkipTest('Missing configuration for: {0}.'.format(
         ', '.join(missing)))
Beispiel #21
0
 def setUpClass(cls):  # noqa
     super(TestCase, cls).setUpClass()
     if not settings.configured:
         settings.configure()
     cls.logger = logging.getLogger('robottelo')
     cls.logger.debug('Started setUpClass: {0}/{1}'.format(
         cls.__module__, cls.__name__))
     # NOTE: longMessage defaults to True in Python 3.1 and above
     cls.longMessage = True
     cls.foreman_user = settings.server.admin_username
     cls.foreman_password = settings.server.admin_password
     if settings.cleanup:
         cls.cleaner = EntitiesCleaner(entities.Organization, entities.Host,
                                       entities.HostGroup)
Beispiel #22
0
    def __init__(self, rp_url, rp_api_key, rp_project):
        """Configure the settings and initiate report portal properties"""
        if not settings.configured:
            settings.configure()
        self.rp_url = rp_url
        self.rp_project = rp_project
        self.rp_api_key = rp_api_key
        self.rp_project_settings = None

        # fetch the project settings
        settings_req = requests.get(url=f'{self.api_url}/settings',
                                    headers=self.headers,
                                    verify=False)
        settings_req.raise_for_status()
        self.rp_project_settings = settings_req.json()
Beispiel #23
0
 def setUpClass(cls):  # noqa
     super(TestCase, cls).setUpClass()
     if not settings.configured:
         settings.configure()
     cls.logger = logging.getLogger('robottelo')
     cls.logger.debug('Started setUpClass: {0}/{1}'.format(
         cls.__module__, cls.__name__))
     # NOTE: longMessage defaults to True in Python 3.1 and above
     cls.longMessage = True
     cls.foreman_user = settings.server.admin_username
     cls.foreman_password = settings.server.admin_password
     if settings.cleanup:
         cls.cleaner = EntitiesCleaner(
             entities.Organization,
             entities.Host,
             entities.HostGroup
         )
Beispiel #24
0
    def module_roles(self):
        """
        Initializes class attribute ``dct_roles`` with several random roles
        saved on sat. roles is a dict so keys are role's id respective value is
        the role itself
        """
        settings.configure()
        include_list = [gen_string("alphanumeric", 100)]

        def roles_helper():
            """Generator funcion which creates several Roles to be used on
            tests
            """
            for role_name in valid_usernames_list() + include_list:
                yield make_role({'name': role_name})

        stubbed_roles = {role['id']: role for role in roles_helper()}
        yield stubbed_roles
Beispiel #25
0
        def wrapper(*args, **kwargs):
            """Wrapper that will skip the test if one of defined versions
            match host's version.
            """
            def log_version_info(msg, template):
                LOGGER.debug(template, func.__name__, func.__module__, msg)

            if not settings.configured:
                settings.configure()

            host_version = get_host_os_version()

            if any(host_version.startswith(version) for version in versions):
                skip_msg = f'host {host_version} in ignored versions {versions}'
                skip_template = 'Skipping test %s in module %s due to %s'
                log_version_info(skip_msg, skip_template)
                raise unittest2.SkipTest(skip_msg)

            return func(*args, **kwargs)
Beispiel #26
0
def get_deselect_bug_ids(bugs=None, log=None, lookup=None):  # pragma: no cover
    """returns the IDs of bugs to be deselected from test collection"""

    if not settings.configured:
        settings.configure()

    lookup = lookup or settings.bugzilla.wontfix_lookup
    if lookup is not True:
        return []

    if log is None:
        log = log_debug

    log('Fetching BZs to deselect...')
    bugs = bugs or get_decorated_bugs()
    resolution_list = []
    flag_list = []
    backlog_list = []
    for bug_id, data in bugs.items():
        bug_data = data.get('bug_data')
        # when not authenticated, private bugs will have no bug data
        if bug_data:
            if 'sat-backlog' in bug_data.get('flags', {}):
                backlog_list.append(bug_id)
            if bug_data['resolution'] in ('WONTFIX', 'CANTFIX', 'DEFERRED'):
                resolution_list.append(bug_id)
            if not any([flag in bug_data.get('flags', {}) for flag in VFLAGS]):
                # If the BZ is not flagged with any of `sat-x.x.x`
                flag_list.append(bug_id)
        else:
            log('bug data for bug id "{}" was not retrieved,'
                ' please review bugzilla credentials'.format(bug_id))

    if resolution_list:
        log('Deselected tests reason: BZ resolution %s' % resolution_list)

    if flag_list:
        log('Deselected tests reason: missing version flag %s' % flag_list)

    if backlog_list:
        log('Deselected tests reason: sat-backlog %s' % backlog_list)

    return set(resolution_list + flag_list + backlog_list)
Beispiel #27
0
def get_deselect_bug_ids(bugs=None, log=None, lookup=None):  # pragma: no cover
    """returns the IDs of bugs to be deselected from test collection"""

    if not settings.configured:
        settings.configure()

    lookup = lookup or settings.bugzilla.wontfix_lookup
    if lookup is not True:
        return []

    if log is None:
        log = log_debug

    log('Fetching BZs to deselect...')
    bugs = bugs or get_decorated_bugs()
    resolution_list = []
    flag_list = []
    backlog_list = []
    for bug_id, data in bugs.items():
        bug_data = data.get('bug_data')
        # when not authenticated, private bugs will have no bug data
        if bug_data:
            if 'sat-backlog' in bug_data.get('flags', {}):
                backlog_list.append(bug_id)
            if bug_data['resolution'] in ('WONTFIX', 'CANTFIX', 'DEFERRED'):
                resolution_list.append(bug_id)
            if not any([flag in bug_data.get('flags', {}) for flag in VFLAGS]):
                # If the BZ is not flagged with any of `sat-x.x.x`
                flag_list.append(bug_id)
        else:
            log('bug data for bug id "{}" was not retrieved,'
                ' please review bugzilla credentials'.format(bug_id))

    if resolution_list:
        log('Deselected tests reason: BZ resolution %s' % resolution_list)

    if flag_list:
        log('Deselected tests reason: missing version flag %s' % flag_list)

    if backlog_list:
        log('Deselected tests reason: sat-backlog %s' % backlog_list)

    return set(resolution_list + flag_list + backlog_list)
Beispiel #28
0
    def setUpClass(cls):
        """
        Initializes class attribute ``dct_roles`` with several random roles
        saved on sat. roles is a dict so keys are role's id respective value is
        the role itself
        """

        super(UserWithCleanUpTestCase, cls).setUpClass()
        settings.configure()
        include_list = [gen_string("alphanumeric", 100)]

        def roles_helper():
            """Generator funcion which creates several Roles to be used on
            tests
            """
            for role_name in valid_usernames_list() + include_list:
                yield make_role({'name': role_name})

        cls.stubbed_roles = {role['id']: role for role in roles_helper()}
        cls.all_roles = {role['id']: role for role in Role.list()}
Beispiel #29
0
    def setUpClass(cls):
        """
        Initializes class attribute ``dct_roles`` with several random roles
        saved on sat. roles is a dict so keys are role's id respective value is
        the role itself
        """

        super(UserWithCleanUpTestCase, cls).setUpClass()
        settings.configure()
        include_list = [gen_string("alphanumeric", 100)]

        def roles_helper():
            """Generator funcion which creates several Roles to be used on
            tests
            """
            for role_name in valid_usernames_list() + include_list:
                yield make_role({'name': role_name})

        cls.stubbed_roles = {role['id']: role for role in roles_helper()}
        cls.all_roles = {role['id']: role for role in Role.list()}
Beispiel #30
0
        def wrapper(*args, **kwargs):
            """Wrapper that will skip the test if one of defined versions
            match host's version.
            """
            def log_version_info(msg, template):
                LOGGER.debug(template, func.__name__, func.__module__, msg)

            if not settings.configured:
                settings.configure()

            host_version = get_host_os_version()

            if any(host_version.startswith(version) for version in versions):
                skip_msg = 'host {0} in ignored versions {1}'.format(
                    host_version,
                    versions
                )
                skip_template = 'Skipping test %s in module %s due to %s'
                log_version_info(skip_msg, skip_template)
                raise unittest2.SkipTest(skip_msg)

            return func(*args, **kwargs)
Beispiel #31
0
def align_xdist_satellites(worker_id):
    """Set a different Satellite per worker when available in robottelo's config"""
    settings.configure()
    settings.server.hostname = settings.server.get_hostname(worker_id)
    settings.configure_nailgun()
    settings.configure_airgun()
Beispiel #32
0
"""Only External Repos url specific constants module"""
from robottelo.config import settings

if not settings.configured:
    settings.configure()

REPOS_URL = settings.repos_hosting_url

CUSTOM_FILE_REPO = 'https://fixtures.pulpproject.org/file/'
CUSTOM_KICKSTART_REPO = 'http://ftp.cvut.cz/centos/8/BaseOS/x86_64/kickstart/'
CUSTOM_RPM_REPO = 'https://fixtures.pulpproject.org/rpm-signed/'
CUSTOM_RPM_SHA_512 = 'https://fixtures.pulpproject.org/rpm-with-sha-512/'
CUSTOM_MODULE_STREAM_REPO_1 = f'{REPOS_URL}/module_stream1'
CUSTOM_MODULE_STREAM_REPO_2 = f'{REPOS_URL}/module_stream2'
CUSTOM_SWID_TAG_REPO = f'{REPOS_URL}/swid_zoo'
FAKE_0_YUM_REPO = f'{REPOS_URL}/fake_yum0'
FAKE_1_YUM_REPO = f'{REPOS_URL}/fake_yum1'
FAKE_2_YUM_REPO = f'{REPOS_URL}/fake_yum2'
FAKE_3_YUM_REPO = f'{REPOS_URL}/fake_yum3'
FAKE_4_YUM_REPO = f'{REPOS_URL}/fake_yum4'
FAKE_5_YUM_REPO = 'http://{0}:{1}@rplevka.fedorapeople.org/fakerepo01/'
FAKE_6_YUM_REPO = f'{REPOS_URL}/needed_errata'
FAKE_7_YUM_REPO = f'{REPOS_URL}/pulp/demo_repos/large_errata/zoo/'
FAKE_8_YUM_REPO = f'{REPOS_URL}/lots_files'
FAKE_9_YUM_REPO = f'{REPOS_URL}/multiple_errata'
FAKE_10_YUM_REPO = f'{REPOS_URL}/modules_rpms'
FAKE_11_YUM_REPO = f'{REPOS_URL}/rpm_deps'
FAKE_YUM_DRPM_REPO = 'https://fixtures.pulpproject.org/drpm-signed/'
FAKE_YUM_SRPM_REPO = 'https://fixtures.pulpproject.org/srpm-signed/'
FAKE_YUM_SRPM_DUPLICATE_REPO = 'https://fixtures.pulpproject.org/srpm-duplicate/'
FAKE_YUM_MIXED_REPO = f'{REPOS_URL}/yum_mixed'
Beispiel #33
0
def configured_settings():
    if not settings.configured:
        settings.configure()
    return settings
Beispiel #34
0
def browse(entity, browser, host):
    """Opens a page in defined browser for interaction:\n
    All parameters defaults to what is in robottelo.properties file.\n
        example: $ manage ui browse activationkey\n
                 Opens a browser in ActivationKey scope and gives you
                 interactive shell to play with the page\n
    """
    settings.configure()
    if host:
        settings.server.hostname = host
    current_browser = _get_browser(browser)
    with Session(current_browser) as session:  # noqa

        ui_crud = _import_ui_crud()
        # Make all UI CRUD entities available in a dict
        # each entity initialized with current_browser instance
        ui_entities = {
            name.lower(): crud_class(current_browser)
            for name, crud_class in ui_crud.items()
        }
        if entity:
            # if entity name specified navigate to the page
            # example: manage ui browse user
            ui_entities[entity.lower()].navigate_to_entity()

        # gets all functions from ui.factory module which starts with 'make_'
        ui_factory_members = getmembers(
            ui_factory,
            lambda i: callable(i) and i.__name__.startswith('make'))
        # Usually we need to pass the `session` as 1st argument
        # e.g `make_user(session, username='******')`
        # using `partial` we make session the default 1st argument
        # it allows the use as: `make_user(username='******')
        # and `session` is implicit there.
        ui_factory_functions = {
            name: partial(function, session=session)
            for name, function in ui_factory_members
        }

        # now we "inject" the factories and entities under `session.ui`
        session.ui = Storage(ui_entities, ui_factory_functions)

        # The same for nailgun.entities.* under `session.api`
        session.api = Storage(dict(getmembers(entities)))

        def close():
            """Hook to close the session and browser atexit it also flushes
            the session history content to the specified file
            """
            session.close()
            # FIXME: if --out=/path/to/file should save session history
            # see ipython.readthedocs.io/en/stable/config/options/terminal.html

        extra_vars = {
            'session': session,
            'browser': current_browser,
            'current_browser': current_browser,
            'host': settings.server.hostname,
            'api_factory': entities,
            'ui_factory': ui_factory
        }

        create_shell('ipython', extra_vars=extra_vars, exit_hooks=[close])
import json

from robottelo import ssh
from robottelo.cli import hammer
from robottelo.config import settings


def generate_command_tree(command):
    """Recursively walk trhough the hammer commands and subcommands and fetch
    their help. Return a dictionary with the contents.

    """
    output = ssh.command('{0} --help'.format(command)).stdout
    contents = hammer.parse_help(output)
    if len(contents['subcommands']) > 0:
        for subcommand in contents['subcommands']:
            subcommand.update(generate_command_tree(
                '{0} {1}'.format(command, subcommand['name'])
            ))
    return contents

settings.configure()

# Generate the json file in the working directory
with open('hammer_commands.json', 'w') as f:
    f.write(json.dumps(
        generate_command_tree('hammer'),
        indent=2,
        sort_keys=True
    ))
Beispiel #36
0
def configured_settings():
    if not settings.configured:
        settings.configure()
    return settings
Beispiel #37
0
def generate_issue_collection(items, config):  # pragma: no cover
    """Generates a dictionary with the usage of Issue blockers

    Arguments:
        items {list} - List of pytest test case objects.
        config {dict} - Pytest config object.

    Returns:
        [List of dicts] - Dicts indexed by "<handler>:<issue>"

        Example of return data::

            {
                "XX:1625783" {
                    "data": {
                        # data taken from REST api,
                        "status": ...,
                        "resolution": ...,
                        ...
                        # Calculated data
                        "is_open": bool,
                        "is_deselected": bool,
                        "clones": [list],
                        "dupe_data": {dict}
                    },
                    "used_in" [
                        {
                            "filepath": "tests/foreman/ui/test_sync.py",
                            "lineno": 124,
                            "testcase": "test_positive_sync_custom_ostree_repo",
                            "component": "Repositories",
                            "usage": "skip_if_open"
                        },
                        ...
                    ]
                },
                ...
            }
    """
    settings.configure()
    valid_markers = ["skip_if_open", "skip", "deselect"]
    collected_data = defaultdict(lambda: {"data": {}, "used_in": []})

    bz_cache = config.getvalue('bz_cache')  # use existing json cache?
    cached_data = None
    if bz_cache:
        with open(bz_cache) as bz_cache_file:
            cached_data = {
                k: _handle_version(k, v)
                for k, v in json.load(bz_cache_file).items()
            }

    deselect_data = {}  # a local cache for deselected tests

    IS_OPEN = re.compile(
        # To match `if is_open('BZ:123456'):`
        r"\s*if\sis_open\(\S(?P<src>\D{2})\s*:\s*(?P<num>\d*)\S\)\d*")

    NOT_IS_OPEN = re.compile(
        # To match `if not is_open('BZ:123456'):`
        r"\s*if\snot\sis_open\(\S(?P<src>\D{2})\s*:\s*(?P<num>\d*)\S\)\d*")

    COMPONENT = re.compile(
        # To match :CaseComponent: FooBar
        r"\s*:CaseComponent:\s*(?P<component>\S*)",
        re.IGNORECASE,
    )

    IMPORTANCE = re.compile(
        # To match :CaseImportance: Critical
        r"\s*:CaseImportance:\s*(?P<importance>\S*)",
        re.IGNORECASE,
    )

    BZ = re.compile(
        # To match :BZ: 123456, 456789
        r"\s*:BZ:\s*(?P<bz>.*\S*)",
        re.IGNORECASE,
    )

    test_modules = set()

    # --- Build the issue marked usage collection ---
    for item in items:
        component = None
        bzs = None
        importance = None

        # register test module as processed
        test_modules.add(item.module)

        # Find matches from docstrings top-down from: module, class, function.
        mod_cls_fun = (item.module, getattr(item, 'cls', None), item.function)
        for docstring in map(inspect.getdoc, mod_cls_fun):
            if not docstring:
                continue
            component_matches = COMPONENT.findall(docstring)
            if component_matches:
                component = component_matches[-1]
            bz_matches = BZ.findall(docstring)
            if bz_matches:
                bzs = bz_matches[-1]
            importance_matches = IMPORTANCE.findall(docstring)
            if importance_matches:
                importance = importance_matches[-1]

        filepath, lineno, testcase = item.location
        component_mark = slugify_component(component, False)
        for marker in item.iter_markers():
            if marker.name in valid_markers:
                issue = marker.kwargs.get('reason') or marker.args[0]
                issue_key = issue.strip()
                collected_data[issue_key]['used_in'].append({
                    'filepath':
                    filepath,
                    'lineno':
                    lineno,
                    'testcase':
                    testcase,
                    'component':
                    component,
                    'importance':
                    importance,
                    'component_mark':
                    component_mark,
                    'usage':
                    marker.name,
                })

                # Store issue key to lookup in the deselection process
                deselect_data[item.location] = issue_key
                # Add issue as a marker to enable filtering e.g: "-m BZ_123456"
                item.add_marker(
                    getattr(pytest.mark, issue_key.replace(':', '_')))

        # Then take the workarounds using `is_open` helper.
        source = inspect.getsource(item.function)
        if 'is_open(' in source:
            kwargs = {
                'filepath': filepath,
                'lineno': lineno,
                'testcase': testcase,
                'component': component,
                'importance': importance,
                'component_mark': component_mark,
            }
            _add_workaround(collected_data, IS_OPEN.findall(source), 'is_open',
                            **kwargs)
            _add_workaround(collected_data, NOT_IS_OPEN.findall(source),
                            'not is_open', **kwargs)

        # Add component as a marker to anable filtering e.g: "-m contentviews"
        item.add_marker(getattr(pytest.mark, component_mark))

        # Add BZs from tokens as a marker to enable filter e.g: "-m BZ_123456"
        if bzs:
            for bz in bzs.split(','):
                item.add_marker(getattr(pytest.mark, f'BZ_{bz.strip()}'))

        # Add importance as a token
        if importance:
            item.add_marker(getattr(pytest.mark, importance.lower().strip()))

    # Take uses of `is_open` from outside of test cases e.g: SetUp methods
    for test_module in test_modules:
        module_source = inspect.getsource(test_module)
        component_matches = COMPONENT.findall(module_source)
        module_component = None
        if component_matches:
            module_component = component_matches[0]
        if 'is_open(' in module_source:
            kwargs = {
                'filepath': test_module.__file__,
                'lineno': 1,
                'testcase': test_module.__name__,
                'component': module_component,
            }

            def validation(data, issue, usage, **kwargs):
                return issue not in data

            _add_workaround(
                collected_data,
                IS_OPEN.findall(module_source),
                'is_open',
                validation=validation,
                **kwargs,
            )
            _add_workaround(
                collected_data,
                NOT_IS_OPEN.findall(module_source),
                'not is_open',
                validation=validation,
                **kwargs,
            )

    # --- Collect BUGZILLA data ---
    bugzilla.collect_data_bz(collected_data, cached_data)

    # --- add deselect markers dinamically ---
    for item in items:
        issue = deselect_data.get(item.location)
        if issue and _should_deselect(issue, collected_data[issue]['data']):
            collected_data[issue]['data']['is_deselected'] = True
            item.add_marker(pytest.mark.deselect(reason=issue))

    # --- if not using pre-existing cache write it ---
    if not bz_cache:
        collected_data['_meta'] = {
            "version": settings.server.version,
            "hostname": settings.server.hostname,
            "created": datetime.now().isoformat(),
            "pytest": {
                "args": config.args,
                "pwd": str(config.invocation_dir)
            },
        }
        with open('bz_cache.json', 'w') as collect_file:
            json.dump(collected_data,
                      collect_file,
                      indent=4,
                      cls=VersionEncoder)
            LOGGER.debug(
                f"Generated file {bz_cache or 'bz_cache.json'} with BZ collect data"
            )

    return collected_data
Beispiel #38
0
def generate_issue_collection(items, config):  # pragma: no cover
    """Generates a dictionary with the usage of Issue blockers

    For use in pytest_collection_modifyitems hook

    Arguments:
        items {list} - List of pytest test case objects.
        config {dict} - Pytest config object.

    Returns:
        [List of dicts] - Dicts indexed by "<handler>:<issue>"

        Example of return data::

            {
                "XX:1625783" {
                    "data": {
                        # data taken from REST api,
                        "status": ...,
                        "resolution": ...,
                        ...
                        # Calculated data
                        "is_open": bool,
                        "is_deselected": bool,
                        "clones": [list],
                        "dupe_data": {dict}
                    },
                    "used_in" [
                        {
                            "filepath": "tests/foreman/ui/test_sync.py",
                            "lineno": 124,
                            "testcase": "test_positive_sync_custom_ostree_repo",
                            "component": "Repositories",
                            "usage": "skip_if_open"
                        },
                        ...
                    ]
                },
                ...
            }
    """
    if not settings.configured:
        settings.configure()
    valid_markers = ["skip_if_open", "skip", "deselect"]
    collected_data = defaultdict(lambda: {"data": {}, "used_in": []})

    use_bz_cache = config.getoption('bz_cache', None)  # use existing json cache?
    cached_data = None
    if use_bz_cache:
        try:
            with open(DEFAULT_BZ_CACHE_FILE) as bz_cache_file:
                logger.info(f'Using BZ cache file for issue collection: {DEFAULT_BZ_CACHE_FILE}')
                cached_data = {
                    k: search_version_key(k, v) for k, v in json.load(bz_cache_file).items()
                }
        except FileNotFoundError:
            # no bz cache file exists
            logger.warning(
                f'--bz-cache option used, cache file [{DEFAULT_BZ_CACHE_FILE}] not found'
            )

    deselect_data = {}  # a local cache for deselected tests

    test_modules = set()

    # --- Build the issue marked usage collection ---
    for item in items:
        if item.nodeid.startswith('tests/robottelo/'):
            # Unit test, no bz processing
            # TODO: We very likely don't need to include component and importance in collected_data
            # Removing these would unravel issue_handlers dependence on testimony
            # Allowing for issue_handler use in unit tests
            continue

        bz_marks_to_add = []
        # register test module as processed
        test_modules.add(item.module)
        # Find matches from docstrings top-down from: module, class, function.
        mod_cls_fun = (item.module, getattr(item, 'cls', None), item.function)
        for docstring in [d for d in map(inspect.getdoc, mod_cls_fun) if d is not None]:
            bz_matches = BZ.findall(docstring)
            if bz_matches:
                bz_marks_to_add.extend(b.strip() for b in bz_matches[-1].split(','))

        filepath, lineno, testcase = item.location
        # Component and importance marks are determined by testimony tokens
        # Testimony.yaml as of writing has both as required, so any
        component_mark = item.get_closest_marker('component').args[0]
        component_slug = slugify_component(component_mark, False)
        importance_mark = item.get_closest_marker('importance').args[0]
        for marker in item.iter_markers():
            if marker.name in valid_markers:
                issue = marker.kwargs.get('reason') or marker.args[0]
                issue_key = issue.strip()
                collected_data[issue_key]['used_in'].append(
                    {
                        'filepath': filepath,
                        'lineno': lineno,
                        'testcase': testcase,
                        'component': component_mark,
                        'importance': importance_mark,
                        'component_mark': component_slug,
                        'usage': marker.name,
                    }
                )

                # Store issue key to lookup in the deselection process
                deselect_data[item.location] = issue_key
                # Add issue as a marker to enable filtering e.g: "--BZ 123456"
                bz_marks_to_add.append(issue_key.split(':')[-1])

        # Then take the workarounds using `is_open` helper.
        source = inspect.getsource(item.function)
        if 'is_open(' in source:
            kwargs = {
                'filepath': filepath,
                'lineno': lineno,
                'testcase': testcase,
                'component': component_mark,
                'importance': importance_mark,
                'component_mark': component_slug,
            }
            add_workaround(collected_data, IS_OPEN.findall(source), 'is_open', **kwargs)
            add_workaround(collected_data, NOT_IS_OPEN.findall(source), 'not is_open', **kwargs)

        # Add BZs from tokens as a marker to enable filter e.g: "--BZ 123456"
        if bz_marks_to_add:
            item.add_marker(pytest.mark.BZ(*bz_marks_to_add))

    # Take uses of `is_open` from outside of test cases e.g: SetUp methods
    for test_module in test_modules:
        module_source = inspect.getsource(test_module)
        component_matches = COMPONENT.findall(module_source)
        module_component = None
        if component_matches:
            module_component = component_matches[0]
        if 'is_open(' in module_source:
            kwargs = {
                'filepath': test_module.__file__,
                'lineno': 1,
                'testcase': test_module.__name__,
                'component': module_component,
            }

            def validation(data, issue, usage, **kwargs):
                return issue not in data

            add_workaround(
                collected_data,
                IS_OPEN.findall(module_source),
                'is_open',
                validation=validation,
                **kwargs,
            )
            add_workaround(
                collected_data,
                NOT_IS_OPEN.findall(module_source),
                'not is_open',
                validation=validation,
                **kwargs,
            )

    # --- Collect BUGZILLA data ---
    bugzilla.collect_data_bz(collected_data, cached_data)

    # --- add deselect markers dynamically ---
    for item in items:
        issue = deselect_data.get(item.location)
        if issue and should_deselect(issue, collected_data[issue]['data']):
            collected_data[issue]['data']['is_deselected'] = True
            item.add_marker(pytest.mark.deselect(reason=issue))

    # --- if no cache file existed write a new cache file ---
    if cached_data is None and use_bz_cache:
        collected_data['_meta'] = {
            "version": settings.server.version,
            "hostname": settings.server.hostname,
            "created": datetime.now().isoformat(),
            "pytest": {"args": config.args, "pwd": str(config.invocation_dir)},
        }
        # bz_cache_filename could be None from the option not being passed, write the file anyway
        with open(DEFAULT_BZ_CACHE_FILE, 'w') as collect_file:
            json.dump(collected_data, collect_file, indent=4, cls=VersionEncoder)
            logger.info(f"Generated BZ cache file {DEFAULT_BZ_CACHE_FILE}")

    return collected_data
Beispiel #39
0
def init_settings():
    """Explicitly init the robottelo conf settings"""
    if not settings.configured:
        settings.configure()