def delete(self, from_dest='All'): """ Delete the catalog, starting from the destination provided by from_dest Throws cfme.DestinationNotFound exception :param from_dest: A valid navigation destination to start the delete from :return: none """ if from_dest in navigator.list_destinations(self): navigate_to(self, from_dest) else: msg = 'cfme.services.catalogs.catalog does not have destination {}'.format(from_dest) raise DestinationNotFound(msg) # Delete using the appropriate method if from_dest == 'All': # Select the row to delete, assuming default List View for All listview_table.select_row_by_cells({'Name': self.name, 'Description': self.description}) cfg_btn(version.pick({version.LOWEST: 'Remove Items from the VMDB', '5.7': 'Remove Catalog Items'}), invokes_alert=True) elif from_dest == 'Details': cfg_btn(version.pick({version.LOWEST: 'Remove Item from the VMDB', '5.7': 'Remove Catalog'}), invokes_alert=True) sel.handle_alert() flash.assert_success_message( 'Catalog "{}": Delete successful'.format(self.description or self.name))
def exists(root, sub=None, and_is_not_greyed=False): """ Checks presence and usability of toolbar buttons. By default it checks whether the button is available, not caring whether it is greyed or not. You can optionally enable check for greyedness. Args: root: Button name. sub: Item name (optional) and_is_not_greyed: Check if the button is available to click. """ sel.wait_for_ajax() if isinstance(root, dict): root = version.pick(root) if isinstance(sub, dict): sub = version.pick(sub) try: greyed = is_greyed(root, sub) if and_is_not_greyed: return not greyed else: return True except sel.NoSuchElementException: return False
def verify_retirement_date(test_vm, expected_date='Never'): """Verify the retirement date for a variety of situations Args: expected_date: a :py:class: `str` or :py:class: `parsetime` date or a dict of :py:class: `parsetime` dates with 'start' and 'end' keys. """ if isinstance(expected_date, dict): # convert to a parsetime object for comparsion, function depends on version if 'UTC' in pick(VM.RETIRE_DATE_FMT): convert_func = parsetime.from_american_minutes_with_utc else: convert_func = parsetime.from_american_date_only expected_date.update({'retire': convert_func(test_vm.retirement_date)}) logger.info('Asserting retire date "%s" is between "%s" and "%s"', # noqa expected_date['retire'], expected_date['start'], expected_date['end']) assert expected_date['start'] <= expected_date['retire'] <= expected_date['end'] elif isinstance(expected_date, (parsetime, datetime, date)): assert test_vm.retirement_date == expected_date.strftime(pick(VM.RETIRE_DATE_FMT)) else: assert test_vm.retirement_date == expected_date
def test_vm_retire_extend(request, testing_vm, soft_assert, retire_extend_button): """ Tests extending a retirement using an AE method. Prerequisities: * A running VM on any provider. Steps: * It creates a button pointing to ``Request/vm_retire_extend`` instance. The button should live in the VM and Instance button group. * Then it sets a retirement date for the VM * Then it waits until the retirement date is set * Then it clicks the button that was created and it waits for the retirement date to extend. Metadata: test_flag: retire, provision """ num_days = 5 soft_assert(testing_vm.retirement_date == 'Never', "The retirement date is not 'Never'!") retirement_date = generate_retirement_date(delta=num_days) testing_vm.set_retirement_date(retirement_date) wait_for(lambda: testing_vm.retirement_date != 'Never', message="retirement date set") set_date = testing_vm.retirement_date if not BZ(1419150, forced_streams='5.6').blocks: soft_assert(set_date == retirement_date.strftime(pick(VM.RETIRE_DATE_FMT)), "The retirement date '{}' did not match expected date '{}'" .format(set_date, retirement_date.strftime(pick(VM.RETIRE_DATE_FMT)))) # current_retirement_date = testing_vm.retirement_date # Now run the extend stuff retire_extend_button()
def delete(self, cancel=False, wait_deleted=True, force=False): """Deletes the manager through UI Args: cancel (bool): Whether to cancel out of the deletion, when the alert pops up. wait_deleted (bool): Whether we want to wait for the manager to disappear from the UI. True will wait; False will only delete it and move on. force (bool): Whether to try to delete the manager even though it doesn't exist. True will try to delete it anyway; False will check for its existence and leave, if not present. """ if not force and not self.exists: return navigate_to(self, 'All') sel.check(Quadicon(self.quad_name, None).checkbox()) item_text = version.pick({'5.6': 'Remove selected items from the VMDB', '5.7': 'Remove selected items'}) cfg_btn(item_text, invokes_alert=True) sel.handle_alert(cancel) if not cancel: flash_msg = version.pick({'5.6': 'Delete initiated for 1 provider', '5.7': 'Delete initiated for 1 Provider'}) flash.assert_message_match(flash_msg) if wait_deleted: wait_for(func=lambda: self.exists, fail_condition=True, delay=15, num_sec=60)
def report_vms(setup_first_provider): report = CustomReport( menu_name=generate_random_string(), title=generate_random_string(), base_report_on="Virtual Machines", report_fields=[ version.pick({ version.LOWEST: "Provider : Name", "5.3": "Cloud/Infrastructure Provider : Name", }), "Cluster : Name", "Datastore : Name", "Hardware : Number of CPUs", "Hardware : RAM", "Host : Name", "Name", ] ) report.create() report.queue(wait_for_finish=True) yield pick( filter( lambda i: len(i[ version.pick({ version.LOWEST: "Provider : Name", "5.3": "Cloud/Infrastructure Provider Name", }) ].strip()) > 0, list(report.get_saved_reports()[0].data.rows)), 2) report.delete()
def view_value_mapping(self): return {'hostname': self.hostname, 'api_port': getattr(self, 'api_port', None), 'verify_tls': version.pick({version.LOWEST: None, '5.8': getattr(self, 'verify_tls', None)}), 'ca_certs': version.pick({version.LOWEST: None, '5.8': getattr(self, 'ca_certs', None)}) }
def nav_edit(self): dp_length = version.pick({version.LOWEST: 1, '5.3': 2}) if len(self.nav_path) > dp_length: cfg_btn('Edit Selected Item') else: cfg_btn(version.pick({version.LOWEST: 'Edit Selected Namespaces', '5.3': 'Edit Selected Namespace'}))
def __init__( self, name=None, credentials=None, key=None, zone=None, provider_data=None): if not credentials: credentials = {} self.name = name self.credentials = credentials self.key = key self.provider_data = provider_data self.zone = zone self.vm_name = version.pick({version.LOWEST: "VMs", '5.5': "VMs and Instances"}) self.template_name = version.pick( {version.LOWEST: "Templates", '5.5': "VM Templates and Images"})
def old_select(root, sub=None, invokes_alert=False): """ Clicks on a button by calling the dhtmlx toolbar callEvent. Args: root: The root button's name as a string. sub: The sub button's name as a string. (optional) invokes_alert: If ``True``, then the behaviour is little bit different. After the last click, no ajax wait and no move away is done to be able to operate the alert that appears after click afterwards. Defaults to ``False``. Returns: ``True`` if everything went smoothly Raises: :py:class:`cfme.exceptions.ToolbarOptionGreyedOrUnavailable` """ # wait for ajax on select to prevent pickup up a toolbar button in the middle of a page change sel.wait_for_ajax() if isinstance(root, dict): root = version.pick(root) if sub is not None and isinstance(sub, dict): sub = version.pick(sub) root_obj = version.pick({'5.4': 'miq_toolbars', '5.5.0.7': 'ManageIQ.toolbars'}) if sub: search = sub_loc(sub) else: search = root_loc(root) eles = sel.elements(search) for ele in eles: idd = sel.get_attribute(ele, 'idd') if idd: break else: raise ToolbarOptionGreyedOrUnavailable( "Toolbar button {}/{} is greyed or unavailable!".format(root, sub)) buttons = sel.execute_script('return {}'.format(root_obj)) tb_name = None for tb_key, tb_obj in buttons.iteritems(): for btn_key, btn_obj in tb_obj['buttons'].iteritems(): if btn_obj['name'] == idd: tb_name = tb_key if not tb_name: raise ToolbarOptionGreyedOrUnavailable( "Toolbar button {}/{} is greyed or unavailable!".format(root, sub)) sel.execute_script( "{}['{}']['obj'].callEvent('onClick', ['{}'])".format(root_obj, tb_name, idd)) if not invokes_alert: sel.wait_for_ajax() return True
def __getattr__(self, attr): """Resulve the button clicking action.""" try: a_tuple = self.buttons[attr] except KeyError: raise AttributeError("Action {} does not exist".format(attr)) action = version.pick(dict(zip(self.versions, self.actions))) action_meth = getattr(self, action) action_data = version.pick(dict(zip(self.versions, a_tuple))) def _click_function(): action_meth(action_data) return _click_function
def delete(self, cancel=False): sel.force_navigate("automate_explorer_table_select", context={'tree_item': self.parent, 'table_item': self}) dp_length = version.pick({version.LOWEST: 1, '5.3': 2}) if len(self.path) > dp_length: cfg_btn('Remove selected Items', invokes_alert=True) else: cfg_btn('Remove Namespaces', invokes_alert=True) sel.handle_alert(cancel) del_msg = version.pick({ version.LOWEST: 'The selected Automate Namespaces were deleted', '5.3': 'Automate Namespace "{}": Delete successful'.format(self.description) }) flash.assert_success_message(del_msg)
def test_discovery_cancelled_validation(): """ Tests that the flash message is correct when discovery is cancelled.""" discover(None, cancel=True, d_type="Amazon") msg = version.pick( {version.LOWEST: 'Amazon Cloud Providers Discovery was cancelled by the user', '5.5': 'Cloud Providers Discovery was cancelled by the user'}) flash.assert_message_match(msg)
def test_services_properties_rel(provider, test_obj): rows = navigate_and_get_rows(provider, test_obj.obj, test_obj.list_tbl, 2) if not rows: pytest.skip('No records found for {}s. Skipping...'.format(test_obj.obj.__name__)) names = [r[2].text for r in rows] if test_obj.obj is Container: args = [(r.pod_name.text, ) for r in rows] elif test_obj.obj is Image: args = [(r.tag.text, provider) for r in rows] else: args = [(provider, ) for _ in rows] errors = [] for name, arg in zip(names, args): instance = test_obj.obj(name, *arg) if isinstance(test_obj.expected_fields, dict): expected_fields = version.pick(test_obj.expected_fields) else: expected_fields = test_obj.expected_fields for field in expected_fields: try: soft_get(instance.summary.properties, field) except AttributeError: errors.append('{} "{}" properties table has missing field - "{}"' .format(test_obj.obj.__name__, name, field)) if errors: raise Exception('\n'.join(errors))
def _scan_ui(vm): logger.info('Initiating vm smart scan on ' + vm.provider.name + ":" + vm.name) vm.smartstate_scan(cancel=False, from_details=True) flash.assert_message_contain(version.pick({ version.LOWEST: "Smart State Analysis initiated", "5.5": "Analysis initiated for 1 VM and Instance from the CFME Database"})) # wait for task to complete pytest.sel.force_navigate('tasks_my_vm') wait_for(is_vm_analysis_finished, [vm.name], delay=15, num_sec=600, handle_exception=True, fail_func=lambda: toolbar.select('Reload')) # make sure fleecing was successful if version.current_version() >= "5.4": task_row = tasks.tasks_table.find_row_by_cells({ 'task_name': "Scan from Vm %s" % vm.name, 'state': 'finished' }) else: task_row = tasks.tasks_table.find_row_by_cells({ 'task_name': "Scan from Vm %s" % vm.name, 'state': 'Finished' }) icon_img = task_row.columns[1].find_element_by_tag_name("img") assert "checkmark" in icon_img.get_attribute("src")
def pytest_generate_tests(metafunc): verpicked_prov_types = version.pick(PROVIDER_TYPES) new_idlist = [] new_argvalues = [] argnames, argvalues, idlist = testgen.provider_by_type( metafunc, verpicked_prov_types, 'datastores') argnames += ['datastore_type', 'datastore_name'] for i, argvalue_tuple in enumerate(argvalues): args = dict(zip(argnames, argvalue_tuple)) if not args['datastores']: continue for ds in args['datastores']: if not ds.get('test_fleece', False): continue assert ds.get('type', None) in DATASTORE_TYPES,\ 'datastore type must be set to [{}] for smartstate analysis tests'\ .format('|'.join(DATASTORE_TYPES)) argvs = argvalues[i][:] argvs.pop(argnames.index('datastores')) new_argvalues.append(argvs + [ds['type'], ds['name']]) test_id = '{}-{}-{}'.format(args['provider'].key, ds['type'], ds['name']) new_idlist.append(test_id) argnames.remove('datastores') metafunc.parametrize(argnames, new_argvalues, ids=new_idlist, scope="module")
def default(cls): if not hasattr(cls, "_default_domain"): cls._default_domain = version.pick({ version.LOWEST: None, '5.3': cls('Default') }) return cls._default_domain
def __init__(self, path_to_report, datetime, candu=False, appliance=None): Navigatable.__init__(self, appliance=appliance) self.path = path_to_report self.datetime = datetime self.candu = candu self.datetime_in_tree = version.pick({"5.6": self.datetime, "5.7": parsetime.from_american_with_utc(self.datetime).to_iso_with_utc()})
def _install_coverage_hook(self): # Clean appliance coverage dir self.ipapp.ssh_client.run_command('rm -rf {}'.format( appliance_coverage_root.strpath)) # Decide which coverage hook file to use based on version coverage_hook = version.pick({ version.LOWEST: coverage_hook_lowest, '5.5': coverage_hook_55 }) # Put the coverage hook in the miq lib path self.ipapp.ssh_client.put_file(coverage_hook.strpath, rails_root.join( '..', 'lib', coverage_hook_out_fn).strpath) replacements = { 'require': r"require 'coverage_hook'", 'config': rails_root.join('config').strpath } # grep/echo to try to add the require line only once # This goes in preinitializer after the miq lib path is set up, # which makes it so ruby can actually require the hook command_template = ( 'cd {config};' 'grep -q "{require}" preinitializer.rb || echo -e "\\n{require}" >> preinitializer.rb' ) x, out = self.ipapp.ssh_client.run_command(command_template.format(**replacements)) return x == 0
def _get_state(): navigate_to(cls, 'Saved') row = records_table.find_row("queued_at", queued_at) status = sel.text(row.status).strip().lower() assert status != "error", sel.text(row) return status == version.pick({"5.6": "finished", "5.7": "complete"})
def paged_table(self): _paged_table_template = '//div[@id="list_grid"]/div[@class="{}"]/table/tbody' return version.pick({ version.LOWEST: SplitPagedTable(header_data=(_paged_table_template.format("xhdr"), 1), body_data=(_paged_table_template.format("objbox"), 0)), "5.5": PagedTable('//table'), })
def catalog_item(provider, provisioning, vm_name, dialog, catalog): template, host, datastore, iso_file, catalog_item_type = map( provisioning.get, ("template", "host", "datastore", "iso_file", "catalog_item_type") ) provisioning_data = {"vm_name": vm_name, "host_name": {"name": [host]}, "datastore_name": {"name": [datastore]}} if provider.type == "rhevm": provisioning_data["provision_type"] = "Native Clone" provisioning_data["vlan"] = provisioning["vlan"] catalog_item_type = version.pick({version.LATEST: "RHEV", "5.3": "RHEV", "5.2": "Redhat"}) elif provider.type == "virtualcenter": provisioning_data["provision_type"] = "VMware" item_name = fauxfactory.gen_alphanumeric() catalog_item = CatalogItem( item_type=catalog_item_type, name=item_name, description="my catalog", display_in=True, catalog=catalog, dialog=dialog, catalog_name=template, provider=provider.name, prov_data=provisioning_data, ) return catalog_item
def test_providers_summary(soft_assert, setup_a_provider): """Checks some informations about the provider. Does not check memory/frequency as there is presence of units and rounding.""" path = ["Configuration Management", "Providers", "Providers Summary"] report = CannedSavedReport.new(path) for provider in report.data.rows: if any(ptype in provider["MS Type"] for ptype in {"ec2", "openstack"}): # Skip cloud continue provider_fake_obj = Provider(name=provider["Name"]) sel.force_navigate("infrastructure_provider", context={"provider": provider_fake_obj}) hostname = version.pick({ version.LOWEST: ("Hostname", "Hostname"), "5.5": ("Host Name", "Hostname")}) soft_assert( provider_props(hostname[0]) == provider[hostname[1]], "Hostname does not match at {}".format(provider["Name"])) if version.current_version() < "5.4": # In 5.4, hostname and IP address are shared under Hostname (above) soft_assert( provider_props("IP Address") == provider["IP Address"], "IP Address does not match at {}".format(provider["Name"])) soft_assert( provider_props("Aggregate Host CPU Cores") == provider["Total Number of Logical CPUs"], "Logical CPU count does not match at {}".format(provider["Name"])) soft_assert( provider_props("Aggregate Host CPUs") == provider["Total Number of Physical CPUs"], "Physical CPU count does not match at {}".format(provider["Name"]))
def test_permission_edit(request, product_features, action): """ Ensures that changes in permissions are enforced on next login """ product_features = version.pick(product_features) request.addfinalizer(login.login_admin) role_name = fauxfactory.gen_alphanumeric() role = ac.Role( name=role_name, vm_restriction=None, product_features=[(["Everything"], False)] + [(k, True) for k in product_features], # role_features ) role.create() group = new_group(role=role.name) group.create() user = new_user(group=group) user.create() with user: try: action() except Exception: pytest.fail("Incorrect permissions set") login.login_admin() role.update({"product_features": [(["Everything"], True)] + [(k, False) for k in product_features]}) with user: try: with error.expected(Exception): action() except error.UnexpectedSuccessException: pytest.Fails("Permissions have not been updated")
def test_evmserverd_stop(appliance): """Tests whether stopping the evmserverd really stops the CFME server processes. Steps: * Remember all server names from ``service evmserverd status`` command. * Or the bin/rake evm:status on 5.5+ since the systemd status does not show that, this applies also for next references to status. * Issue a ``service evmserverd stop`` command. * Periodically check output of ``service evmserverd status`` that all servers are stopped. * For 5.5+: Really call ``service evmserverd status`` and check that the mentions of stopping the service are present. """ server_name_key = version.pick({ version.LOWEST: 'Server Name', '5.8': 'Server' }) server_names = {server[server_name_key] for server in appliance.ssh_client.status["servers"]} assert appliance.ssh_client.run_command("systemctl stop evmserverd").rc == 0 @wait_for_decorator(timeout="2m", delay=5) def servers_stopped(): status = { server[server_name_key]: server for server in appliance.ssh_client.status["servers"] } for server_name in server_names: if status[server_name]["Status"] != "stopped": return False return True if version.current_version() >= "5.5": status = appliance.ssh_client.run_command("systemctl status evmserverd") assert "Stopped EVM server daemon" in status.output assert "code=exited" in status.output
def catalog_item(provider_crud, provider_type, provisioning, vm_name, dialog, catalog): item_name = fauxfactory.gen_alphanumeric() template, host, datastore, iso_file, catalog_item_type = map(provisioning.get, ('template', 'host', 'datastore', 'iso_file', 'catalog_item_type')) provisioning_data = { 'vm_name': vm_name, 'host_name': {'name': [host]}, 'datastore_name': {'name': [datastore]} } if provider_type == 'rhevm': provisioning_data['provision_type'] = 'Native Clone' provisioning_data['vlan'] = provisioning['vlan'] catalog_item_type = version.pick({ version.LATEST: "RHEV", '5.3': "RHEV", '5.2': "Redhat" }) elif provider_type == 'virtualcenter': provisioning_data['provision_type'] = 'VMware' catalog_item = CatalogItem(item_type=catalog_item_type, name=item_name, description="my catalog", display_in=True, catalog=catalog, dialog=dialog, catalog_name=template, provider=provider_crud.name, prov_data=provisioning_data) yield catalog_item
def test_certificates_present(ssh_client, soft_assert): """Test whether the required product certificates are present. This test is parametrized with the given file and its MD5 hash. If the given MD5 hash is ``None``, it won't be checked. From wiki: `Ships with /etc/pki/product/<id>.pem where RHEL is "69" and CF is "167"` """ filenames_md5s = version.pick({ version.LOWEST: [ ("/etc/pki/product/69.pem", None), ("/etc/pki/product/167.pem", None) ], '5.3': [ ("/etc/pki/product/69.pem", None), ("/etc/pki/product/167.pem", None), ("/etc/pki/product/201.pem", None) ], '5.4.2': [ ("/etc/pki/product-default/69.pem", '0f7e6e9343c2b7fe1162f06dd92c93c3'), ("/etc/pki/product/167.pem", '1a67ad5013806cad9d839180b6564e00'), ("/etc/pki/product/201.pem", '0a2739f9ad6f4f5288379295004a1d7d') ] }) for filename, given_md5 in filenames_md5s: file_exists = ssh_client.run_command("test -f '%s'" % filename)[0] == 0 soft_assert(file_exists, "File %s does not exist!" % filename) if given_md5: md5_of_file = ssh_client.run_command("md5sum '%s'" % filename)[1].strip() # Format `abcdef0123456789<whitespace>filename md5_of_file = re.split(r"\s+", md5_of_file, 1)[0] soft_assert(given_md5 == md5_of_file, "md5 of file %s differs" % filename)
def _provisioner(template, provisioning_data, delayed=None): pytest.sel.force_navigate('infrastructure_provision_vms', context={ 'provider': provider, 'template_name': template, }) vm_name = provisioning_data["vm_name"] fill(provisioning_form, provisioning_data, action=provisioning_form.submit_button) flash.assert_no_errors() request.addfinalizer(lambda: cleanup_vm(vm_name, provider)) if delayed is not None: total_seconds = (delayed - datetime.utcnow()).total_seconds() row_description = 'Provision from [%s] to [%s]' % (template, vm_name) cells = {'Description': row_description} try: row, __ = wait_for(requests.wait_for_request, [cells], fail_func=requests.reload, num_sec=total_seconds, delay=5) pytest.fail("The provisioning was not postponed") except TimedOutError: pass logger.info('Waiting for vm %s to appear on provider %s', vm_name, provider.key) wait_for(provider.mgmt.does_vm_exist, [vm_name], handle_exception=True, num_sec=600) # nav to requests page happens on successful provision logger.info('Waiting for cfme provision request for vm %s' % vm_name) row_description = 'Provision from [%s] to [%s]' % (template, vm_name) cells = {'Description': row_description} row, __ = wait_for(requests.wait_for_request, [cells], fail_func=requests.reload, num_sec=900, delay=20) assert row.last_message.text == version.pick( {version.LOWEST: 'VM Provisioned Successfully', "5.3": 'Vm Provisioned Successfully', }) return VM.factory(vm_name, provider)
def is_analysis_finished(name, task_type='vm', clear_tasks_after_success=True): """ Check if analysis is finished - if not, reload page""" tabs_data = { 'vm': { 'tab': 'All VM Analysis Tasks', 'page': 'tasks_all_vm', 'task': 'Scan from Vm {}', 'state': 'finished' }, 'host': { 'tab': 'My Other UI Tasks', 'page': 'tasks_my_other_ui', 'task': pick({ LOWEST: "SmartState Analysis for {}", "5.5": "SmartState Analysis for '{}'", }), 'state': 'Finished' }, 'datastore': { 'tab': 'My Other UI Tasks', 'page': 'tasks_my_other_ui', 'task': 'SmartState Analysis for [{}]', 'state': "Finished"} }[task_type] return is_task_finished(tab=tabs_data['tab'], page=tabs_data['page'], task_name=tabs_data['task'].format(name), expected_status=tabs_data['state'], clear_tasks_after_success=clear_tasks_after_success)
def scl_name(): # postgres's version is in the service name and file paths when we pull it from SCL, # so this is a little resolver to help keep the version picking centralized return version.pick({ version.LOWEST: 'postgresql92', '5.5': 'rh-postgresql94' })
def service_data(request, rest_api, a_provider, service_dialog=None, service_catalog=None): """ The attempt to add the service entities via web """ if not service_dialog: service_dialog = dialog() if not service_catalog: service_catalog = service_catalog_obj(request, rest_api) template, host, datastore, vlan, catalog_item_type = map( a_provider.data.get('provisioning').get, ('template', 'host', 'datastore', 'vlan', 'catalog_item_type')) provisioning_data = { 'vm_name': 'test_rest_{}'.format(fauxfactory.gen_alphanumeric()), 'host_name': { 'name': [host] }, 'datastore_name': { 'name': [datastore] } } if a_provider.type == 'rhevm': provisioning_data['provision_type'] = 'Native Clone' provisioning_data['vlan'] = vlan catalog_item_type = 'RHEV' elif a_provider.type == 'virtualcenter': provisioning_data['provision_type'] = 'VMware' provisioning_data['vlan'] = vlan vm_name = version.pick({ version.LOWEST: provisioning_data['vm_name'] + '_0001', '5.7': provisioning_data['vm_name'] + '0001' }) item_name = fauxfactory.gen_alphanumeric() catalog_item = CatalogItem(item_type=catalog_item_type, name=item_name, description='my catalog', display_in=True, catalog=service_catalog, dialog=service_dialog, catalog_name=template, provider=a_provider, prov_data=provisioning_data) catalog_item.create() service_catalogs = ServiceCatalogs(catalog_item.catalog, catalog_item.name) service_catalogs.order() row_description = catalog_item.name cells = {'Description': row_description} row, _ = wait_for(requests.wait_for_request, [cells, True], fail_func=requests.reload, num_sec=2000, delay=60) assert row.request_state.text == 'Finished' assert row.status.text != 'Error', "Provisioning failed with the message `{}`".format( row.last_message.text) # on 5.8 the service name visible via REST API is in form <assigned_name>-DATE-TIMESTAMP # (i.e. 2ojnKgZRCJ-20170410-113646) for services created using UI rest_service = rest_api.collections.services.get( name='{}%'.format(catalog_item.name)) @request.addfinalizer def _finished(): try: a_provider.mgmt.delete_vm(vm_name) except Exception: # vm can be deleted/retired by test logger.warning("Failed to delete vm '{}'.".format(vm_name)) try: rest_api.collections.services.get( name=rest_service.name).action.delete() except ValueError: # service can be deleted by test logger.warning("Failed to delete service '{}'.".format( rest_service.name)) return {'service_name': rest_service.name, 'vm_name': vm_name}
def config_option(): return version.pick({version.LOWEST: 'Edit Selected Hosts', '5.4': 'Edit Selected items'})
def run_command(self, command, timeout=RUNCMD_TIMEOUT, reraise=False, ensure_host=False, ensure_user=False): """Run a command over SSH. Args: command: The command. Supports taking dicts as version picking. timeout: Timeout after which the command execution fails. reraise: Does not muffle the paramiko exceptions in the log. ensure_host: Ensure that the command is run on the machine with the IP given, not any container or such that we might be using by default. ensure_user: Ensure that the command is run as the user we logged in, so in case we are not root, setting this to True will prevent from running sudo. Returns: A :py:class:`SSHResult` instance. """ if isinstance(command, dict): command = version.pick(command) original_command = command uses_sudo = False logger.info("Running command %r", command) if self.is_pod and not ensure_host: # This command will be executed in the context of the host provider command = 'oc rsh {} bash -c {}'.format( self._container, quote('source /etc/default/evm; ' + command)) ensure_host = True elif self.is_container and not ensure_host: command = 'docker exec {} bash -c {}'.format( self._container, quote('source /etc/default/evm; ' + command)) if self.username != 'root' and not ensure_user: # We need sudo command = 'sudo -i bash -c {command}'.format( command=quote(command)) uses_sudo = True if command != original_command: logger.info("> Actually running command %r", command) command += '\n' output = [] try: session = self.get_transport().open_session() if uses_sudo: # We need a pseudo-tty for sudo session.get_pty() if timeout: session.settimeout(float(timeout)) session.exec_command(command) stdout = session.makefile() stderr = session.makefile_stderr() while True: if session.recv_ready: for line in stdout: output.append(line) if self._streaming: self.f_stdout.write(line) if session.recv_stderr_ready: for line in stderr: output.append(line) if self._streaming: self.f_stderr.write(line) if session.exit_status_ready(): break exit_status = session.recv_exit_status() return SSHResult(exit_status, ''.join(output)) except paramiko.SSHException: if reraise: raise else: logger.exception('Exception happened during SSH call') except socket.timeout: logger.exception( "Command %r timed out. Output before it failed was:\n%r", command, ''.join(output)) raise # Returning two things so tuple unpacking the return works even if the ssh client fails # Return whatever we have in the output return SSHResult(1, ''.join(output))
def service_data(request, rest_api, a_provider, dialog, service_catalogs): """ The attempt to add the service entities via web """ template, host, datastore, vlan, catalog_item_type = map( a_provider.data.get('provisioning').get, ('template', 'host', 'datastore', 'vlan', 'catalog_item_type')) provisioning_data = { 'vm_name': 'test_rest_{}'.format(fauxfactory.gen_alphanumeric()), 'host_name': { 'name': [host] }, 'datastore_name': { 'name': [datastore] } } if a_provider.type == 'rhevm': provisioning_data['provision_type'] = 'Native Clone' provisioning_data['vlan'] = vlan catalog_item_type = 'RHEV' elif a_provider.type == 'virtualcenter': provisioning_data['provision_type'] = 'VMware' provisioning_data['vlan'] = vlan vm_name = version.pick({ version.LOWEST: provisioning_data['vm_name'] + '_0001', '5.7': provisioning_data['vm_name'] + '0001' }) catalog = service_catalogs[0].name item_name = fauxfactory.gen_alphanumeric() catalog_item = CatalogItem(item_type=catalog_item_type, name=item_name, description='my catalog', display_in=True, catalog=catalog, dialog=dialog.label, catalog_name=template, provider=a_provider, prov_data=provisioning_data) catalog_item.create() service_catalogs = ServiceCatalogs(catalog_item.name) service_catalogs.order() row_description = catalog_item.name cells = {'Description': row_description} row, _ = wait_for(requests.wait_for_request, [cells, True], fail_func=requests.reload, num_sec=2000, delay=60) assert row.request_state.text == 'Finished' @request.addfinalizer def _finished(): try: a_provider.mgmt.delete_vm(vm_name) except Exception: # vm can be deleted/retired by test logger.warning("Failed to delete vm '{}'.".format(vm_name)) try: rest_api.collections.services.get( name=catalog_item.name).action.delete() except ValueError: # service can be deleted by test logger.warning("Failed to delete service '{}'.".format( catalog_item.name)) return {'service_name': catalog_item.name, 'vm_name': vm_name}
from functools import partial from cfme.web_ui import toolbar as tb from cfme import web_ui as ui from xml.sax.saxutils import quoteattr from cfme.exceptions import CFMEException from utils.wait import wait_for from utils import version details_page = Region(infoblock_type='detail') cfg_btn = partial(tb.select, "Configuration") pol_btn = partial(tb.select, 'Policy') lifecycle_btn = partial(tb.select, 'Lifecycle') output_table = lambda: version.pick({ '5.5': Table('//div[@id="list_grid"]/table'), '5.4': SplitTable( ('//*[@id="list_grid"]//table[contains(@class, "hdr")]/tbody', 1), ('//*[@id="list_grid"]//table[contains(@class, "obj")]/tbody', 1)) }) edit_tags_form = Form(fields=[( "select_tag", ui.Select("select#tag_cat")), ("select_value", ui.Select("select#tag_add"))]) nav.add_branch('clouds_stacks', { 'clouds_stack': lambda ctx: sel.click(Quadicon(ctx['stack'].name, 'stack')) })
def step(self): cfg_btn(version.pick({ version.LOWEST: 'Add a New Containers Provider', '5.7': 'Add Existing Containers Provider' }))
def minimise_dict(item): if isinstance(item, dict): return version.pick({str(k): v for k, v in item.iteritems()}) else: return item
def test_rh_registration(request, unset_org_id, reg_method, reg_data, proxy_url, proxy_creds): if reg_method in ('rhsm', 'sat6'): repo_or_channel = reg_data.get('enable_repo', None) else: repo_or_channel = reg_data.get('add_channel', None) if not repo_or_channel: set_default_repo = True else: set_default_repo = False if proxy_url: use_proxy = True proxy_username = proxy_creds['username'] proxy_password = proxy_creds['password'] else: use_proxy = False proxy_url = None proxy_username = None proxy_password = None red_hat_updates.update_registration( service=reg_method, url=reg_data['url'], username=conf.credentials[reg_method]['username'], password=conf.credentials[reg_method]['password'], repo_name=repo_or_channel, organization=reg_data.get('organization', None), use_proxy=use_proxy, proxy_url=proxy_url, proxy_username=proxy_username, proxy_password=proxy_password, set_default_repository=set_default_repo, # Satellite 6 registration requires validation to be able to choose organization validate=False if reg_method != 'sat6' else True) used_repo_or_channel = InfoBlock( 'Red Hat Software Updates', version.pick({ version.LOWEST: 'Update Repository', "5.4": 'Channel Name(s)' if reg_method == 'sat5' else 'Repository Name(s)' })).text red_hat_updates.register_appliances() # Register all if reg_method == 'rhsm': request.addfinalizer(rhsm_unregister) elif reg_method == 'sat5': request.addfinalizer(sat5_unregister) else: request.addfinalizer(sat6_unregister) wait_for(func=is_registration_complete, func_args=[used_repo_or_channel], delay=40, num_sec=400, fail_func=red_hat_updates.register_appliances)
def _d(l, **kwargs): """Resolve version-specific locators.""" return elements(version.pick(l), **kwargs)
def vm_name(self): return version.pick({ version.LOWEST: "VMs and Instances", '5.7.1': "Virtual Machines" })
list_table = SplitTable( header_data=("//div[@id='list_grid']/div[@class='xhdr']/table/tbody", 1), body_data=("//div[@id='list_grid']/div[@class='objbox']/table/tbody", 1), ) add_manager_btn = form_buttons.FormButton('Add') edit_manager_btn = form_buttons.FormButton('Save changes') cfg_btn = partial(tb.select, 'Configuration') nav.add_branch( 'infrastructure_config_management', { 'infrastructure_config_managers': [ lambda _: (accordion.tree( 'Providers', version.pick({ version.LOWEST: 'All Red Hat Satellite Providers', version.UPSTREAM: 'All Foreman Providers' })), tb.select('Grid View')), { 'infrastructure_config_manager_new': lambda _: cfg_btn('Add a new Provider'), 'infrastructure_config_manager': [ lambda ctx: sel.check( Quadicon( '{} Configuration Manager'. format(ctx['manager'].name), None).checkbox), { 'infrastructure_config_manager_edit': lambda _: cfg_btn('Edit Selected item'), 'infrastructure_config_manager_refresh': lambda _: cfg_btn( 'Refresh Relationships and Power states', invokes_alert=True),
def none(self): if self._none: return version.pick(self._none) else: return None
"//th[normalize-space(.)='Timestamp']/ancestor::table[1]" }) host_add_btn = FormButton('Add this Host') forced_saved = FormButton("Save Changes", dimmed_alt="Save", force_click=True) cfg_btn = partial(tb.select, 'Configuration') pol_btn = partial(tb.select, 'Policy') pow_btn = partial(tb.select, 'Power') lif_btn = partial(tb.select, 'Lifecycle') nav.add_branch( 'infrastructure_hosts', { 'infrastructure_host_new': lambda _: cfg_btn( version.pick({ version.LOWEST: 'Add a New Host', '5.4': 'Add a New item' })), 'infrastructure_host_discover': lambda _: cfg_btn('Discover Hosts'), 'infrastructure_host': [ lambda ctx: sel.click(Quadicon(ctx['host'].name, 'host')), { 'infrastructure_host_edit': lambda _: cfg_btn( version.pick({ version.LOWEST: 'Edit this Host', '5.4': 'Edit this item' })), 'infrastructure_host_policy_assignment': lambda _: pol_btn('Manage Policies'), 'infrastructure_provision_host': lambda _: lif_btn(
testing. name=None will generate a random name ''' name = name or random.generate_random_string() return lambda: ac.Role(name=name, vm_restriction=vm_restriction, product_features=product_features) def _go_to(dest): '''Create a thunk that navigates to the given destination''' return lambda: nav.go_to(dest) cat_name = version.pick({ "default": "Settings & Operations", "5.3": "Configure" }) @pytest.mark.parametrize( 'role,allowed_actions,disallowed_actions', [ [ _mk_role(product_features=[ [['Everything'], False], # minimal permission [[cat_name, 'Tasks'], True] ]), { 'tasks': lambda: sel.click(tasks.buttons.default) }, # can only access one thing {
"""A set of functions for dealing with the paginator controls.""" from cfme.web_ui import Select, Input, AngularSelect import cfme.fixtures.pytest_selenium as sel import re from selenium.common.exceptions import NoSuchElementException from functools import partial from utils import version from cfme.exceptions import PaginatorException _locator = lambda: version.pick({ version.LOWEST: '(//div[@id="paging_div"]//div[@id="pc_div_1"])', '5.5': '(//div[@id="paging_div"]//div[@id="rpb_div_1" or @id="pc_div_1"])' }) _next = '//img[@alt="Next"]|//li[contains(@class, "next")]/span' _previous = '//img[@alt="Previous"]|//li[contains(@class, "prev")]/span' _first = '//img[@alt="First"]|//li[contains(@class, "first")]/span' _last = '//img[@alt="Last"]|//li[contains(@class, "last")]/span' _num_results = '//select[@id="ppsetting" or @id="perpage_setting1"]' _sort_by = '//select[@id="sort_choice"]' _page_cell = '//td//td[contains(., " of ")]|//li//span[contains(., " of ")]' _check_all = Input("masterToggle") _prefix = r"(?:Items?|Rows?|Showing)?\s*" _regexp = r"{}(?P<first>\d+)-?(?P<last>\d+)? of (?P<total>\d+)\s*(?:items?)?".format( _prefix) def page_controls_exist(): """ Simple check to see if page controls exist. """
def select_from_row(self, row): el = pick({"5.6": "./td/select", "5.7": "./td/div/select"}) return Select_old(sel.element(el, root=row))
def _locator(): return version.pick({version.LOWEST: '(//div[@id="paging_div"]//div[@id="pc_div_1"])', '5.5': '(//div[@id="paging_div"]//div[@id="rpb_div_1" or @id="pc_div_1"])'})
details_page = Region(infoblock_type='detail') cfg_btn = partial(toolbar.select, 'Configuration') pol_btn = partial(toolbar.select, 'Policy') lcl_btn = partial(toolbar.select, 'Lifecycle') mon_btn = partial(toolbar.select, 'Monitoring') pwr_btn = partial(toolbar.select, 'Power') visible_tree = Tree("//div[@class='dhxcont_global_content_area']" "[not(contains(@style, 'display: none'))]/div/div/div" "/ul[@class='dynatree-container']") manage_policies_tree = CheckboxTree( version.pick({ "default": "//div[@id='treebox']/div/table", "5.3": "//div[@id='protect_treebox']/ul" })) manage_policies_page = Region( locators={ 'save_button': "//div[@id='buttons_on']//img[@alt='Save Changes']", }) snapshot_form = Form(fields=[( 'name', "//div[@id='auth_tabs']/ul/li/a[@href='#default']" ), ( 'descrition', "//*[@id='default_userid']" ), ('snapshot_memory', "//*[@id='default_password']"), ( 'create_button', "//input[@name='create']"), ('cancel_button',