def get_detail(self, *args, **kwargs): # TODO: remove when bug 1389299 is fixed to use common.vm.get_detail() # Navigate to all first to force reload of details screen without using refresh navigate_to(self, 'All') self.load_details() if kwargs.get('icon_href', False): return InfoBlock.icon_href(*kwargs.get('properties')) else: return InfoBlock.text(*kwargs.get('properties'))
def get_vm_details(): power_state = InfoBlock.text('Power Management', 'Power State') logger.debug('Service VM power state: {}'.format(power_state)) if power_state == 'unknown': # The VM power state is unknown, check lifecycle instead of power retire_state = InfoBlock.text('Lifecycle', 'Retirement state') return retire_state == 'Retired' else: # VM power is a known state, use it return power_state == 'off'
def get_vm_details(): power_state = InfoBlock.text("Power Management", "Power State") logger.debug("Service VM power state: {}".format(power_state)) if power_state == "unknown": # The VM power state is unknown, check lifecycle instead of power retire_state = InfoBlock.text("Lifecycle", "Retirement state") return retire_state == "Retired" else: # VM power is a known state, use it return power_state == "off"
def get_detail(self, properties=None, icon_href=False): """ Gets details from the details infoblock Args: *properties: An InfoBlock title, followed by the Key name e.g. "Relationships", "Images" icon_href: Boolean indicating to return icon_href instead of text Returns: A string representing the contents of the InfoBlock's value. """ navigate_to(self, 'Details') if icon_href: return InfoBlock.icon_href(*properties) else: return InfoBlock.text(*properties)
def test_pods_rel(provider, rel): """ This module verifies the integrity of the Relationships table We also verify that clicking on the Relationships table field takes the user to the correct page, and the number of rows that appears on that page is equal to the number in the Relationships table """ sel.force_navigate('containers_pods') tb.select('List View') list_tbl_pod = CheckboxTable(table_locator="//div[@id='list_grid']//table") ui_pods = [r.name.text for r in list_tbl_pod.rows()] ui_pods_revised = filter( lambda ch: 'nginx' not in ch and not ch.startswith('metrics'), ui_pods) for name in ui_pods_revised: obj = Pod(name, provider) val = obj.get_detail('Relationships', rel) if val == '0': continue obj.click_element('Relationships', rel) try: val = int(val) assert len([r for r in list_tbl_pod.rows()]) == val except ValueError: assert val == InfoBlock.text('Properties', 'Name')
def test_services_rel(provider, rel): sel.force_navigate('containers_services') list_tbl_service = CheckboxTable( table_locator="//div[@id='list_grid']//table") ui_services = [r.name.text for r in list_tbl_service.rows()] mgmt_objs = provider.mgmt.list_service() # run only if table is not empty if ui_services: # verify that mgmt pods exist in ui listed pods assert set(ui_services).issubset( [obj.name for obj in mgmt_objs]), 'Missing objects' for name in ui_services: obj = Service(name, provider) val = obj.get_detail('Relationships', rel) if val == '0': continue obj.click_element('Relationships', rel) try: val = int(val) assert len([r for r in list_tbl_service.rows()]) == val except ValueError: assert val == InfoBlock.text('Properties', 'Name')
def get_detail(self, properties=None, icon_href=False): """Gets details from the details infoblock The function first ensures that we are on the detail page for the specific VM/Instance. Args: properties: An InfoBlock title, followed by the Key name, e.g. "Relationships", "Images" Returns: A string representing the contents of the InfoBlock's value. """ self.load_details(refresh=True) if icon_href: return InfoBlock.icon_href(*properties) else: return InfoBlock.text(*properties)
def get_detail(self, *ident): """ Gets details from the details infoblock Args: *ident: Table name and Key name, e.g. "Relationships", "Images" Returns: A string representing the contents of the summary's value. """ return InfoBlock.text(*ident)
def wait_for_vm_retire(self): """ Waits for self.vm_name to go to the off state and returns state Args: Returns: A string representing the VM state """ def get_vm_details(): power_state = InfoBlock.text('Power Management', 'Power State') logger.debug('Service VM power state: {}'.format(power_state)) if power_state == 'unknown': # The VM power state is unknown, check lifecycle instead of power retire_state = InfoBlock.text('Lifecycle', 'Retirement state') return retire_state == 'Retired' else: # VM power is a known state, use it return power_state == 'off' quadicon = Quadicon(self.vm_name, "vm") sel.click(quadicon) wait_for( get_vm_details, fail_func=tb.refresh, num_sec=120 * 60, delay=10, message="Service VM power off wait" ) return InfoBlock.text('Power Management', 'Power State')
def test_disk_format_select(provisioner, disk_format, provider, prov_data): """ Tests disk format selection in provisioning dialog. Prerequisities: * A provider set up, supporting provisioning in CFME Steps: * Open the provisioning dialog. * Apart from the usual provisioning settings, set the disk format to be thick or thin. * Submit the provisioning request and wait for it to finish. * Visit the page of the provisioned VM. * The ``Thin Provisioning Used`` field should state true of false according to the selection Metadata: test_flag: provision """ prov_data["vm_name"] = "test_prov_dlg_{}".format(fauxfactory.gen_alphanumeric()) prov_data["disk_format"] = disk_format template_name = provider.data['provisioning']['template'] vm = provisioner(template_name, prov_data) # Go to the VM info vm.load_details(refresh=True) thin = InfoBlock.text( "Datastore Allocation Summary", "Thin Provisioning Used").strip().lower() == "true" if disk_format == "thin": assert thin, "The disk format should be Thin" else: assert not thin, "The disk format should not be Thin"
def test_host_devices(provider): navigate_to(provider, 'Details') sel.click(InfoBlock.element("Relationships", "Nodes")) my_quads = list(Quadicon.all()) assert len(my_quads) > 0 for quad in my_quads: host = Host(name=quad.name, provider=provider) assert int(host.get_detail("Properties", "Devices")) > 0
def get_clusters(self): """returns the list of clusters belonging to the provider""" web_clusters = [] sel.force_navigate('infrastructure_provider', context={'provider': self}) sel.click(InfoBlock.element('Relationships', 'Clusters')) icons = Quadicon.all(qtype='cluster') for icon in icons: web_clusters.append(Cluster(icon.name, self)) return web_clusters
def test_smbios_data(provider): provider.load_details() sel.click(InfoBlock.element("Relationships", "Nodes")) my_quads = list(Quadicon.all()) assert len(my_quads) > 0 for quad in my_quads: host = Host(name=quad.name) result = get_integer_value(host.get_detail("Properties", "Memory")) assert result > 0
def test_host_role_type(provider): navigate_to(provider, 'Details') sel.click(InfoBlock.element("Relationships", "Nodes")) my_quads = list(Quadicon.all()) assert len(my_quads) > 0 for quad in my_quads: role_name = str(quad.name) role_name = re.search(r'\((\w+)\)', role_name).group(1) assert role_name in ROLES
def test_host_memory(provider): navigate_to(provider, 'Details') sel.click(InfoBlock.element("Relationships", "Nodes")) my_quads = list(Quadicon.all()) assert len(my_quads) > 0 for quad in my_quads: host = Host(name=quad.name, provider=provider) result = int(host.get_detail("Properties", "Memory").split()[0]) assert result > 0
def get_clusters(self): """returns the list of clusters belonging to the provider""" web_clusters = [] navigate_to(self, "Details") sel.click(InfoBlock.element("Relationships", "Clusters")) icons = Quadicon.all(qtype="cluster") for icon in icons: web_clusters.append(Cluster(icon.name, self)) return web_clusters
def test_server_name(): """Tests that changing the server name updates the about page""" form_infoblocks = InfoBlock('form') flash_msg = 'Configuration settings saved for CFME Server "{}' sel.force_navigate('cfg_settings_currentserver_server') old_server_name = sel.value(BasicInformation.basic_information.appliance_name) new_server_name = old_server_name + "-CFME" settings_pg = BasicInformation(appliance_name=new_server_name) settings_pg.update() flash.assert_message_contain(flash_msg.format(new_server_name)) sel.force_navigate('about') assert new_server_name == form_infoblocks.text('Session Information', 'Server Name'),\ "Server name in About section does not match the new name" settings_pg = BasicInformation(appliance_name=old_server_name) settings_pg.update() flash.assert_message_contain(flash_msg.format(old_server_name))
def details_page_check(name, provider): title_match = match_page(summary='Instance "{}"'.format(name)) if title_match: # Also check provider try: prov_match = InfoBlock.text('Relationships', 'Cloud Provider') == provider.name return title_match and prov_match except BlockTypeUnknown: # Default to false since we can't identify which provider the image belongs to return False
def test_templates(provider, soft_assert): navigate_to(provider, 'Details') images = [i.name for i in provider.mgmt.images] assert int(provider.get_detail('Relationships', 'Templates')) == len(images) sel.click(InfoBlock.element('Relationships', 'Templates')) table = Table("//table[contains(@class, 'table')]") for image in images: cell = table.find_cell('Name', image) soft_assert(cell, 'Missing template: {}'.format(image))
def test_host_zones_assigned(provider): navigate_to(provider, 'Details') sel.click(InfoBlock.element("Relationships", "Nodes")) my_quads = list(Quadicon.all()) assert len(my_quads) > 0 my_quads = filter(lambda q: True if 'Compute' in q.name else False, my_quads) for quad in my_quads: host = Host(name=quad.name, provider=provider) result = host.get_detail('Relationships', 'Availability Zone') assert result, "Availability zone doesn't specified"
def test_infra_host_event(gen_events, new_vm): """Tests host event on timelines Metadata: test_flag: timelines, provision """ new_vm.load_details() host_name = InfoBlock.text('Relationships', 'Host') host = Host(name=host_name, provider=new_vm.provider) wait_for(count_events, [host, new_vm], timeout='10m', fail_condition=0, message="events to appear")
def test_smbios_data(provider): provider.load_details() sel.click(InfoBlock.element("Relationships", "Nodes")) my_quads = list(Quadicon.all()) assert len(my_quads) > 0 for quad in my_quads: host = Host(name=quad.name) host.run_smartstate_analysis() wait_for(lambda: is_host_analysis_finished(host.name), delay=15, timeout="10m", fail_func=lambda: toolbar.select('Reload')) result = get_integer_value(host.get_detail("Properties", "Memory")) assert result > 0
def details_page_check(name, provider): title_match = match_page(summary='Image "{}"'.format(name)) if title_match: # Also check provider # Limits scope of testing to images that aren't orphaned or archived, but if we don't do # this and multiple providers are present we might have multiple images with the same name try: prov_match = InfoBlock.text('Relationships', 'Cloud Provider') == provider return title_match and prov_match except BlockTypeUnknown: # Default to false since we can't identify which provider the image belongs to return False
def test_host_cpu_resources(provider, soft_assert): navigate_to(provider, 'Details') sel.click(InfoBlock.element("Relationships", "Nodes")) my_quads = list(Quadicon.all()) assert len(my_quads) > 0 for quad in my_quads: host = Host(name=quad.name, provider=provider) fields = ['Number of CPUs', 'Number of CPU Cores', 'CPU Cores Per Socket'] for field in fields: value = int(host.get_detail("Properties", field)) soft_assert(value > 0, "Aggregate Node {} is 0".format(field))
def register(self, file_path): """Register new nodes (Openstack) Fill a form for new host with json file format This function is valid only for RHOS10 and above Args: file_path - file path of json file with new node details, navigation MUST be from a specific self """ navigate_to(self, 'Details') sel.click(InfoBlock.element("Relationships", "Nodes")) tb.select('Configuration', 'Register Nodes') my_form = {'file': file_path} fill(register_nodes_form, my_form, action=register_nodes_form.register)
def test_host_role_type(provider): provider.load_details() sel.click(InfoBlock.element("Relationships", "Nodes")) my_quads = list(Quadicon.all()) assert len(my_quads) > 0 result = True while result: for quad in my_quads: role_name = str(quad.name) role_name = re.search(r'\((\w+)\)', role_name).group(1) if role_name not in ROLES: result = False assert result
def test_images_rel(provider, rel, detailfield): """ https://bugzilla.redhat.com/show_bug.cgi?id=1365878 """ # Nav to provider first navigate_to(provider, 'Details') # Then to container images for that provider # Locate Relationships table in provider details images_key = ({ version.LOWEST: 'Images', '5.7': 'Container Images' }) sel.click(InfoBlock.element('Relationships', version.pick(images_key))) # Get the names of all the container images from the table list_tbl_image = CheckboxTable( table_locator="//div[@id='list_grid']//table") ui_images = [r.name.text for r in list_tbl_image.rows()] for name in ui_images: img = Image(name, provider) navigate_to(img, 'Details') val = img.get_detail('Relationships', rel) assert val != 'Unknown image source' sel.click(InfoBlock.element('Relationships', rel)) # Containers Provider and Image Registry are string values # Other rows in the table show the number of the given items if rel in ['Containers Provider', 'Image Registry']: assert val == InfoBlock.text('Properties', detailfield) else: val = int(val) # There might be more than 1 page of items if paginator.page_controls_exist(): paginator.results_per_page(1000) assert len([r for r in list_tbl_image.rows()]) == val
def test_host_configuration(provider, soft_assert): navigate_to(provider, 'Details') sel.click(InfoBlock.element("Relationships", "Nodes")) my_quads = list(Quadicon.all()) assert len(my_quads) > 0 for quad in my_quads: host = Host(name=quad.name, provider=provider) host.run_smartstate_analysis() wait_for(is_host_analysis_finished, [host.name], delay=15, timeout="10m", fail_func=toolbar.refresh) fields = ['Packages', 'Services', 'Files'] for field in fields: value = int(host.get_detail("Configuration", field)) soft_assert(value > 0, 'Nodes number of {} is 0'.format(field))
def test_host_security(provider, soft_assert): navigate_to(provider, 'Details') sel.click(InfoBlock.element("Relationships", "Nodes")) my_quads = list(Quadicon.all()) assert len(my_quads) > 0 for quad in my_quads: host = Host(name=quad.name, provider=provider) soft_assert( int(host.get_detail("Security", "Users")) > 0, 'Nodes number of Users is 0') soft_assert( int(host.get_detail("Security", "Groups")) > 0, 'Nodes number of Groups is 0')
def test_host_assigned_zones(provider): provider.load_details() sel.click(InfoBlock.element("Relationships", "Nodes")) my_quads = list(Quadicon.all()) assert len(my_quads) > 0 for quad in my_quads: if quad.name != NODE_TYPE: break host = Host(name=quad.name) host.run_smartstate_analysis() wait_for(lambda: is_host_analysis_finished(host.name), delay=15, timeout="10m", fail_func=lambda: toolbar.select('Reload')) result = host.get_detail('Relationships', 'Availability Zone') assert result == 'nova'
def equal_drift_results(self, row_text, section, *indexes): """ Compares drift analysis results of a row specified by it's title text Args: row_text: Title text of the row to compare section: Accordion section where the change happened; this section will be activated indexes: Indexes of results to compare starting with 0 for first row (latest result). Compares all available drifts, if left empty (default). Note: There have to be at least 2 drift results available for this to work. Returns: ``True`` if equal, ``False`` otherwise. """ # mark by indexes or mark all self.load_details(refresh=True) sel.click(InfoBlock("Properties", "Drift History")) if indexes: drift_table.select_rows_by_indexes(*indexes) else: # We can't compare more than 10 drift results at once # so when selecting all, we have to limit it to the latest 10 if len(list(drift_table.rows())) > 10: drift_table.select_rows_by_indexes(*range(0, min(10, len))) else: drift_table.select_all() tb.select("Select up to 10 timestamps for Drift Analysis") # Make sure the section we need is active/open sec_apply_btn = "//div[@id='accordion']/a[contains(normalize-space(text()), 'Apply')]" # Deselect other sections for other_section in drift_section.child_items(): drift_section.check_node(other_section.text) drift_section.uncheck_node(other_section.text) # Activate the required section drift_section.check_node(section) sel.click(sec_apply_btn) if not tb.is_active("All attributes"): tb.select("All attributes") drift_grid = DriftGrid() if any(drift_grid.cell_indicates_change(row_text, i) for i in range(0, len(indexes))): return False return True
def test_images_rel(provider, rel): sel.force_navigate('containers_images') ui_images = [r.name.text for r in list_tbl.rows()] for name in ui_images: obj = Image(name, provider) val = obj.get_detail('Relationships', rel) if val == '0' or val == 'Unknown image source': continue obj.click_element('Relationships', rel) try: val = int(val) assert len([r for r in list_tbl.rows()]) == val except ValueError: assert val == InfoBlock.text('Properties', 'Name')
def test_ssa_users(provider, instance, soft_assert): """ Tests SSA fetches correct results for users list Metadata: test_flag: vm_analysis """ username = fauxfactory.gen_alphanumeric() expected = None # In windows case we can't add new users (yet) # So we simply check that user list doesn't cause any Rails errors if instance.system_type != WINDOWS: # Add a new user instance.ssh.run_command("userdel {0} || useradd {0}".format(username)) expected = instance.ssh.run_command( "cat /etc/passwd | wc -l").output.strip('\n') instance.smartstate_scan() wait_for(lambda: is_vm_analysis_finished(instance.name), delay=15, timeout="10m", fail_func=lambda: tb.select('Reload')) # Check that all data has been fetched current = instance.get_detail(properties=('Security', 'Users')) if instance.system_type != WINDOWS: assert current == expected # Make sure created user is in the list sel.click(InfoBlock("Security", "Users")) template = '//div[@id="list_grid"]/div[@class="{}"]/table/tbody' users = version.pick({ version.LOWEST: SplitTable(header_data=(template.format("xhdr"), 1), body_data=(template.format("objbox"), 0)), "5.5": Table('//table'), }) for page in paginator.pages(): sel.wait_for_element(users) if users.find_row('Name', username): return if instance.system_type != WINDOWS: pytest.fail("User {0} was not found".format(username))
def get_detail(properties): navigate_to(current_appliance().server, 'About') if current_version() < '5.7': properties = ['Session Information', properties] return InfoBlock.text(*properties).encode("utf-8").strip() else: locator = '//div[@class="product-versions-pf"]//li' sel.wait_for_element(locator) for element in sel.elements(locator): logger.debug('Checking for detail match for "{}" in "{}"'.format( properties, element.text)) match = re.match("{}\s(?P<value>.*)".format(properties), element.text) if match: return match.group('value') else: raise ElementOrBlockNotFound( 'Could not match about detail {}'.format(properties))
def test_ssa_groups(provider, instance, soft_assert): """ Tests SSA fetches correct results for groups Metadata: test_flag: vm_analysis """ group = fauxfactory.gen_alphanumeric() expected = None if instance.system_type != WINDOWS: # Add a new group instance.ssh.run_command("groupdel {0} || groupadd {0}".format(group)) expected = instance.ssh.run_command( "cat /etc/group | wc -l").output.strip('\n') instance.smartstate_scan() wait_for(lambda: is_vm_analysis_finished(instance.name), delay=15, timeout="10m", fail_func=lambda: tb.select('Reload')) # Check that all data has been fetched current = instance.get_detail(properties=('Security', 'Groups')) if instance.system_type != WINDOWS: assert current == expected # Make sure created group is in the list sel.click(InfoBlock("Security", "Groups")) template = '//div[@id="list_grid"]/div[@class="{}"]/table/tbody' groups = version.pick({ version.LOWEST: SplitTable(header_data=(template.format("xhdr"), 1), body_data=(template.format("objbox"), 0)), "5.5": Table('//table'), }) for page in paginator.pages(): sel.wait_for_element(groups) if groups.find_row('Name', group): return if instance.system_type != WINDOWS: pytest.fail("Group {0} was not found".format(group))
def test_server_name(): """Tests that changing the server name updates the about page""" flash_msg = 'Configuration settings saved for CFME Server "{}' sel.force_navigate('cfg_settings_currentserver_server') old_server_name = sel.value(BasicInformation.basic_information.appliance_name) new_server_name = old_server_name + "-CFME" settings_pg = BasicInformation(appliance_name=new_server_name) settings_pg.update() flash.assert_message_contain(flash_msg.format(new_server_name)) sel.force_navigate('about') assert new_server_name == InfoBlock('Session Information', 'Server Name').text,\ "Server name in About section does not match the new name" clear_property_cache(store.current_appliance, 'configuration_details') settings_pg = BasicInformation(appliance_name=old_server_name) settings_pg.update() flash.assert_message_contain(flash_msg.format(old_server_name)) clear_property_cache(store.current_appliance, 'configuration_details')
def test_services_rel(provider, rel): sel.force_navigate('containers_services') ui_services = [r.name.text for r in list_tbl.rows()] mgmt_objs = provider.mgmt.list_service() # run only if table is not empty if ui_services: # verify that mgmt pods exist in ui listed pods assert set(ui_services).issubset([obj.name for obj in mgmt_objs ]), 'Missing objects' for name in ui_services: obj = Service(name, provider) val = obj.get_detail('Relationships', rel) if val == '0': continue obj.click_element('Relationships', rel) try: val = int(val) assert len([r for r in list_tbl.rows()]) == val except ValueError: assert val == InfoBlock.text('Properties', 'Name')
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') else: repo_or_channel = reg_data.get('add_channel') 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'), 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 test_run_host_analysis(request, setup_provider, provider, host_type, host_name, register_event, soft_assert, bug): """ Run host SmartState analysis Metadata: test_flag: host_analysis """ # Add credentials to host host_data = get_host_data_by_name(provider.key, host_name) test_host = host.Host(name=host_name) wait_for(lambda: test_host.exists, delay=10, num_sec=120) if not test_host.has_valid_credentials: with update(test_host): test_host.credentials = host.get_credentials_from_config( host_data['credentials']) wait_for(lambda: test_host.has_valid_credentials, delay=10, num_sec=120) # Remove creds after test @request.addfinalizer def _host_remove_creds(): with update(test_host): test_host.credentials = host.Host.Credential(principal="", secret="", verify_secret="") register_event(None, "host", host_name, ["host_analysis_request", "host_analysis_complete"]) # Initiate analysis test_host.run_smartstate_analysis() wait_for(lambda: is_host_analysis_finished(host_name), delay=15, timeout="10m", fail_func=lambda: toolbar.select('Reload')) # Check results of the analysis drift_history = test_host.get_detail('Relationships', 'Drift History') soft_assert(drift_history != '0', 'No drift history change found') if provider.type == "rhevm": soft_assert( test_host.get_detail('Configuration', 'Services') != '0', 'No services found in host detail') if host_type in ('rhel', 'rhev'): soft_assert( InfoBlock.text('Security', 'Users') != '0', 'No users found in host detail') soft_assert( InfoBlock.text('Security', 'Groups') != '0', 'No groups found in host detail') soft_assert( InfoBlock.text('Security', 'SSH Root') != '', 'No packages found in host detail') soft_assert( InfoBlock.text('Configuration', 'Packages') != '0', 'No packages found in host detail') soft_assert( InfoBlock.text('Configuration', 'Files') != '0', 'No files found in host detail') soft_assert( InfoBlock.text('Security', 'Firewall Rules') != '0', 'No firewall rules found in host detail') elif host_type in ('esx', 'esxi'): soft_assert( InfoBlock.text('Configuration', 'Advanced Settings') != '0', 'No advanced settings found in host detail') if not (provider.type == "virtualcenter" and provider.version < "5"): # If the Firewall Rules are 0, the element can't be found (it's not a link) try: # This fails for vsphere4... https://bugzilla.redhat.com/show_bug.cgi?id=1055657 list_acc.select('Security', 'Show the firewall rules on this Host') except ListAccordionLinkNotFound: # py.test's .fail would wipe the soft_assert data soft_assert( False, "No firewall rules found in host detail accordion")
def nav_step(): test_instance.load_details() pytest.sel.click(InfoBlock.element('Relationships', 'Availability Zone')) toolbar.select('Monitoring', 'Timelines')
def get_tag(): return InfoBlock('Smart Management', 'My Company Tags').text
def test_ssa_template(request, local_setup_provider, provider, soft_assert, vm_analysis_data, appliance): """ Tests SSA can be performed on a template Metadata: test_flag: vm_analysis """ template_name = vm_analysis_data['image'] template = Template.factory(template_name, provider, template=True) # Set credentials to all hosts set for this datastore if provider.type in ['virtualcenter', 'rhevm']: datastore_name = vm_analysis_data['datastore'] datastore_collection = appliance.collections.datastores test_datastore = datastore_collection.instantiate(name=datastore_name, provider=provider) host_list = cfme_data.get('management_systems', {})[provider.key].get('hosts', []) host_names = [h.name for h in test_datastore.get_hosts()] for host_name in host_names: host_collection = appliance.collections.hosts test_host = host_collection.instantiate(name=host_name, provider=provider) hosts_data = [x for x in host_list if x.name == host_name] if len(hosts_data) > 0: host_data = hosts_data[0] if not test_host.has_valid_credentials: creds = host.get_credentials_from_config( host_data['credentials']) test_host.update(updates={'credentials': creds}, validate_credentials=True) template.smartstate_scan() wait_for(lambda: is_vm_analysis_finished(template_name), delay=15, timeout="35m", fail_func=lambda: toolbar.select('Reload')) # Check release and quadricon quadicon_os_icon = template.find_quadicon().data['os'] details_os_icon = template.get_detail(properties=('Properties', 'Operating System'), icon_href=True) logger.info("Icons: {}, {}".format(details_os_icon, quadicon_os_icon)) # We shouldn't use get_detail anymore - it takes too much time c_users = InfoBlock.text('Security', 'Users') c_groups = InfoBlock.text('Security', 'Groups') c_packages = 0 if vm_analysis_data['fs-type'] not in ['ntfs', 'fat32']: c_packages = InfoBlock.text('Configuration', 'Packages') logger.info("SSA shows {} users, {} groups and {} packages".format( c_users, c_groups, c_packages)) if vm_analysis_data['fs-type'] not in ['ntfs', 'fat32']: soft_assert(c_users != '0', "users: '{}' != '0'".format(c_users)) soft_assert(c_groups != '0', "groups: '{}' != '0'".format(c_groups)) soft_assert(c_packages != '0', "packages: '{}' != '0'".format(c_packages)) else: # Make sure windows-specific data is not empty c_patches = InfoBlock.text('Security', 'Patches') c_applications = InfoBlock.text('Configuration', 'Applications') c_win32_services = InfoBlock.text('Configuration', 'Win32 Services') c_kernel_drivers = InfoBlock.text('Configuration', 'Kernel Drivers') c_fs_drivers = InfoBlock.text('Configuration', 'File System Drivers') soft_assert(c_patches != '0', "patches: '{}' != '0'".format(c_patches)) soft_assert(c_applications != '0', "applications: '{}' != '0'".format(c_applications)) soft_assert(c_win32_services != '0', "win32 services: '{}' != '0'".format(c_win32_services)) soft_assert(c_kernel_drivers != '0', "kernel drivers: '{}' != '0'".format(c_kernel_drivers)) soft_assert(c_fs_drivers != '0', "fs drivers: '{}' != '0'".format(c_fs_drivers))
def nav_step(): test_vm.load_details() pytest.sel.click(InfoBlock.element('Relationships', 'Cluster')) toolbar.select('Monitoring', 'Timelines')
def test_run_host_analysis(request, setup_provider, provider, host_type, host_name, register_event, soft_assert, bug): """ Run host SmartState analysis Metadata: test_flag: host_analysis """ # Add credentials to host host_data = get_host_data_by_name(provider.key, host_name) test_host = host.Host(name=host_name) wait_for(lambda: test_host.exists, delay=10, num_sec=120) if not test_host.has_valid_credentials: with update(test_host): test_host.credentials = host.get_credentials_from_config( host_data['credentials']) wait_for(lambda: test_host.has_valid_credentials, delay=10, num_sec=120) # Remove creds after test @request.addfinalizer def _host_remove_creds(): with update(test_host): test_host.credentials = host.Host.Credential(principal="", secret="", verify_secret="") register_event(None, "host", host_name, ["host_analysis_request", "host_analysis_complete"]) # Initiate analysis test_host.run_smartstate_analysis() # Wait for the task to finish @pytest.wait_for(delay=15, timeout="8m", fail_func=lambda: tb.select('Reload')) def is_host_analysis_finished(): """ Check if analysis is finished - if not, reload page """ if not sel.is_displayed(tasks.tasks_table) or not tabs.is_tab_selected( 'All Other Tasks'): sel.force_navigate('tasks_all_other') host_analysis_finished = tasks.tasks_table.find_row_by_cells({ 'task_name': "SmartState Analysis for '{}'".format(host_name), 'state': 'Finished' }) return host_analysis_finished is not None # Delete the task tasks.tasks_table.select_row_by_cells({ 'task_name': "SmartState Analysis for '{}'".format(host_name), 'state': 'Finished' }) tb.select('Delete Tasks', 'Delete', invokes_alert=True) sel.handle_alert() # Check results of the analysis drift_history = test_host.get_detail('Relationships', 'Drift History') soft_assert(drift_history != '0', 'No drift history change found') # This is done on purpose; we cannot use the "bug" fixture here as # the bug doesnt block streams other than 5.3 services_bug = BZ(1156028, forced_streams=["5.3", "5.4", "5.5", "upstream"]) if provider.type == "rhevm" and (not services_bug.blocks): soft_assert( test_host.get_detail('Configuration', 'Services') != '0', 'No services found in host detail') if host_type in ('rhel', 'rhev'): soft_assert( InfoBlock.text('Security', 'Users') != '0', 'No users found in host detail') soft_assert( InfoBlock.text('Security', 'Groups') != '0', 'No groups found in host detail') soft_assert( InfoBlock.text('Security', 'SSH Root') != '', 'No packages found in host detail') soft_assert( InfoBlock.text('Configuration', 'Packages') != '0', 'No packages found in host detail') soft_assert( InfoBlock.text('Configuration', 'Files') != '0', 'No files found in host detail') if not BZ(1055657, forced_streams=["5.4", "5.5", "upstream"]).blocks: soft_assert( InfoBlock.text('Security', 'Firewall Rules') != '0', 'No firewall rules found in host detail') elif host_type in ('esx', 'esxi'): soft_assert( InfoBlock.text('Configuration', 'Advanced Settings') != '0', 'No advanced settings found in host detail') fw_bug = bug(1055657) if not (fw_bug is not None and provider.type == "virtualcenter" and provider.version < "5"): # If the Firewall Rules are 0, the element can't be found (it's not a link) try: # This fails for vsphere4... https://bugzilla.redhat.com/show_bug.cgi?id=1055657 list_acc.select('Security', 'Show the firewall rules on this Host') except ListAccordionLinkNotFound: # py.test's .fail would wipe the soft_assert data soft_assert( False, "No firewall rules found in host detail accordion")
def _nav_to_snapshot_mgmt(self): snapshot_title = '"Snapshots" for Virtual Machine "{}"'.format( self.vm.name) if summary_title() != snapshot_title: self.vm.load_details() sel.click(InfoBlock.element("Properties", "Snapshots"))
def navigate(self): self.o.load_details() sel.click(InfoBlock.element("Relationships", "Genealogy"))
def step(self): sel.click(InfoBlock('Overview', 'Topology'))
from selenium.common.exceptions import NoSuchElementException import utils.conf as conf from utils.datafile import load_data_file from utils.log import logger from utils.path import project_path from utils.update import Updateable from utils.wait import wait_for from utils.pretty import Pretty from utils.db import cfmedb from utils.varmeth import variable cfg_btn = partial(tb.select, 'Configuration') pxe_server_table_exist = Table('//div[@id="records_div"]/table/tbody/tr/td') pxe_details_page = Region(locators=dict( last_refreshed=InfoBlock("Basic Information", "Last Refreshed On"), pxe_image_type=InfoBlock("Basic Information", "Type"))) pxe_properties_form = Form(fields=[ ('name_text', Input('name')), ('log_protocol', Select("//select[@id='log_protocol']")), ('uri_text', Input('uri')), ('userid_text', Input('log_userid')), ('password_text', Input('log_password')), ('verify_text', Input('log_verify')), ('validate_btn', "//a[@id='val']"), ('access_url_text', Input('access_url')), ('pxe_dir_text', Input('pxe_directory')), ('windows_dir_text', Input('windows_images_directory')), ('customize_dir_text', Input('customization_directory')), ('pxe_menu_text', Input('pxemenu_0')),
def test_drift_analysis(request, provider, instance, soft_assert): """ Tests drift analysis is correct Metadata: test_flag: vm_analysis """ instance.load_details() drift_num_orig = 0 drift_orig = InfoBlock("Relationships", "Drift History").text if drift_orig != 'None': drift_num_orig = int(drift_orig) instance.smartstate_scan() wait_for(lambda: is_vm_analysis_finished(instance.name), delay=15, timeout="35m", fail_func=lambda: toolbar.select('Reload')) instance.load_details() wait_for(lambda: int(InfoBlock("Relationships", "Drift History").text) == drift_num_orig + 1, delay=20, num_sec=120, message="Waiting for Drift History count to increase", fail_func=sel.refresh) drift_new = int(InfoBlock("Relationships", "Drift History").text) # add a tag and a finalizer to remove it instance.add_tag('Department', 'Accounting') request.addfinalizer( lambda: instance.remove_tag('Department', 'Accounting')) instance.smartstate_scan() wait_for(lambda: is_vm_analysis_finished(instance.name), delay=15, timeout="35m", fail_func=lambda: toolbar.select('Reload')) instance.load_details() wait_for(lambda: int(InfoBlock("Relationships", "Drift History").text) == drift_new + 1, delay=20, num_sec=120, message="Waiting for Drift History count to increase", fail_func=sel.refresh) # check drift difference soft_assert( not instance.equal_drift_results('Department (1)', 'My Company Tags', 0, 1), "Drift analysis results are equal when they shouldn't be") # Test UI features that modify the drift grid d_grid = DriftGrid() # Accounting tag should not be displayed, because it was changed to True toolbar.select("Attributes with same values") with error.expected(sel.NoSuchElementException): d_grid.get_cell('Accounting', 0) # Accounting tag should be displayed now toolbar.select("Attributes with different values") d_grid.get_cell('Accounting', 0)
def test_ssa_vm(provider, instance, soft_assert): """ Tests SSA can be performed and returns sane results Metadata: test_flag: vm_analysis """ # TODO: check if previously scanned? # delete the vm itself if it did have a scan already # delete all previous scan tasks e_users = None e_groups = None e_packages = None e_services = None e_icon_part = instance.system_type['icon'] if instance.system_type != WINDOWS: e_users = instance.ssh.run_command( "cat /etc/passwd | wc -l").output.strip('\n') e_groups = instance.ssh.run_command( "cat /etc/group | wc -l").output.strip('\n') e_packages = instance.ssh.run_command( instance.system_type['package-number']).output.strip('\n') e_services = instance.ssh.run_command( instance.system_type['services-number']).output.strip('\n') logger.info( "Expecting to have {} users, {} groups, {} packages and {} services". format(e_users, e_groups, e_packages, e_services)) instance.smartstate_scan() wait_for(lambda: is_vm_analysis_finished(instance.name), delay=15, timeout="35m", fail_func=lambda: toolbar.select('Reload')) # Check release and quadricon quadicon_os_icon = instance.find_quadicon().data['os'] details_os_icon = instance.get_detail(properties=('Properties', 'Operating System'), icon_href=True) logger.info("Icons: %s, %s", details_os_icon, quadicon_os_icon) # We shouldn't use get_detail anymore - it takes too much time c_lastanalyzed = InfoBlock.text('Lifecycle', 'Last Analyzed') c_users = InfoBlock.text('Security', 'Users') c_groups = InfoBlock.text('Security', 'Groups') c_packages = 0 c_services = 0 if instance.system_type != WINDOWS: c_packages = InfoBlock.text('Configuration', 'Packages') c_services = InfoBlock.text('Configuration', 'Init Processes') logger.info( "SSA shows {} users, {} groups {} packages and {} services".format( c_users, c_groups, c_packages, c_services)) soft_assert(c_lastanalyzed != 'Never', "Last Analyzed is set to Never") soft_assert( e_icon_part in details_os_icon, "details icon: '{}' not in '{}'".format(e_icon_part, details_os_icon)) soft_assert( e_icon_part in quadicon_os_icon, "quad icon: '{}' not in '{}'".format(e_icon_part, details_os_icon)) if instance.system_type != WINDOWS: soft_assert(c_users == e_users, "users: '{}' != '{}'".format(c_users, e_users)) soft_assert(c_groups == e_groups, "groups: '{}' != '{}'".format(c_groups, e_groups)) soft_assert(c_packages == e_packages, "packages: '{}' != '{}'".format(c_packages, e_packages)) soft_assert(c_services == e_services, "services: '{}' != '{}'".format(c_services, e_services)) else: # Make sure windows-specific data is not empty c_patches = InfoBlock.text('Security', 'Patches') c_applications = InfoBlock.text('Configuration', 'Applications') c_win32_services = InfoBlock.text('Configuration', 'Win32 Services') c_kernel_drivers = InfoBlock.text('Configuration', 'Kernel Drivers') c_fs_drivers = InfoBlock.text('Configuration', 'File System Drivers') soft_assert(c_patches != '0', "patches: '{}' != '0'".format(c_patches)) soft_assert(c_applications != '0', "applications: '{}' != '0'".format(c_applications)) soft_assert(c_win32_services != '0', "win32 services: '{}' != '0'".format(c_win32_services)) soft_assert(c_kernel_drivers != '0', "kernel drivers: '{}' != '0'".format(c_kernel_drivers)) soft_assert(c_fs_drivers != '0', "fs drivers: '{}' != '0'".format(c_fs_drivers))
'containers_provider_edit': lambda _: cfg_btn('Edit Selected Containers Provider'), 'containers_provider_edit_tags': lambda _: pol_btn('Edit Tags') } ], 'containers_provider_detail': [ lambda ctx: sel.click(Quadicon(ctx['provider'].name, None)), { 'containers_provider_edit_detail': lambda _: cfg_btn('Edit this Containers Provider'), 'containers_provider_timelines_detail': lambda _: mon_btn('Timelines'), 'containers_provider_edit_tags_detail': lambda _: pol_btn('Edit Tags'), 'containers_provider_topology_detail': lambda _: sel.click(InfoBlock('Overview', 'Topology')) } ] }) properties_form = Form(fields=[( 'type_select', AngularSelect('server_emstype')), ( 'name_text', Input('name')), ('hostname_text', Input('hostname')), ('port_text', Input('port'))]) properties_form_56 = TabStripForm( fields=[('type_select', AngularSelect('ems_type')), ('name_text', Input('name'))], tab_fields={
def open_details(self, properties=None): """Clicks on details infoblock""" self.load_details(refresh=True) sel.click(InfoBlock(*properties))
def test_rh_registration(appliance, request, reg_method, reg_data, proxy_url, proxy_creds): """ Tests whether an appliance can be registered againt RHSM and SAT6 """ repo = reg_data.get('enable_repo') if not repo: 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, organization=reg_data.get('organization'), 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 fetch organization validate=False if reg_method != 'sat6' else True) used_repo_or_channel = InfoBlock('Red Hat Software Updates', 'Repository Name(s)').text red_hat_updates.register_appliances() # Register all request.addfinalizer(appliance.unregister) wait_for(func=red_hat_updates.is_registering, func_args=[appliance.server.name], delay=10, num_sec=100, fail_func=red_hat_updates.refresh) '''if/else added to overcome bz #1463588 these can be removed once fixed''' if reg_method == 'rhsm': wait_for(func=red_hat_updates.is_registered, handle_exception=True, func_args=[appliance.server.name], delay=40, num_sec=400, fail_func=red_hat_updates.refresh) else: # First registration with sat6 fails; we need to click it after this failure wait_for(func=red_hat_updates.is_registered, func_args=[appliance.server.name], delay=50, num_sec=1200, fail_func=red_hat_updates.register_appliances) wait_for(func=appliance.is_registration_complete, func_args=[used_repo_or_channel], delay=20, num_sec=400)
class Schedule(Updateable): """Represents a schedule in Intelligence/Reports/Schedules. Args: name: Schedule name. description: Schedule description. filter: 3-tuple with filter selection (see the UI). active: Whether is this schedule active. run: Specifies how often this schedule runs. It can be either string "Once", or a tuple, which maps to the two selects in UI ("Hourly", "Every hour")... time_zone: Specify time zone. start_date: Specify the start date. start_time: Specify the start time either as a string ("0:15") or tuple ("0", "15") send_email: If specifies, turns on e-mail sending. Can be string, or list or set. """ form = Form(fields=[ ("name", "//input[@id='name']"), ("description", "//input[@id='description']"), ("active", "//input[@id='enabled']"), ("filter", ShowingInputs( Select("//select[@id='filter_typ']"), Select("//select[@id='subfilter_typ']"), Select("//select[@id='repfilter_typ']"), min_values=3 )), ("timer", Timer()), ("send_email", "//input[@id='send_email_cb']"), ("emails", EmailSelectForm()) ]) _run_mapping = { "Once": None, "Hourly": "run_hours", "Daily": "run_days", "Weekly": "run_weekly", "Monthly": "run_months" } info_block = InfoBlock("detail") def __init__( self, name, description, filter, active=None, timer=None, send_email=None): self.name = name self.description = description self.filter = filter self.active = active self.timer = timer self.send_email = send_email @property def exists(self): schedules = cfmedb["miq_schedules"] return cfmedb.session\ .query(schedules.name)\ .filter(schedules.name == self.name)\ .count() > 0 def _fill(self, action): fill( self.form, self._create_fill_dict(), action=action ) def create(self, cancel=False): sel.force_navigate("schedule_add") self._fill(form_buttons.add if not cancel else form_buttons.cancel) flash.assert_no_errors() assert self.exists, "Schedule does not exist!" def update(self, updates): sel.force_navigate("schedule_edit", context={"schedule": self}) fill(self.form, updates, action=form_buttons.save) flash.assert_no_errors() assert self.exists, "Schedule does not exist!" def delete(self, cancel=False): sel.force_navigate("schedule", context={"schedule": self}) cfg_btn("Delete this Schedule from the Database", invokes_alert=True) sel.handle_alert(cancel) flash.assert_no_errors() assert not self.exists, "Schedule does not exist!" def table_item(self, item): """Works both up- and downstream. I think this should be incorporated into InfoBlock somehow. Currently there is the fieldset issue. """ return "//td[preceding-sibling::td[contains(@class, 'key') and .='{}']]".format(item) def queue(self, wait_for_finish=False): """Queue this schedule. Args: wait_for_finish: If True, then this function blocks until the action is finished. """ if not self.exists: self.create() sel.force_navigate("schedule", context={"schedule": self}) last_run = sel.text(self.table_item("Last Run Time")).strip() cfg_btn("Queue up this Schedule to run now") flash.assert_no_errors() if wait_for_finish: wait_for( lambda: sel.text(self.table_item("Last Run Time")).strip() != last_run, delay=2, fail_func=lambda: toolbar.select("Reload current display"), message="wait for report queue finish" ) def _create_fill_dict(self): """Handle the values, create dictionary for form""" # Simple values come fields = { "name": self.name, "description": self.description, "active": self.active, "filter": self.filter, "timer": self.timer, } # Send e-mail if self.send_email is not None: fields["send_email"] = True fields["emails"] = self.send_email return fields # Methods for all schedules @classmethod def _select_schedules(cls, schedules): """Select schedules in the table. Args: schedules: Schedules to select. Raises: :py:class:`NameError` when some of the schedules were not found. """ sel.force_navigate("schedules") failed_selections = [] for schedule in schedules: if isinstance(schedule, cls): name = schedule.name else: name = str(schedule) if not schedules_table.select_row("Name", name): failed_selections.append(name) if failed_selections: raise NameError("These schedules were not found: {}.".format( ", ".join(failed_selections) )) @classmethod def _action_on_schedules(cls, action, schedules, cancel=None): """Select schedules and perform an action on them Args: action: Action in Configuration to perform. schedules: List of schedules. cancel: If specified, the nalert is expected after clicking on action and value of the variable specifies handling behaviour. Raises: :py:class:`NameError` when some of the schedules were not found. """ cls._select_schedules(schedules) if cancel is None: cfg_btn(action) else: cfg_btn(action, invokes_alert=True) sel.handle_alert(bool(cancel)) flash.assert_no_errors() @classmethod def enable_schedules(cls, *schedules): """Select and enable specified schedules. Args: *schedules: Schedules to enable. Can be objects or strings. Raises: :py:class:`NameError` when some of the schedules were not found. """ return cls._action_on_schedules("Enable the selected Schedules", schedules) @classmethod def disable_schedules(cls, *schedules): """Select and disable specified schedules. Args: *schedules: Schedules to disable. Can be objects or strings. Raises: :py:class:`NameError` when some of the schedules were not found. """ return cls._action_on_schedules("Disable the selected Schedules", schedules) @classmethod def queue_schedules(cls, *schedules): """Select and queue specified schedules. Args: *schedules: Schedules to queue. Can be objects or strings. Raises: :py:class:`NameError` when some of the schedules were not found. """ return cls._action_on_schedules("Queue up selected Schedules to run now", schedules) @classmethod def delete_schedules(cls, *schedules, **kwargs): """Select and delete specified schedules from VMDB. Args: *schedules: Schedules to delete. Can be objects or strings. Keywords: cancel: Whether to cancel the deletion (Default: False) Raises: :py:class:`NameError` when some of the schedules were not found. """ return cls._action_on_schedules( "Delete the selected Schedules from the VMDB", schedules, kwargs.get("cancel", False) )
def step(self): sel.click(InfoBlock.element('Relationships', 'Middleware Deployments'))
def step(self): sel.click( InfoBlock.element('Relationships', 'Middleware Server Groups'))
def step(self): sel.click(InfoBlock.element('Relationships', 'Middleware Messagings'))
def step(self): navigate_to(self.obj.provider, 'Details') sel.click(InfoBlock('Relationships', 'Cloud volumes').element)
def step(self): sel.click(InfoBlock.element('Relationships', 'Middleware Datasources'))