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 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 verify_retirement_date(retire_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 elif pick(VM.RETIRE_DATE_FMT).endswith('+0000'): convert_func = parsetime.from_saved_report_title_format else: convert_func = parsetime.from_american_date_only expected_date.update({'retire': convert_func(retire_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 retire_vm.retirement_date == expected_date.strftime(pick(VM.RETIRE_DATE_FMT)) else: assert retire_vm.retirement_date == expected_date
def verify_retirement_date(retire_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(retire_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 retire_vm.retirement_date == expected_date.strftime( pick(VM.RETIRE_DATE_FMT)) else: assert retire_vm.retirement_date == expected_date
def view_value_mapping(self): out = {} out['hostname'] = version.pick({ version.LOWEST: None, '5.9': self.hostname }) out['api_port'] = version.pick({ version.LOWEST: None, '5.9': self.api_port }) out['sec_protocol'] = version.pick({ version.LOWEST: None, '5.9': self.sec_protocol }) if out['sec_protocol'] and self.sec_protocol.lower( ) == 'ssl trusting custom ca': out['trusted_ca_certificates'] = OpenshiftDefaultEndpoint.get_ca_cert( { "username": self.ssh_creds.principal, "password": self.ssh_creds.secret, "hostname": self.master_hostname }) return out
def view_value_mapping(self): tls_since_version = '5.8.0.8' return {'hostname': self.hostname, 'api_port': getattr(self, 'api_port', None), 'verify_tls': version.pick({ version.LOWEST: None, tls_since_version: getattr(self, 'verify_tls', None)}), 'ca_certs': version.pick({ version.LOWEST: None, tls_since_version: getattr(self, 'ca_certs', None)}) }
def pf_select(root, sub=None, invokes_alert=False): """ Clicks on a button by calling the click event with the jquery trigger. 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` """ sel.wait_for_ajax() if isinstance(root, dict): root = version.pick(root) if isinstance(sub, dict): sub = version.pick(sub) if sub: q_sub = xpath_quote(sub).replace("'", "\\'") sel.execute_script( "return $('a:contains({})').trigger('click')".format(q_sub)) else: q_root = xpath_quote(root).replace("'", "\\'") try: sel.element("//button[@data-original-title = {0}] | " "//a[@data-original-title = {0}]".format(q_root)) sel.execute_script( "return $('*[data-original-title={}]').trigger('click')". format(q_root)) except sel.NoSuchElementException: try: sel.element("//button[@title={}]".format(q_root)) sel.execute_script( "return $('button[title={}]').trigger('click')".format( q_root)) except sel.NoSuchElementException: try: sel.element( "//button[contains(@title, {})]".format(q_root)) sel.execute_script( "return $('button:contains({})').trigger('click')". format(q_root)) except sel.NoSuchElementException: # The view selection buttons? sel.click( "//li/a[@title={}]/*[self::i or self::img]/../..". format(q_root)) if not invokes_alert: sel.wait_for_ajax() return True
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 = '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 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 = '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 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 test_crud_service_dialog(appliance): element_data = { 'element_information': { 'ele_label': "ele_" + fauxfactory.gen_alphanumeric(), 'ele_name': fauxfactory.gen_alphanumeric(), 'ele_desc': fauxfactory.gen_alphanumeric(), 'choose_type': "Text Box" }, 'options': { 'default_text_box': "Default text" } } dialog, element = create_dialog(appliance, element_data) view_cls = navigator.get_class(element.parent, 'Add').VIEW view = element.appliance.browser.create_view(view_cls) flash_message = version.pick({ '5.8': 'Dialog "{}" was added'.format(dialog.label), '5.9': '{} was saved'.format(dialog.label) }) view.flash.assert_message(flash_message) with update(dialog): dialog.description = "my edited description" dialog.delete()
def myservice(appliance, setup_provider, provider, catalog_item, request): """Tests my service Metadata: test_flag: provision """ vm_name = version.pick({ version.LOWEST: catalog_item.provisioning_data["vm_name"] + '_0001', '5.7': catalog_item.provisioning_data["vm_name"] + '0001' }) catalog_item.create() service_catalogs = ServiceCatalogs(appliance, catalog_item.catalog, catalog_item.name) service_catalogs.order() logger.info('Waiting for cfme provision request for service %s', catalog_item.name) request_description = catalog_item.name service_request = appliance.collections.requests.instantiate( request_description, partial_check=True) service_request.wait_for_request() assert service_request.is_succeeded() yield catalog_item.name, vm_name cleanup_vm(vm_name, provider)
def assign_to(self, assign, selections=None, tag_category=None): """Assigns this Alert Profile to specified objects. Args: assign: Where to assign (The Enterprise, ...). selections: What items to check in the tree. N/A for The Enteprise. tag_category: Only for choices starting with Tagged. N/A for The Enterprise. """ view = navigate_to(self, "Edit assignments") changed = view.fill({ "assign_to": assign, "tag_category": tag_category, "selections": selections }) if changed: view.save_button.click() else: view.cancel_button.click() view = self.create_view(AlertProfileDetailsView) assert view.is_displayed view.flash.assert_no_error() if changed: view.flash.assert_message( 'Alert Profile "{}" assignments {} saved'.format( self.description, version.pick({ version.LOWEST: "succesfully", "5.8": "successfully", }))) else: view.flash.assert_message( 'Edit of Alert Profile "{}" was cancelled by the user'.format( self.description))
def test_service_dialog_duplicate_name(appliance, request): element_data = { 'element_information': { 'ele_label': "ele_" + fauxfactory.gen_alphanumeric(), 'ele_name': fauxfactory.gen_alphanumeric(), 'ele_desc': fauxfactory.gen_alphanumeric(), 'choose_type': "Text Box" }, 'options': { 'default_text_box': "Default text" } } label = 'duplicate_' + fauxfactory.gen_alphanumeric() dialog, element = create_dialog(appliance, element_data, label=label) request.addfinalizer(dialog.delete_if_exists) region_number = appliance.server.zone.region.number error_message = version.pick({ '5.8': 'Validation failed: Label is not unique within region {}'.format(region_number), '5.9': 'There was an error editing this dialog: ' 'Failed to create a new dialog - Validation failed: ' 'Name is not unique within region {}'.format(region_number)}) with pytest.raises(AssertionError): create_dialog(appliance, element_data, label=label) view_cls = navigator.get_class(element.parent, 'Add').VIEW view = element.appliance.browser.create_view(view_cls) view.flash.assert_message(error_message)
def _fill_provider_attributes(self, provider_attributes): """Fills provider data. Helper method for ``self.create_rest`` """ if getattr(self, "region", None): provider_attributes["provider_region"] = version.pick( self.region) if isinstance(self.region, dict) else self.region if getattr(self, "project", None): provider_attributes["project"] = self.project if self.type_name in ('openstack_infra', 'openstack'): if getattr(self, 'api_version', None): version = 'v3' if 'v3' in self.api_version else 'v2' provider_attributes['api_version'] = version if version == 'v3' and getattr(self, 'keystone_v3_domain_id', None): provider_attributes['uid_ems'] = self.keystone_v3_domain_id if self.type_name == "azure": provider_attributes["uid_ems"] = self.tenant_id provider_attributes["provider_region"] = self.region.lower( ).replace(" ", "") if getattr(self, "subscription_id", None): provider_attributes["subscription"] = self.subscription_id
def test_service_dialog_duplicate_name(appliance, request): element_data = { 'element_information': { 'ele_label': "ele_" + fauxfactory.gen_alphanumeric(), 'ele_name': fauxfactory.gen_alphanumeric(), 'ele_desc': fauxfactory.gen_alphanumeric(), 'choose_type': "Text Box" }, 'options': { 'default_text_box': "Default text" } } label = 'duplicate_' + fauxfactory.gen_alphanumeric() dialog, element = create_dialog(appliance, element_data, label=label) request.addfinalizer(dialog.delete_if_exists) region_number = appliance.server.zone.region.number error_message = version.pick({ '5.8': 'Validation failed: Label is not unique within region {}'.format( region_number), '5.9': 'There was an error editing this dialog: ' 'Failed to create a new dialog - Validation failed: ' 'Name is not unique within region {}'.format(region_number) }) with pytest.raises(AssertionError): create_dialog(appliance, element_data, label=label) view_cls = navigator.get_class(element.parent, 'Add').VIEW view = element.appliance.browser.create_view(view_cls) view.flash.assert_message(error_message)
def test_permission_edit(appliance, request, product_features, action): """ Ensures that changes in permissions are enforced on next login Args: appliance: cfme appliance fixture request: pytest request fixture product_features: product features to set for test role action: reference to a function to execute under the test user context """ product_features = version.pick(product_features) request.addfinalizer(appliance.server.login_admin) role_name = fauxfactory.gen_alphanumeric() role = appliance.collections.roles.create(name=role_name, vm_restriction=None, product_features=[(['Everything'], False)] + # role_features [(k, True) for k in product_features]) group_description = 'grp{}'.format(fauxfactory.gen_alphanumeric()) group = group_collection(appliance).create(description=group_description, role=role.name) user = new_user(appliance, group=group) with user: try: action() except Exception: pytest.fail('Incorrect permissions set') appliance.server.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.fail('Permissions have not been updated')
def backup(appliance, provider): volume_collection = appliance.collections.volumes storage_manager = version.pick({ '5.8': '{} Cinder Manager'.format(provider.name), version.LOWEST: None }) backup_collection = appliance.collections.volume_backups.filter( {'provider': provider}) # create new volume volume = volume_collection.create( name=fauxfactory.gen_alpha(), storage_manager=storage_manager, tenant=provider.data['provisioning']['cloud_tenant'], size=STORAGE_SIZE, provider=provider) # create new backup for crated volume backup_name = fauxfactory.gen_alpha() volume.create_backup(backup_name) backup = backup_collection.instantiate(backup_name, provider) yield backup try: if backup.exists: backup_collection.delete(backup) if volume.exists: volume.delete(wait=False) except Exception: logger.warning('Exception during volume deletion - skipping..')
def view_value_mapping(self): out = { 'hostname': self.hostname, 'password': self.token, 'api_port': self.api_port, 'sec_protocol': self.sec_protocol } if self.sec_protocol.lower() == 'ssl trusting custom ca' and hasattr( self, 'get_ca_cert'): out['trusted_ca_certificates'] = self.get_ca_cert({ "username": self.ssh_creds.principal, "password": self.ssh_creds.secret, "hostname": self.master_hostname }) out['confirm_password'] = version.pick({ version.LOWEST: self.token, '5.9': None }) return out
def orchestration_templates(request, rest_api, num=2): data = [] for _ in range(num): uniq = fauxfactory.gen_alphanumeric(5) data.append({ 'name': 'test_{}'.format(uniq), 'description': 'Test Template {}'.format(uniq), 'type': version.pick({ version.LOWEST: 'OrchestrationTemplateCfn', '5.9': 'ManageIQ::Providers::Amazon::CloudManager::OrchestrationTemplate' }), 'orderable': False, 'draft': False, 'content': TEMPLATE_TORSO.replace('CloudFormation', uniq) }) return _creating_skeleton(request, rest_api, 'orchestration_templates', data)
def _refresh_flash_msg(self): return version.pick({ '5.7': 'Refresh Provider initiated for 1 provider ({})'.format(self.type), '5.8': 'Refresh Provider initiated for 1 provider' })
def pf_select(root, sub=None, invokes_alert=False): """ Clicks on a button by calling the click event with the jquery trigger. 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` """ sel.wait_for_ajax() if isinstance(root, dict): root = version.pick(root) if isinstance(sub, dict): sub = version.pick(sub) if sub: q_sub = xpath_quote(sub).replace("'", "\\'") sel.execute_script( "return $('a:contains({})').trigger('click')".format(q_sub)) else: q_root = xpath_quote(root).replace("'", "\\'") try: sel.element("//button[@data-original-title = {0}] | " "//a[@data-original-title = {0}]".format(q_root)) sel.execute_script( "return $('*[data-original-title={}]').trigger('click')".format(q_root)) except sel.NoSuchElementException: try: sel.element("//button[@title={}]".format(q_root)) sel.execute_script( "return $('button[title={}]').trigger('click')".format(q_root)) except sel.NoSuchElementException: try: sel.element("//button[contains(@title, {})]".format(q_root)) sel.execute_script( "return $('button:contains({})').trigger('click')".format(q_root)) except sel.NoSuchElementException: # The view selection buttons? sel.click("//li/a[@title={}]/*[self::i or self::img]/../..".format(q_root)) if not invokes_alert: sel.wait_for_ajax() return True
def retire(self): self.load_details(refresh=True) lcl_btn(self.TO_RETIRE, invokes_alert=True) sel.handle_alert() flash.assert_success_message( 'Retirement initiated for 1 VM and Instance from the {} Database'.format(version.pick({ version.LOWEST: 'CFME', 'upstream': 'ManageIQ'})))
def type(self): """Returns presumed type of the manager based on CFME version Note: We cannot actually know the type of the provider from the UI. This represents the supported type by CFME version and is to be used in navigation. """ return version.pick({version.LOWEST: 'Red Hat Satellite', version.LATEST: 'Foreman'})
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)))) # Create the vm_retire_extend button and click on it retire_extend_button() # CFME automate vm_retire_extend method defaults to extending the date by 14 days extend_duration_days = 14 extended_retirement_date = retirement_date + timedelta( days=extend_duration_days) # Check that the WebUI updates with the correct date wait_for( lambda: testing_vm.retirement_date >= extended_retirement_date. strftime(pick(VM.RETIRE_DATE_FMT)), num_sec=60, message="Check for extension of the VM retirement date by {} days". format(extend_duration_days))
def _install_simplecov(self): self.log.info('Installing coverage gem on appliance') self.ipapp.ssh_client.put_file(gemfile.strpath, bundler_d.strpath) # gem install for more recent downstream builds def _gem_install(): self.ipapp.ssh_client.run_command( 'gem install --install-dir /opt/rh/cfme-gemset/ -v0.9.2 simplecov') # bundle install for old downstream and upstream builds def _bundle_install(): self.ipapp.ssh_client.run_command('yum -y install git') self.ipapp.ssh_client.run_command('cd {}; bundle'.format(rails_root)) version.pick({ version.LOWEST: _gem_install, version.LATEST: _bundle_install, })()
def view_value_mapping(self): out = {} out['hostname'] = version.pick({ version.LOWEST: None, '5.9': self.hostname}) out['api_port'] = version.pick({ version.LOWEST: None, '5.9': self.api_port}) out['sec_protocol'] = version.pick({ version.LOWEST: None, '5.9': self.sec_protocol}) if out['sec_protocol'] and self.sec_protocol.lower() == 'ssl trusting custom ca': out['trusted_ca_certificates'] = OpenshiftDefaultEndpoint.get_ca_cert() return out
def view_value_mapping(self): """Maps values to view attrs""" region = pick(self.region) if isinstance(self.region, dict) else self.region return { 'name': self.name, 'prov_type': 'Azure', 'region': region, 'tenant_id': self.tenant_id, 'subscription': getattr(self, 'subscription_id', None) }
def view_value_mapping(self): return { 'name': self.name, 'prov_type': version.pick({ version.LOWEST: 'Red Hat Virtualization Manager', '5.8.0.10': 'Red Hat Virtualization' }), }
def view_value_mapping(self): """ used for filling forms like add/edit provider form Returns: dict """ return { 'token': self.token, 'verify_token': version.pick({version.LOWEST: self.verify_token, '5.9': None}) }
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)))) # Create the vm_retire_extend button and click on it retire_extend_button() # CFME automate vm_retire_extend method defaults to extending the date by 14 days extend_duration_days = 14 extended_retirement_date = retirement_date + timedelta(days=extend_duration_days) # Check that the WebUI updates with the correct date wait_for( lambda: testing_vm.retirement_date >= extended_retirement_date.strftime( pick(VM.RETIRE_DATE_FMT)), num_sec=60, message="Check for extension of the VM retirement date by {} days".format( extend_duration_days) )
def retire(self): self.load_details(refresh=True) lcl_btn(self.TO_RETIRE, invokes_alert=True) sel.handle_alert() flash.assert_success_message( 'Retirement initiated for 1 VM and Instance from the {} Database'. format( version.pick({ version.LOWEST: 'CFME', 'upstream': 'ManageIQ' })))
def view_value_mapping(self): """ used for filling forms like add/edit provider form Returns: dict """ return { 'username': self.principal, 'password': self.secret, 'confirm_password': version.pick({version.LOWEST: self.verify_secret, '5.9': None}) }
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 delete(self): view = navigate_to(self, "Details") view.configuration.item_select( version.pick({ version.LOWEST: 'Remove Item from the VMDB', '5.7': 'Remove Catalog'}), handle_alert=True) view = self.create_view(CatalogsView) assert view.is_displayed view.flash.assert_no_error() view.flash.assert_success_message( 'Catalog "{}": Delete successful'.format(self.description or self.name))
def view_value_mapping(self): out = {} out['hostname'] = version.pick({ version.LOWEST: None, '5.9': self.hostname}) out['api_port'] = version.pick({ version.LOWEST: None, '5.9': self.api_port}) out['sec_protocol'] = version.pick({ version.LOWEST: None, '5.9': self.sec_protocol}) if out['sec_protocol'] and self.sec_protocol.lower() == 'ssl trusting custom ca': out['trusted_ca_certificates'] = OpenshiftDefaultEndpoint.get_ca_cert( {"username": self.ssh_creds.principal, "password": self.ssh_creds.secret, "hostname": self.master_hostname}) return out
def delete(self): view = navigate_to(self, "Details") view.configuration.item_select(version.pick({ version.LOWEST: 'Remove Item from the VMDB', '5.7': 'Remove Catalog Item' }), handle_alert=True) view = self.create_view(AllCatalogItemView) assert view.is_displayed view.flash.assert_success_message( 'The selected Catalog Item was deleted')
def delete(self, cancel=True): """ Deletes a provider from CFME Args: cancel: Whether to cancel the deletion, defaults to True """ view = navigate_to(self, 'Details') item_title = version.pick({'5.9': 'Remove this {} Provider from Inventory', version.LOWEST: 'Remove this {} Provider'}) view.toolbar.configuration.item_select(item_title.format("Infrastructure"), handle_alert=not cancel) if not cancel: view.flash.assert_no_error()
def view_value_mapping(self): out = {'hostname': self.hostname, 'password': self.token, 'api_port': self.api_port, 'sec_protocol': self.sec_protocol} if self.sec_protocol.lower() == 'ssl trusting custom ca' and hasattr(self, 'get_ca_cert'): out['trusted_ca_certificates'] = self.get_ca_cert() out['confirm_password'] = version.pick({ version.LOWEST: self.token, '5.9': None}) return out
def orchestration_templates(request, rest_api, num=2): data = [] for _ in range(num): uniq = fauxfactory.gen_alphanumeric(5) data.append({ 'name': 'test_{}'.format(uniq), 'description': 'Test Template {}'.format(uniq), 'type': version.pick({ version.LOWEST: 'OrchestrationTemplateCfn', '5.9': 'ManageIQ::Providers::Amazon::CloudManager::OrchestrationTemplate'}), 'orderable': False, 'draft': False, 'content': TEMPLATE_TORSO.replace('CloudFormation', uniq)}) return _creating_skeleton(request, rest_api, 'orchestration_templates', data)
def delete(self, cancel=True): """ Deletes a provider from CFME Args: cancel: Whether to cancel the deletion, defaults to True """ view = navigate_to(self, 'Details') item_title = version.pick({'5.9': 'Remove this {} Provider from Inventory', version.LOWEST: 'Remove this {} Provider'}) view.toolbar.configuration.item_select(item_title.format(self.string_name), handle_alert=not cancel) if not cancel: msg = ('Delete initiated for 1 {} Provider from ' 'the {} Database'.format(self.string_name, self.appliance.product_name)) view.flash.assert_success_message(msg)
def _fill_provider_attributes(self, provider_attributes): """Fills provider data. Helper method for ``self.create_rest`` """ if getattr(self, "region", None): provider_attributes["provider_region"] = version.pick( self.region) if isinstance(self.region, dict) else self.region if getattr(self, "project", None): provider_attributes["project"] = self.project if self.type_name == "azure": provider_attributes["uid_ems"] = self.tenant_id provider_attributes["provider_region"] = self.region.lower().replace(" ", "") if getattr(self, "subscription_id", None): provider_attributes["subscription"] = self.subscription_id
def test_properties(provider, appliance, test_item, soft_assert): instances = test_item.collection_object(appliance).get_random_instances(count=2) for instance in instances: if isinstance(test_item.expected_fields, dict): expected_fields = version.pick(test_item.expected_fields) else: expected_fields = test_item.expected_fields for field in expected_fields: view = navigate_to(instance, 'Details') try: soft_get(view.entities.properties.read(), field, dict_=True) except AttributeError: soft_assert(False, '{} "{}" properties table has missing field - "{}"' .format(test_item.obj.__name__, instance.name, field))
def num_container(self): # Containers are linked to providers through container definitions and then through pods query = version.pick({ version.LOWEST: "SELECT count(*) " "FROM ext_management_systems, container_groups, container_definitions, containers " "WHERE containers.container_definition_id=container_definitions.id " "AND container_definitions.container_group_id=container_groups.id " "AND container_groups.ems_id=ext_management_systems.id " "AND ext_management_systems.name='{}'".format(self.name), '5.9': "SELECT count(*) " "FROM ext_management_systems, container_groups, containers " "WHERE containers.container_group_id=container_groups.id " "AND container_groups.ems_id=ext_management_systems.id " "AND ext_management_systems.name='{}'".format(self.name) }) res = self.appliance.db.client.engine.execute(query) return int(res.first()[0])
def test_service_dialog_duplicate_name(appliance, request): element_data = { 'element_information': { 'ele_label': "ele_" + fauxfactory.gen_alphanumeric(), 'ele_name': fauxfactory.gen_alphanumeric(), 'ele_desc': fauxfactory.gen_alphanumeric(), 'choose_type': "Text Box" }, 'options': { 'default_text_box': "Default text" } } label = 'duplicate_' + fauxfactory.gen_alphanumeric() dialog = create_dialog(appliance, element_data, label=label) request.addfinalizer(dialog.delete_if_exists) error_message = version.pick({ '5.8': 'Validation failed: Label is not unique within region 0', '5.9': 'There was an error editing this dialog: ' 'Failed to create a new dialog - Validation failed: ' 'Name is not unique within region 0'}) with error.expected(error_message): create_dialog(appliance, element_data, label=label)
def test_crud_service_dialog(appliance): element_data = { 'element_information': { 'ele_label': "ele_" + fauxfactory.gen_alphanumeric(), 'ele_name': fauxfactory.gen_alphanumeric(), 'ele_desc': fauxfactory.gen_alphanumeric(), 'choose_type': "Text Box" }, 'options': { 'default_text_box': "Default text" } } dialog, element = create_dialog(appliance, element_data) view_cls = navigator.get_class(element.parent, 'Add').VIEW view = element.appliance.browser.create_view(view_cls) flash_message = version.pick({ '5.8': 'Dialog "{}" was added'.format(dialog.label), '5.9': '{} was saved'.format(dialog.label)}) view.flash.assert_message(flash_message) with update(dialog): dialog.description = "my edited description" dialog.delete()
def none(self): if self._none: return version.pick(self._none) else: return None
def pick(self, appliance_version): from cfme.utils.version import pick return pick(self.version_dict, appliance_version)
def g(m, *args, **kwargs): if isinstance(m, dict): m = version.pick(m) return f(m, *args, **kwargs)
def _d(l, **kwargs): """Resolve version-specific locators.""" return elements(version.pick(l), **kwargs)
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, active_version=self.vmdb_version) 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_to_run = 'source /etc/default/evm; ' + command oc_cmd = 'oc exec --namespace={proj} {pod} -- bash -c {cmd}'.format( proj=self._project, pod=self._container, cmd=quote(command_to_run)) command = oc_cmd 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 view_value_mapping(self): return { 'name': self.name, 'prov_type': version.pick({version.LOWEST: 'Red Hat Virtualization Manager', '5.8.0.10': 'Red Hat Virtualization'}), }
def run_command( self, command, timeout=RUNCMD_TIMEOUT, reraise=False, ensure_host=False, ensure_user=False, container=None): """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. container: allows to temporarily override default container Returns: A :py:class:`SSHResult` instance. """ if isinstance(command, dict): command = version.pick(command, active_version=self.vmdb_version) original_command = command uses_sudo = False logger.info("Running command %r", command) container = container or self._container if self.is_pod and not ensure_host: # This command will be executed in the context of the host provider command_to_run = '[[ -f /etc/default/evm ]] && source /etc/default/evm; ' + command oc_cmd = 'oc exec --namespace={proj} {pod} -- bash -c {cmd}'.format( proj=self._project, pod=container, cmd=quote(command_to_run)) command = oc_cmd ensure_host = True elif self.is_container and not ensure_host: command = 'docker exec {} bash -c {}'.format(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() def write_output(line, file): output.append(line) if self._streaming: file.write(line) while True: if session.exit_status_ready(): break # While the program is running loop through collecting line by line so that we don't # fill the buffers up without a newline. # Also, note that for long running programs if we try to read output when there # is none (and in the case of stderr may never be any) # we risk blocking so long that the write buffer on the remote side will fill # and the remote program will block on a write. # The blocking on our side occurs in paramiko's buffered_pipe.py's read() call, # which will block if its internal buffer is empty. if session.recv_ready(): try: line = next(stdout) write_output(line, self.f_stdout) except StopIteration: pass if session.recv_stderr_ready(): try: line = next(stdout) write_output(line, self.f_stderr) except StopIteration: pass # When the program finishes, we need to grab the rest of the output that is left. # Also, we don't have the issue of blocking reads because since the command is # finished, any pending reads of SSH encrypted data will finish shortly and put in # the buffer or for an empty file EOF will be reached as it will be closed. for line in stdout: write_output(line, self.f_stdout) for line in stderr: write_output(line, self.f_stderr) exit_status = session.recv_exit_status() if exit_status != 0: logger.warning('Exit code %d!', exit_status) return SSHResult(rc=exit_status, output=''.join(output), command=command) 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(rc=1, output=''.join(output), command=command)