def _get_template(provider, template_type_name): template = provider.data.get(template_type_name) # if the template is None, try to get it from templates section on provider data # because additional templates are present in this section which are not present # under provider directly if not template: template = provider.data.templates.get(template_type_name) if isinstance(template, Mapping): template_name = template.get("name") else: template_name = template if template_name: if not TEMPLATES: # Same as couple of lines above return template templates = TEMPLATES.get(provider.key) # If template is type string then return template else template_name # since template could be AttrDict and returning it would fail provisioning # _get_template should always return template name of type string if templates and template_name in templates and isinstance(template, six.string_types): return template return template_name else: pytest.skip('No {} for provider {}'.format(template_type_name, provider.key)) logger.info("Wanted template %s on %s but it is not there!", template, provider.key) pytest.skip('Template not available')
def template(template_location, provider): if template_location is not None: o = provider.data try: for field in template_location: o = o[field] except (IndexError, KeyError): logger.info( "Cannot apply %r to %r in the template specification, ignoring.", field, o) else: if not isinstance(o, six.string_types): raise ValueError( "{!r} is not a string! (for template)".format(o)) if not TEMPLATES: # There is nothing in TEMPLATES, that means no trackerbot URL and no data pulled. # This should normally not constitute an issue so continue. return o templates = TEMPLATES.get(provider.key) if templates is not None: if o in templates: return o logger.info("Wanted template %s on %s but it is not there!", o, provider.key) pytest.skip('Template not available')
def _get_template(provider, template_type_name): template = provider.data.get(template_type_name) # if the template is None, try to get it from templates section on provider data # because additional templates are present in this section which are not present # under provider directly if not template: template = provider.data.templates.get(template_type_name) if isinstance(template, Mapping): template_name = template.get("name") else: template_name = template if template_name: if not TEMPLATES: # Same as couple of lines above return template templates = TEMPLATES.get(provider.key) # If template is type string then return template else template_name # since template could be AttrDict and returning it would fail provisioning # _get_template should always return template name of type string if templates and template_name in templates and isinstance( template, six.string_types): return template return template_name else: pytest.skip('No {} for provider {}'.format(template_type_name, provider.key)) logger.info("Wanted template %s on %s but it is not there!", template, provider.key) pytest.skip('Template not available')
def full_template(provider): template = provider.data.get('full_template', {}) if template: templates = TEMPLATES.get(provider.key, None) if templates is not None: if template['name'] in templates: return template logger.info( "Wanted template {} on {} but it is not there!\n".format(template, provider.key)) pytest.skip('Template not available')
def full_template(provider): template = provider.data.get('full_template', {}) if template: templates = TEMPLATES.get(provider.key, None) if templates is not None: if template['name'] in templates: return template logger.info("Wanted template {} on {} but it is not there!\n".format( template, provider.key)) pytest.skip('Template not available')
def full_template(provider): template = provider.data.get('full_template', {}) if template: if not TEMPLATES: # Same as couple of lines above return template templates = TEMPLATES.get(provider.key, None) if templates is not None: if template['name'] in templates: return template else: pytest.skip('No full_template for provider {}'.format(provider.key)) logger.info("Wanted template %s on %s but it is not there!", template, provider.key) pytest.skip('Template not available')
def _get_template(provider, template_type_name): template = provider.data.get(template_type_name, None) if isinstance(template, Mapping): template_name = template.get("name", None) else: template_name = template if template_name: if not TEMPLATES: # Same as couple of lines above return template templates = TEMPLATES.get(provider.key, None) if templates and template_name in templates: return template else: pytest.skip('No {} for provider {}'.format(template_type_name, provider.key)) logger.info("Wanted template %s on %s but it is not there!", template, provider.key) pytest.skip('Template not available')
def template(template_location, provider): if template_location is not None: o = provider.data try: for field in template_location: o = o[field] except (IndexError, KeyError): logger.info("Cannot apply %s to %s in the template specification, ignoring.", repr(field), repr(o)) else: if not isinstance(o, basestring): raise ValueError("{} is not a string! (for template)".format(repr(o))) templates = TEMPLATES.get(provider.key, None) if templates is not None: if o in templates: return o logger.info( "Wanted template {} on {} but it is not there!\n".format(o, provider.key)) pytest.skip('Template not available')
def template(template_location, provider): if template_location is not None: o = provider.data try: for field in template_location: o = o[field] except (IndexError, KeyError): logger.info("Cannot apply %r to %r in the template specification, ignoring.", field, o) else: if not isinstance(o, six.string_types): raise ValueError("{!r} is not a string! (for template)".format(o)) if not TEMPLATES: # There is nothing in TEMPLATES, that means no trackerbot URL and no data pulled. # This should normally not constitute an issue so continue. return o templates = TEMPLATES.get(provider.key, None) if templates is not None: if o in templates: return o logger.info("Wanted template %s on %s but it is not there!", o, provider.key) pytest.skip('Template not available')
def template(template_location, provider): if template_location is not None: o = provider.data try: for field in template_location: o = o[field] except (IndexError, KeyError): logger.info( "Cannot apply %s to %s in the template specification, ignoring.", repr(field), repr(o)) else: if not isinstance(o, basestring): raise ValueError("{} is not a string! (for template)".format( repr(o))) templates = TEMPLATES.get(provider.key, None) if templates is not None: if o in templates: return o logger.info("Wanted template {} on {} but it is not there!\n".format( o, provider.key)) pytest.skip('Template not available')
def provider_by_type(metafunc, provider_types, *fields, **options): """Get the values of the named field keys from ``cfme_data.get('management_systems', {})`` Args: provider_types: A list of provider types to include. If None, all providers are considered *fields: Names of keys in an individual provider dict whose values will be returned when used as test function arguments **options: Explained below The ``**options`` available are defined below: * ``required_fields``: when fields passed are not present, skip them * ``choose_random``: choose a single provider from the list * ``template_location``: Specification where a required tempalte lies in the yaml, If not found in the provider, warning is printed and the test not collected. The spec is a tuple or list where each item is a key to the next field (str or int). The following test function arguments are special: ``provider`` the provider's CRUD object, either a :py:class:`cfme.cloud.provider.Provider` or a :py:class:`cfme.infrastructure.provider.Provider` Returns: An tuple of ``(argnames, argvalues, idlist)`` for use in a pytest_generate_tests hook, or with the :py:func:`parametrize` helper. Usage: # In the function itself def pytest_generate_tests(metafunc): argnames, argvalues, idlist = testgen.provider_by_type( ['openstack', 'ec2'], 'type', 'name', 'credentials', 'provider', 'hosts' ) metafunc.parametrize(argnames, argvalues, ids=idlist, scope='module') # Using the parametrize wrapper pytest_generate_tests = testgen.parametrize(testgen.provider_by_type, ['openstack', 'ec2'], 'type', 'name', 'credentials', 'provider', 'hosts', scope='module') Note: Using the default 'function' scope, each test will be run individually for each provider before moving on to the next test. To group all tests related to single provider together, parametrize tests in the 'module' scope. Note: testgen for providers now requires the usage of test_flags for collection to work. Please visit http://cfme-tests.readthedocs.org/guides/documenting.html#documenting-tests for more details. """ metafunc.function = pytest.mark.uses_testgen()(metafunc.function) argnames = list(fields) argvalues = [] idlist = [] template_location = options.pop("template_location", None) if 'provider' in metafunc.fixturenames and 'provider' not in argnames: argnames.append('provider') for provider, data in cfme_data.get('management_systems', {}).iteritems(): # Check provider hasn't been filtered out with --use-provider if provider not in filtered: continue try: prov_obj = get_crud(provider) except UnknownProviderType: continue if not prov_obj: logger.debug( "Whilst trying to create an object for {} we failed".format( provider)) continue skip = False if provider_types is not None and prov_obj.type not in provider_types: # Skip unwanted types continue restricted_version = data.get('restricted_version', None) if restricted_version: logger.info('we found a restricted version') for op, comparator in _version_operator_map.items(): # split string by op; if the split works, version won't be empty head, op, ver = restricted_version.partition(op) if not ver: # This means that the operator was not found continue if not comparator(version.current_version(), ver): skip = True break else: raise Exception( 'Operator not found in {}'.format(restricted_version)) # Test to see the test has meta data, if it does and that metadata contains # a test_flag kwarg, then check to make sure the provider contains that test_flag # if not, do not collect the provider for this particular test. # Obtain the tests flags meta = getattr(metafunc.function, 'meta', None) test_flags = getattr(meta, 'kwargs', {}) \ .get('from_docs', {}).get('test_flag', '').split(',') if test_flags != ['']: test_flags = [flag.strip() for flag in test_flags] defined_flags = cfme_data.get('test_flags', '').split(',') defined_flags = [flag.strip() for flag in defined_flags] excluded_flags = data.get('excluded_test_flags', '').split(',') excluded_flags = [flag.strip() for flag in excluded_flags] allowed_flags = set(defined_flags) - set(excluded_flags) if set(test_flags) - allowed_flags: logger.info( "Skipping Provider {} for test {} in module {} because " "it does not have the right flags, " "{} does not contain {}".format( provider, metafunc.function.func_name, metafunc.function.__module__, list(allowed_flags), list(set(test_flags) - allowed_flags))) continue try: if prov_obj.type == "scvmm" and version.current_version() < "5.3": # Ignore SCVMM on 5.2 continue if "since_version" in data: # Ignore providers that are not supported in this version yet if version.current_version() < data["since_version"]: continue except Exception: # No SSH connection continue # Get values for the requested fields, filling in with None for undefined fields data_values = {field: data.get(field, None) for field in fields} # Go through the values and handle the special 'data' name # report the undefined fields to the log for key in data_values.keys(): if data_values[key] is None: if 'require_fields' not in options: options['require_fields'] = True if options['require_fields']: skip = True logger.warning( 'Field "%s" not defined for provider "%s", skipping' % (key, provider)) else: logger.debug( 'Field "%s" not defined for provider "%s", defaulting to None' % (key, provider)) if skip: continue # Check the template presence if requested if template_location is not None: o = data try: for field in template_location: o = o[field] except (IndexError, KeyError): logger.info( "Cannot apply {} to {} in the template specification, ignoring." .format(repr(field), repr(o))) else: if not isinstance(o, basestring): raise ValueError( "{} is not a string! (for template)".format(repr(o))) templates = TEMPLATES.get(provider, None) if templates is not None: if o not in templates: logger.info( "Wanted template {} on {} but it is not there!\n". format(o, provider)) # Skip collection of this one continue values = [] for arg in argnames: if arg == 'provider': metafunc.function = pytest.mark.provider_related()( metafunc.function) values.append(prov_obj) elif arg in data_values: values.append(data_values[arg]) # skip when required field is not present and option['require_field'] == True argvalues.append(values) # Use the provider name for idlist, helps with readable parametrized test output idlist.append(provider) # pick a single provider if option['choose_random'] == True if 'choose_random' not in options: options['choose_random'] = False if idlist and options['choose_random']: single_index = idlist.index(random.choice(idlist)) new_idlist = ['random_provider'] new_argvalues = [argvalues[single_index]] logger.debug('Choosing random provider, "%s" selected, ' % (provider)) return argnames, new_argvalues, new_idlist return argnames, argvalues, idlist
def provider_by_type(metafunc, provider_types, *fields, **options): """Get the values of the named field keys from ``cfme_data.get('management_systems', {})`` Args: provider_types: A list of provider types to include. If None, all providers are considered *fields: Names of keys in an individual provider dict whose values will be returned when used as test function arguments **options: Explained below The ``**options`` available are defined below: * ``require_fields``: when fields passed are not present, skip them, boolean * ``template_location``: Specification where a required tempalte lies in the yaml, If not found in the provider, warning is printed and the test not collected. The spec is a tuple or list where each item is a key to the next field (str or int). The following test function arguments are special: ``provider`` the provider's CRUD object, either a :py:class:`cfme.cloud.provider.Provider` or a :py:class:`cfme.infrastructure.provider.Provider` Returns: An tuple of ``(argnames, argvalues, idlist)`` for use in a pytest_generate_tests hook, or with the :py:func:`parametrize` helper. Usage: # In the function itself def pytest_generate_tests(metafunc): argnames, argvalues, idlist = testgen.provider_by_type( ['openstack', 'ec2'], 'type', 'name', 'credentials', 'provider', 'hosts' ) metafunc.parametrize(argnames, argvalues, ids=idlist, scope='module') # Using the parametrize wrapper pytest_generate_tests = testgen.parametrize(testgen.provider_by_type, ['openstack', 'ec2'], 'type', 'name', 'credentials', 'provider', 'hosts', scope='module') Note: Using the default 'function' scope, each test will be run individually for each provider before moving on to the next test. To group all tests related to single provider together, parametrize tests in the 'module' scope. Note: testgen for providers now requires the usage of test_flags for collection to work. Please visit http://cfme-tests.readthedocs.org/guides/documenting.html#documenting-tests for more details. """ metafunc.function = pytest.mark.uses_testgen()(metafunc.function) argnames = list(fields) argvalues = [] idlist = [] template_location = options.pop("template_location", None) if 'provider' in metafunc.fixturenames and 'provider' not in argnames: argnames.append('provider') for provider, data in cfme_data.get('management_systems', {}).iteritems(): # Check provider hasn't been filtered out with --use-provider if provider not in filtered: continue try: prov_obj = get_crud(provider) except UnknownProviderType: continue if not prov_obj: logger.debug("Whilst trying to create an object for %s we failed", provider) continue skip = False if provider_types is not None and prov_obj.type not in provider_types: # Skip unwanted types continue restricted_version = data.get('restricted_version', None) if restricted_version: logger.info('we found a restricted version') for op, comparator in _version_operator_map.items(): # split string by op; if the split works, version won't be empty head, op, ver = restricted_version.partition(op) if not ver: # This means that the operator was not found continue if not comparator(version.current_version(), ver): skip = True break else: raise Exception('Operator not found in {}'.format(restricted_version)) # Test to see the test has meta data, if it does and that metadata contains # a test_flag kwarg, then check to make sure the provider contains that test_flag # if not, do not collect the provider for this particular test. # Obtain the tests flags meta = getattr(metafunc.function, 'meta', None) test_flags = getattr(meta, 'kwargs', {}) \ .get('from_docs', {}).get('test_flag', '').split(',') if test_flags != ['']: test_flags = [flag.strip() for flag in test_flags] defined_flags = cfme_data.get('test_flags', '').split(',') defined_flags = [flag.strip() for flag in defined_flags] excluded_flags = data.get('excluded_test_flags', '').split(',') excluded_flags = [flag.strip() for flag in excluded_flags] allowed_flags = set(defined_flags) - set(excluded_flags) if set(test_flags) - allowed_flags: logger.info("Skipping Provider %s for test %s in module %s because " "it does not have the right flags, " "%s does not contain %s", provider, metafunc.function.func_name, metafunc.function.__module__, list(allowed_flags), list(set(test_flags) - allowed_flags)) continue try: if "since_version" in data: # Ignore providers that are not supported in this version yet if version.current_version() < data["since_version"]: continue except Exception: # No SSH connection continue # Get values for the requested fields, filling in with None for undefined fields data_values = {field: data.get(field, None) for field in fields} # Go through the values and handle the special 'data' name # report the undefined fields to the log for key in data_values.keys(): if data_values[key] is None: if 'require_fields' not in options: options['require_fields'] = True if options['require_fields']: skip = True logger.warning('Field "%s" not defined for provider "%s", skipping' % (key, provider) ) else: logger.debug('Field "%s" not defined for provider "%s", defaulting to None' % (key, provider) ) if skip: continue # Check the template presence if requested if template_location is not None: o = data try: for field in template_location: o = o[field] except (IndexError, KeyError): logger.info("Cannot apply %s to %s in the template specification, ignoring.", repr(field), repr(o)) else: if not isinstance(o, basestring): raise ValueError("{} is not a string! (for template)".format(repr(o))) templates = TEMPLATES.get(provider, None) if templates is not None: if o not in templates: logger.info( "Wanted template %s on %s but it is not there!\n", o, provider) # Skip collection of this one continue values = [] for arg in argnames: if arg == 'provider': metafunc.function = pytest.mark.provider_related()(metafunc.function) values.append(prov_obj) elif arg in data_values: values.append(data_values[arg]) # skip when required field is not present and option['require_field'] == True argvalues.append(values) # Use the provider name for idlist, helps with readable parametrized test output idlist.append(provider) return argnames, argvalues, idlist
def provider_by_type(metafunc, provider_types, *fields, **options): """Get the values of the named field keys from ``cfme_data.get('management_systems', {})`` Args: provider_types: A list of provider types to include. If None, all providers are considered *fields: Names of keys in an individual provider dict whose values will be returned when used as test function arguments **options: Explained below The ``**options`` available are defined below: * ``required_fields``: when fields passed are not present, skip them * ``choose_random``: choose a single provider from the list * ``template_location``: Specification where a required tempalte lies in the yaml, If not found in the provider, warning is printed and the test not collected. The spec is a tuple or list where each item is a key to the next field (str or int). The following test function arguments are special: ``provider_data`` the entire provider data dict from cfme_data. ``provider_key`` the provider's key in ``cfme_data.get('management_systems', {})`` ``provider_crud`` the provider's CRUD object, either a :py:class:`cfme.cloud.provider.Provider` or a :py:class:`cfme.infrastructure.provider.Provider` ``provider_mgmt`` the provider's backend manager, from :py:class:`utils.mgmt_system` Returns: An tuple of ``(argnames, argvalues, idlist)`` for use in a pytest_generate_tests hook, or with the :py:func:`parametrize` helper. Usage: # In the function itself def pytest_generate_tests(metafunc): argnames, argvalues, idlist = testgen.provider_by_type( ['openstack', 'ec2'], 'type', 'name', 'credentials', 'provider_data', 'hosts' ) metafunc.parametrize(argnames, argvalues, ids=idlist, scope='module') # Using the parametrize wrapper pytest_generate_tests = testgen.parametrize(testgen.provider_by_type, ['openstack', 'ec2'], 'type', 'name', 'credentials', 'provider_data', 'hosts', scope='module') Note: Using the default 'function' scope, each test will be run individually for each provider before moving on to the next test. To group all tests related to single provider together, parametrize tests in the 'module' scope. Note: testgen for providers now requires the usage of test_flags for collection to work. Please visit http://cfme-tests.readthedocs.org/guides/documenting.html#documenting-tests for more details. """ metafunc.function = pytest.mark.uses_testgen()(metafunc.function) argnames = list(fields) argvalues = [] idlist = [] template_location = options.pop("template_location", None) special_args = ('provider_key', 'provider_data', 'provider_crud', 'provider_mgmt', 'provider_type') # Hook on special attrs if requested for argname in special_args: if argname in metafunc.fixturenames and argname not in argnames: argnames.append(argname) for provider, data in cfme_data.get('management_systems', {}).iteritems(): skip = False prov_type = data['type'] if provider_types is not None and prov_type not in provider_types: # Skip unwanted types continue # Test to see the test has meta data, if it does and that metadata contains # a test_flag kwarg, then check to make sure the provider contains that test_flag # if not, do not collect the provider for this particular test. # Obtain the tests flags meta = getattr(metafunc.function, 'meta', None) test_flags = getattr(meta, 'kwargs', {}) \ .get('from_docs', {}).get('test_flag', '').split(',') if test_flags != ['']: test_flags = [flag.strip() for flag in test_flags] defined_flags = cfme_data.get('test_flags', '').split(',') defined_flags = [flag.strip() for flag in defined_flags] excluded_flags = data.get('excluded_test_flags', '').split(',') excluded_flags = [flag.strip() for flag in excluded_flags] allowed_flags = set(defined_flags) - set(excluded_flags) if set(test_flags) - allowed_flags: logger.info("Skipping Provider {} for test {} in module {} because " "it does not have the right flags, " "{} does not contain {}".format(provider, metafunc.function.func_name, metafunc.function.__module__, list(allowed_flags), list(set(test_flags) - allowed_flags))) continue try: if prov_type == "scvmm" and version.current_version() < "5.3": # Ignore SCVMM on 5.2 continue except Exception: # No SSH connection continue # Check provider hasn't been filtered out with --use-provider if provider not in filtered: continue # Use the provider name for idlist, helps with readable parametrized test output idlist.append(provider) # Get values for the requested fields, filling in with None for undefined fields data_values = {field: data.get(field, None) for field in fields} # Go through the values and handle the special 'data' name # report the undefined fields to the log for key in data_values.keys(): if data_values[key] is None: if 'require_fields' not in options: options['require_fields'] = True if options['require_fields']: skip = True try: idlist.remove(provider) except ValueError: pass logger.warning('Field "%s" not defined for provider "%s", skipping' % (key, provider) ) else: logger.debug('Field "%s" not defined for provider "%s", defaulting to None' % (key, provider) ) # Check the template presence if requested if template_location is not None: o = data try: for field in template_location: o = o[field] except (IndexError, KeyError): logger.info("Cannot apply {} to {} in the template specification, ignoring.".format( repr(field), repr(o))) else: if not isinstance(o, basestring): raise ValueError("{} is not a string! (for template)".format(repr(o))) templates = TEMPLATES.get(provider, None) if templates is not None: if o not in templates: logger.info( "Wanted template {} on {} but it is not there!\n".format(o, provider)) # Skip collection of this one continue if prov_type in cloud_provider_type_map: crud = get_cloud_provider(provider) elif prov_type in infra_provider_type_map: crud = get_infra_provider(provider) # else: wat? You deserve the NameError you're about to receive mgmt = provider_factory(provider) values = [] special_args_map = dict(zip(special_args, (provider, data, crud, mgmt, prov_type))) for arg in argnames: if arg in special_args_map: if arg == "provider_crud": metafunc.function = pytest.mark.provider_related()(metafunc.function) values.append(special_args_map[arg]) elif arg in data_values: values.append(data_values[arg]) # skip when required field is not present and option['require_field'] == True if not skip: argvalues.append(values) # pick a single provider if option['choose_random'] == True if 'choose_random' not in options: options['choose_random'] = False if idlist and options['choose_random']: single_index = idlist.index(random.choice(idlist)) new_idlist = ['random_provider'] new_argvalues = [argvalues[single_index]] logger.debug('Choosing random provider, "%s" selected, ' % (provider)) return argnames, new_argvalues, new_idlist return argnames, argvalues, idlist