def get_all_vms(do_not_navigate=False): """Returns list of all vms""" if not do_not_navigate: sel.force_navigate('infra_vms') vms = set([]) # This is really stupid, but I cannot come up with better getting of the attributes :( if not paginator.page_controls_exist(): for title in sel.elements(QUADICON_TITLE_LOCATOR): title_value = sel.get_attribute(title, "title") if not title_value: title_value = sel.get_attribute(title, "data-original-title") vms.add(title_value) return vms paginator.results_per_page(1000) for page in paginator.pages(): try: for page in paginator.pages(): for title in sel.elements(QUADICON_TITLE_LOCATOR): title_value = sel.get_attribute(title, "title") if not title_value: title_value = sel.get_attribute( title, "data-original-title") vms.add(title_value) except sel.NoSuchElementException: pass return vms
def get_all_vms(do_not_navigate=False): """Returns list of all vms""" if not do_not_navigate: sel.force_navigate('infra_vms') vms = set([]) # This is really stupid, but I cannot come up with better getting of the attributes :( if not paginator.page_controls_exist(): for title in sel.elements(QUADICON_TITLE_LOCATOR): title_value = sel.get_attribute(title, "title") if not title_value: title_value = sel.get_attribute(title, "data-original-title") vms.add(title_value) return vms paginator.results_per_page(1000) for page in paginator.pages(): try: for page in paginator.pages(): for title in sel.elements(QUADICON_TITLE_LOCATOR): title_value = sel.get_attribute(title, "title") if not title_value: title_value = sel.get_attribute(title, "data-original-title") vms.add(title_value) except sel.NoSuchElementException: pass return vms
def navigate_split_table(table, page_name, nav_limit, ui_worker_pid, prod_tail, soft_assert): pages = [] count = 0 if nav_limit == 0: count = -1 pages.extend( analyze_page_stat( perf_click(ui_worker_pid, prod_tail, False, sel.force_navigate, page_name), soft_assert)) # Obtain all items from Split Table item_names = [] for page in paginator.pages(): rows = table.rows() for row in rows: item_names.append(row.columns[2].text) logger.info('Discovered {} Split Table items.'.format(len(item_names))) pages.extend( analyze_page_stat( perf_click(ui_worker_pid, prod_tail, True, sel.force_navigate, page_name), soft_assert)) for item_name in item_names: logger.info('Navigating to Split Table Item: {}'.format(item_name)) page_found = False for page in paginator.pages(): cell_found = table.find_cell('name', item_name) if cell_found: page_found = True count += 1 pages.extend( analyze_page_stat( perf_click(ui_worker_pid, prod_tail, True, table.click_cell, 'name', item_name), soft_assert)) pages.extend( analyze_page_stat( perf_click(ui_worker_pid, prod_tail, True, sel.force_navigate, page_name), soft_assert)) break if not page_found: logger.error( 'Split Table Page was never found: page_name: {}, item: {}'. format(page_name, item_name)) # If nav_limit == 0 every item is navigated to if not nav_limit == 0 and count >= nav_limit: break return pages
def wait_for_request(cells, partial_check=False): """helper function checks if a request is complete After finding the request's row using the ``cells`` argument, this will wait for a request to reach the 'Finished' state and return it. In the event of an 'Error' state, it will raise an AssertionError, for use with ``pytest.raises``, if desired. Args: cells: A dict of cells use to identify the request row to inspect in the :py:attr:`request_list` Table. See :py:meth:`cfme.web_ui.Table.find_rows_by_cells` for more. Usage: # Filter on the "Description" column description = 'Provision from [%s] to [%s]' % (template_name, vm_name) cells = {'Description': description} # Filter on the "Request ID" column # Text must match exactly, you can use "{:,}".format(request_id) to add commas if needed. request_id = '{:,}'.format(1000000000001) # Becomes '1,000,000,000,001', as in the table cells = {'Request ID': request_id} # However you construct the cells dict, pass it to wait_for_request # Provisioning requests often take more than 5 minutes but less than 10. wait_for(wait_for_request, [cells], num_sec=600) Raises: AssertionError: if the matched request has status 'Error' RequestException: if multiple matching requests were found Returns: The matching :py:class:`cfme.web_ui.Table.Row` if found, ``False`` otherwise. """ for page in paginator.pages(): if sel.elements(request_list._header_loc) and not sel.is_displayed(request_list): # The table exists but it is hidden - no cells return False results = request_list.find_rows_by_cells(cells, partial_check) if len(results) == 0: # row not on this page, assume it has yet to appear continue elif len(results) > 1: raise RequestException( 'Multiple requests with matching content found - be more specific!' ) else: # found the row! row = results[0] logger.debug(' Request Message: %s' % row.last_message.text) break else: # Request not found at all, can't continue return False assert row.status.text != 'Error' if row.request_state.text == 'Finished': return row else: return False
def exists(self): sel.force_navigate('infrastructure_hosts') for page in paginator.pages(): if sel.is_displayed(Quadicon(self.name, 'host')): return True else: return False
def exists(self): sel.force_navigate('infrastructure_providers') for page in paginator.pages(): if sel.is_displayed(Quadicon(self.name, 'infra_prov')): return True else: return False
def find_request(cells, partial_check=False): """Finds the request and returns the row element Args: cells: Search data for the requests table. partial_check: If to use the ``in`` operator rather than ``==`` in find_rows_by_cells(). Returns: row """ navigate_to(Request, 'All') from cfme.web_ui import paginator for page in paginator.pages(): results = fields.request_list.find_rows_by_cells(cells, partial_check) if len(results) == 0: # row not on this page, assume it has yet to appear # it might be nice to add an option to fail at this point continue elif len(results) > 1: raise RequestException( 'Multiple requests with matching content found - be more specific!' ) else: # found the row! row = results[0] logger.debug(' Request Message: %s', row.last_message.text) return row else: # Request not found at all, can't continue return False
def test_perf_ui_infra_resource_pools(ui_worker_pid, soft_assert): pages, prod_tail = standup_perf_ui(ui_worker_pid, soft_assert) nav_limit = 0 if 'resource_pools' in perf_tests['ui']['page_check']['infrastructure']: nav_limit = perf_tests['ui']['page_check']['infrastructure'][ 'resource_pools'] pages.extend( analyze_page_stat( perf_click(ui_worker_pid, prod_tail, True, sel.force_navigate, 'infrastructure_resource_pools'), soft_assert)) resource_pools = set([]) for page in paginator.pages(): for title in sel.elements( "//div[@id='quadicon']/../../../tr/td/a[contains(@href," "'resource_pool/show')]"): resource_pools.add(sel.get_attribute(title, "title")) acc_bars = ['Properties', 'Relationships'] pages.extend( navigate_quadicons(resource_pools, 'resource_pool', 'infrastructure_resource_pools', nav_limit, ui_worker_pid, prod_tail, soft_assert, acc_bars)) pages_to_csv(pages, 'perf_ui_infra_resource_pools.csv') pages_to_statistics_csv(pages, resource_pool_filters, 'ui-statistics.csv')
def _repo_row(name): for page in pages(): row = repo_list.find_row('Name', name) if row: return row else: raise Exception('row not found for repo {}'.format(name))
def find_quadicon( self, do_not_navigate=False, mark=False, refresh=True, from_any_provider=False): """Find and return a quadicon belonging to a specific instance Args: from_any_provider: Whether to look for it anywhere (root of the tree). Useful when looking up archived or orphaned VMs Returns: :py:class:`cfme.web_ui.Quadicon` instance Raises: InstanceNotFound """ if not do_not_navigate: if from_any_provider: sel.force_navigate("clouds_instances") elif not self.provider_crud.load_all_provider_instances(): raise InstanceNotFound("No instances for the provider!") toolbar.set_vms_grid_view() elif refresh: sel.refresh() if not paginator.page_controls_exist(): raise InstanceNotFound("Instance '{}' not found in UI!".format(self.name)) paginator.results_per_page(1000) for page in paginator.pages(): quadicon = Quadicon(self.name, "instance") if sel.is_displayed(quadicon): if mark: sel.check(quadicon.checkbox()) return quadicon else: raise InstanceNotFound("Instance '{}' not found in UI!".format(self.name))
def data(self): """Retrieves data from the saved report. Returns: :py:class:`SavedReportData` if it is not a candu report. If it is, then it returns a list of groups in the table. """ navigate_to(self, "Details") if isinstance(self._table, CAndUGroupTable): return list(self._table.groups()) try: headers = tuple( [sel.text(hdr).encode("utf-8") for hdr in self._table.headers]) body = [] for page in paginator.pages(): for row in self._table.rows(): row_data = tuple([ sel.text(row[header]).encode("utf-8") for header in headers ]) body.append(row_data) except sel.NoSuchElementException: # No data found return SavedReportData([], []) else: return SavedReportData(headers, body)
def exists(self): navigate_to(self, 'All') for page in paginator.pages(): if sel.is_displayed(Quadicon(self.name, 'host')): return True else: return False
def test_paginator(some_dialogs, soft_assert): """ This test tests weird behaviour of the paginator in Service dialogs. Prerequisities: * There have to be couple of service dialogs, about 16 is recommended. Steps: * Go to service dialogs page * Set the paginator to 50 results per page, then to 5 results per page. * Assert there are 5 rows displayed in the table * Then cycle through the pages. Note all the dialogs you see, in the end the list of all dialogs must contain all idalogs you created before. * During the cycling, assert the numbers displayed in the paginator make sense * During the cycling, assert the paginator does not get stuck. """ pytest.sel.force_navigate("service_dialogs") paginator.results_per_page(50) paginator.results_per_page(5) # Now we must have only 5 soft_assert(len(list(common.dialogs_table.rows())) == 5, "Changing number of rows failed!") # try to browse current_rec_offset = None dialogs_found = set() for page in paginator.pages(): if paginator.rec_offset() == current_rec_offset: soft_assert(False, "Paginator is locked, it does not advance to next page") break if current_rec_offset is None: current_rec_offset = paginator.rec_offset() for text in get_relevant_rows(common.dialogs_table): dialogs_found.add(text) current_rec_offset = paginator.rec_offset() assert set([dlg.label for dlg in some_dialogs]) <= dialogs_found, \ "Could not find all dialogs by clicking the paginator!"
def exists(self): sel.force_navigate('clouds_providers') for page in paginator.pages(): if sel.is_displayed(Quadicon(self.name, 'cloud_prov')): return True else: return False
def _get_tasks(tab_destination, **filter_kwargs): """ Generic function to return contents of the tasks table Args: location: Location for :py:module:`ui_navigate` where to get the data. **filter_kwargs: See :py:meth:`_filter` Returns: List of dicts. """ navigate_to(Tasks, tab_destination) if any([filter_kwargs[key] is not None for key in filter_kwargs.keys()]): _filter(**filter_kwargs) tasks = [] if sel.is_displayed(tasks_table): for page in paginator.pages(): for row in tasks_table.rows(): tasks.append( dict( updated=parsetime.from_american_with_utc( row.updated.text.encode('utf-8').strip() ), started=parsetime.from_american_with_utc( row.started.text.encode('utf-8').strip() ), state=row.state.text.encode('utf-8').strip(), message=row.message.text.encode('utf-8').strip(), task_name=row.task_name.text.encode('utf-8').strip(), user=row.user.text.encode('utf-8').strip() ) ) else: logger.info('No Tasks collected on {}'.format(tab_destination)) return tasks
def find_request(cells, partial_check=False): """Finds the request and returns the row element Args: cells: Search data for the requests table. partial_check: If to use the ``in`` operator rather than ``==`` in find_rows_by_cells(). Returns: row """ navigate_to(Request, 'All') for page in paginator.pages(): results = fields.request_list.find_rows_by_cells(cells, partial_check) if len(results) == 0: # row not on this page, assume it has yet to appear # it might be nice to add an option to fail at this point continue elif len(results) > 1: raise RequestException( 'Multiple requests with matching content found - be more specific!' ) else: # found the row! row = results[0] logger.debug(' Request Message: %s', row.last_message.text) return row else: # Request not found at all, can't continue return False
def find_request(self, cells, partial_check=False): """Finds the request and returns the row element Args: cells: Search data for the requests table. partial_check: If to use the ``__contains`` operator Returns: row """ contains = '' if not partial_check else '__contains' column_list = self.table.attributized_headers cells = copy(cells) for key in cells.keys(): for column_name, column_text in column_list.items(): if key == column_text: cells['{}{}'.format(column_name, contains)] = cells.pop(key) break # TODO Replace Paginator with paginator_pane after 1450002 gets resolved from cfme.web_ui import paginator for page in paginator.pages(): rows = list(self.table.rows(**cells)) if len(rows) == 0: # row not on this page, assume it has yet to appear # it might be nice to add an option to fail at this point continue elif len(rows) > 1: raise RequestException( 'Multiple requests with matching content found - be more specific!') else: # found the row! row = rows[0] logger.debug(' Request Message: %s', row.last_message.text) return row else: raise Exception("The requst specified by {} not found!".format(str(cells)))
def _find_quadicon(self, is_vm=True, do_not_navigate=False, mark=False, refresh=True): """Find and return a quadicon belonging to a specific vm Returns: :py:class:`cfme.web_ui.Quadicon` instance Raises: VmNotFound """ quadicon = Quadicon(self.name, "vm") if not do_not_navigate: if is_vm: self.provider_crud.load_all_provider_vms() else: self.provider_crud.load_all_provider_templates() toolbar.set_vms_grid_view() elif refresh: sel.refresh() if not paginator.page_controls_exist(): if is_vm: raise VmNotFound("VM '{}' not found in UI!".format(self.name)) else: raise TemplateNotFound("Template '{}' not found in UI!".format(self.name)) paginator.results_per_page(1000) for page in paginator.pages(): if sel.is_displayed(quadicon): if mark: sel.check(quadicon.checkbox()) return quadicon else: raise VmNotFound("VM '{}' not found in UI!".format(self.name))
def _setup_providers(cloud_or_infra, validate, check_existing): """Helper to set up all cloud or infra providers, and then validate them Args: cloud_or_infra: Like the name says: 'cloud' or 'infra' (a string) validate: see description in :py:func:`setup_provider` check_existing: see description in :py:func:`setup_provider` Returns: A list of provider objects that have been created. """ # Pivot behavior on cloud_or_infra options_map = { 'cloud': { 'navigate': 'clouds_providers', 'quad': 'cloud_prov', 'list': list_cloud_providers }, 'infra': { 'navigate': 'infrastructure_providers', 'quad': 'infra_prov', 'list': list_infra_providers } } # Check for existing providers all at once, to prevent reloading # the providers page for every provider in cfme_data if not options_map[cloud_or_infra]['list'](): return [] if check_existing: sel.force_navigate(options_map[cloud_or_infra]['navigate']) add_providers = [] for provider_key in options_map[cloud_or_infra]['list'](): provider_name = conf.cfme_data.get('management_systems', {})[provider_key]['name'] quad = Quadicon(provider_name, options_map[cloud_or_infra]['quad']) for page in paginator.pages(): if sel.is_displayed(quad): logger.debug('Provider "%s" exists, skipping' % provider_key) break else: add_providers.append(provider_key) else: # Add all cloud or infra providers unconditionally add_providers = options_map[cloud_or_infra]['list']() if add_providers: logger.info('Providers to be added: %s' % ', '.join(add_providers)) # Save the provider objects for validation and return added_providers = [] for provider_name in add_providers: # Don't validate in this step; add all providers, then go back and validate in order provider = setup_provider(provider_name, validate=False, check_existing=False) added_providers.append(provider) if validate: map(methodcaller('validate'), added_providers) return added_providers
def get_all_vms(do_not_navigate=False): """Returns list of all vms""" if not do_not_navigate: sel.force_navigate('infra_vms') vms = set([]) if not paginator.page_controls_exist(): return vms paginator.results_per_page(1000) for page in paginator.pages(): try: for page in paginator.pages(): for title in sel.elements(QUADICON_TITLE_LOCATOR): vms.add(sel.get_attribute(title, "title")) except sel.NoSuchElementException: pass return vms
def find_quadicon(self, do_not_navigate=False, mark=False, refresh=True, from_any_provider=False, use_search=True): """Find and return a quadicon belonging to a specific vm Args: from_any_provider: Whether to look for it anywhere (root of the tree). Useful when looking up archived or orphaned VMs Returns: :py:class:`cfme.web_ui.Quadicon` instance Raises: VmOrInstanceNotFound """ quadicon = Quadicon(self.name, self.quadicon_type) if not do_not_navigate: if from_any_provider: # TODO implement as navigate_to when cfme.infra.virtual_machines has destination navigate_to(self, 'All') elif self.is_vm: navigate_to(self, 'AllForProvider', use_resetter=False) else: navigate_to(self, 'AllForProvider', use_resetter=False) toolbar.select('Grid View') else: # Search requires navigation, we shouldn't use it then use_search = False if refresh: sel.refresh() if not paginator.page_controls_exist(): if self.is_vm: raise VmOrInstanceNotFound("VM '{}' not found in UI!".format( self.name)) else: raise TemplateNotFound("Template '{}' not found in UI!".format( self.name)) paginator.results_per_page(1000) if use_search: try: if not search.has_quick_search_box(): # TODO rework search for archived/orphaned VMs if self.is_vm: navigate_to(self, 'AllForProvider', use_resetter=False) else: navigate_to(self, 'AllForProvider', use_resetter=False) search.normal_search(self.name) except Exception as e: logger.warning("Failed to use search: %s", str(e)) for page in paginator.pages(): if sel.is_displayed(quadicon, move_to=True): if mark: sel.check(quadicon.checkbox()) return quadicon else: raise VmOrInstanceNotFound("VM '{}' not found in UI!".format( self.name))
def request_by_id(self, request_id): """Loop over request pages and return the request with matching id or None if that request isn't found. """ for page in paginator.pages(): for request_item in self.request_items: if request_item.request_id == request_id: return request_item
def _setup_providers(prov_class, validate, check_existing): """Helper to set up all cloud, infra or container providers, and then validate them Args: prov_class: Provider class - 'cloud, 'infra', 'container' or 'middleware' (a string) validate: see description in :py:func:`setup_provider` check_existing: see description in :py:func:`setup_provider` Returns: A list of provider objects that have been created. """ # Check for existing providers all at once, to prevent reloading # the providers page for every provider in cfme_data if not list_providers(BaseProvider.type_mapping[prov_class]): return [] if check_existing: navigate = "{}_providers".format( BaseProvider.type_mapping[prov_class].values()[0].page_name) sel.force_navigate(navigate) add_providers = [] for provider_key in list_providers( BaseProvider.type_mapping[prov_class].keys()): provider_name = conf.cfme_data.get('management_systems', {})[provider_key]['name'] quad_name = BaseProvider.type_mapping[prov_class].values( )[0].quad_name quad = Quadicon(provider_name, quad_name) for page in paginator.pages(): if sel.is_displayed(quad): logger.debug('Provider %s exists, skipping', provider_key) break else: add_providers.append(provider_key) else: # Add all cloud, infra or container providers unconditionally add_providers = list_providers( BaseProvider.type_mapping[prov_class].keys()) if add_providers: logger.info('Providers to be added: %s', ', '.join(add_providers)) # Save the provider objects for validation and return added_providers = [] for provider_name in add_providers: # Don't validate in this step; add all providers, then go back and validate in order provider = setup_provider(provider_name, validate=False, check_existing=False) added_providers.append(provider) if validate: map(methodcaller('validate'), added_providers) return added_providers
def wait_for_request(cells): """helper function checks if a request is complete After finding the request's row using the ``cells`` argument, this will wait for a request to reach the 'Finished' state and return it. In the event of an 'Error' state, it will raise an AssertionError, for use with ``pytest.raises``, if desired. Args: cells: A dict of cells use to identify the request row to inspect in the :py:attr:`request_list` Table. See :py:meth:`cfme.web_ui.Table.find_rows_by_cells` for more. Usage: # Filter on the "Description" column description = 'Provision from [%s] to [%s]' % (template_name, vm_name) cells = {'Description': description} # Filter on the "Request ID" column # Text must match exactly, you can use "{:,}".format(request_id) to add commas if needed. request_id = '{:,}'.format(1000000000001) # Becomes '1,000,000,000,001', as in the table cells = {'Request ID': request_id} # However you construct the cells dict, pass it to wait_for_request # Provisioning requests often take more than 5 minutes but less than 10. wait_for(wait_for_request, [cells], num_sec=600) Raises: AssertionError: if the matched request has status 'Error' RequestException: if multiple matching requests were found Returns: The matching :py:class:`cfme.web_ui.Table.Row` if found, ``False`` otherwise. """ for page in paginator.pages(): results = request_list.find_rows_by_cells(cells) if len(results) == 0: # row not on this page, assume it has yet to appear continue elif len(results) > 1: raise RequestException( 'Multiple requests with matching content found - be more specific!' ) else: # found the row! row = results[0] logger.debug(' Request Message: %s' % row.last_message.text) break else: # Request not found at all, can't continue return False assert row.status.text != 'Error' if row.request_state.text == 'Finished': return row else: return False
def get_all_hosts(do_not_navigate=False): """Returns list of all hosts""" if not do_not_navigate: navigate_to(Host, 'All') hosts = set([]) for page in paginator.pages(): for title in sel.elements( "//div[@id='quadicon']/../../../tr/td/a[contains(@href,'host/show')]"): hosts.add(sel.get_attribute(title, "title")) return hosts
def get_all_hosts(do_not_navigate=False): """Returns list of all hosts""" if not do_not_navigate: sel.force_navigate('infrastructure_hosts') hosts = set([]) for page in paginator.pages(): for title in sel.elements( "//div[@id='quadicon']/../../../tr/td/a[contains(@href,'host/show')]"): hosts.add(sel.get_attribute(title, "title")) return hosts
def datasources(cls, provider=None, server=None): datasources = [] _get_datasources_page(provider=provider, server=server) if sel.is_displayed(list_tbl): for _ in paginator.pages(): for row in list_tbl.rows(): _server = MiddlewareServer(provider=provider, name=row.server.text) datasources.append(MiddlewareDatasource(name=row.datasource_name.text, server=_server)) return datasources
def datasources(cls, provider=None, server=None): datasources = [] _get_datasources_page(provider=provider, server=server) if sel.is_displayed(list_tbl): for _ in paginator.pages(): for row in list_tbl.rows(): _server = MiddlewareServer(provider=provider, name=row.server.text) datasources.append(MiddlewareDatasource(provider=provider, server=_server, name=row.datasource_name.text)) return datasources
def get_all_clusters(do_not_navigate=False): """Returns list of all clusters""" if not do_not_navigate: sel.force_navigate('infrastructure_clusters') clusters = set([]) for page in paginator.pages(): for title in sel.elements( "//div[@id='quadicon']/../../../tr/td/a[contains(@href,'cluster/show')]"): clusters.add(sel.get_attribute(title, "title")) return clusters
def find_quadicon( self, do_not_navigate=False, mark=False, refresh=True, from_any_provider=False, use_search=True): """Find and return a quadicon belonging to a specific vm Args: from_any_provider: Whether to look for it anywhere (root of the tree). Useful when looking up archived or orphaned VMs Returns: :py:class:`cfme.web_ui.Quadicon` instance Raises: VmOrInstanceNotFound """ quadicon = Quadicon(self.name, self.quadicon_type) if not do_not_navigate: if from_any_provider: # TODO implement as navigate_to when cfme.infra.virtual_machines has destination sel.force_navigate(self.ALL_LIST_LOCATION) elif self.is_vm: self.provider.load_all_provider_vms() else: self.provider.load_all_provider_templates() toolbar.select('Grid View') else: # Search requires navigation, we shouldn't use it then use_search = False if refresh: sel.refresh() if not paginator.page_controls_exist(): if self.is_vm: raise VmOrInstanceNotFound("VM '{}' not found in UI!".format(self.name)) else: raise TemplateNotFound("Template '{}' not found in UI!".format(self.name)) # this is causing some issues in 5.5.0.9, commenting out for a bit # paginator.results_per_page(1000) if use_search: try: if not search.has_quick_search_box(): # We don't use provider-specific page (vm_templates_provider_branch) here # as those don't list archived/orphaned VMs if self.is_vm: navigate_to(self.provider, 'Instances') else: navigate_to(self.provider, self.provider.templates_destination_name) search.normal_search(self.name) except Exception as e: logger.warning("Failed to use search: %s", str(e)) for page in paginator.pages(): if sel.is_displayed(quadicon, move_to=True): if mark: sel.check(quadicon.checkbox()) return quadicon else: raise VmOrInstanceNotFound("VM '{}' not found in UI!".format(self.name))
def deployments(cls, provider=None, server=None): deployments = [] _get_deployments_page(provider=provider, server=server) if sel.is_displayed(list_tbl): _provider = provider # In deployment UI, we cannot get provider name on list all page for _ in paginator.pages(): for row in list_tbl.rows(): _server = MiddlewareServer(provider=provider, name=row.server.text) deployments.append(MiddlewareDeployment(provider=_provider, server=_server, name=row.deployment_name.text)) return deployments
def _find_and_click_sm(context): """Incorporates searching through the page listing and clicking in the table. Also ensures waiting for the transition as there is no ajax hook.""" sm_name = _get_sm_name(context["storage_manager"]) for page in paginator.pages(): if sel.is_displayed("#no_records_div"): break if list_page.managers_table.click_cell("name", sm_name): sel.wait_for_element("#textual_div") # No ajax wait there :( return raise StorageManagerNotFound("Storage manager with name '{}' not found!".format(sm_name))
def get_datastores(self): """ Gets list of all datastores used by this host""" sel.force_navigate('infrastructure_host', context={'host': self}) list_acc.select('Relationships', 'Datastores', by_title=False, partial=True) datastores = set([]) for page in paginator.pages(): for title in sel.elements( "//div[@id='quadicon']/../../../tr/td/a[contains(@href,'storage/show')]"): datastores.add(sel.get_attribute(title, "title")) return datastores
def get_datastores(self): """ Gets list of all datastores used by this host""" sel.force_navigate('infrastructure_host', context={'host': self}) list_acc.select('Relationships', 'Show all Datastores') datastores = set([]) for page in paginator.pages(): for title in sel.elements( "//div[@id='quadicon']/../../../tr/td/a[contains(@href,'storage/show')]"): datastores.add(sel.get_attribute(title, "title")) return datastores
def find_quadicon( self, do_not_navigate=False, mark=False, refresh=True, from_any_provider=False, use_search=True): """Find and return a quadicon belonging to a specific vm Args: from_any_provider: Whether to look for it anywhere (root of the tree). Useful when looking up archived or orphaned VMs Returns: :py:class:`cfme.web_ui.Quadicon` instance Raises: VmOrInstanceNotFound """ quadicon = Quadicon(self.name, self.quadicon_type) if not do_not_navigate: if from_any_provider: sel.force_navigate(self.ALL_LIST_LOCATION) elif self.is_vm: self.provider.load_all_provider_vms() else: self.provider.load_all_provider_templates() toolbar.select('Grid View') else: # Search requires navigation, we shouldn't use it then use_search = False if refresh: sel.refresh() if not paginator.page_controls_exist(): if self.is_vm: raise VmOrInstanceNotFound("VM '{}' not found in UI!".format(self.name)) else: raise TemplateNotFound("Template '{}' not found in UI!".format(self.name)) # this is causing some issues in 5.5.0.9, commenting out for a bit # paginator.results_per_page(1000) if use_search: try: if not search.has_quick_search_box(): # We don't use provider-specific page (vm_templates_provider_branch) here # as those don't list archived/orphaned VMs if self.is_vm: sel.force_navigate(self.provider.instances_page_name) else: sel.force_navigate(self.provider.templates_page_name) search.normal_search(self.name) except Exception as e: logger.warning("Failed to use search: %s", str(e)) for page in paginator.pages(): if sel.is_displayed(quadicon, move_to=True): if mark: sel.check(quadicon.checkbox()) return quadicon else: raise VmOrInstanceNotFound("VM '{}' not found in UI!".format(self.name))
def get_all_providers(do_not_navigate=False): """Returns list of all providers""" if not do_not_navigate: sel.force_navigate('clouds_providers') providers = set([]) link_marker = "ems_cloud" for page in paginator.pages(): for title in sel.elements("//div[@id='quadicon']/../../../tr/td/a[contains(@href," "'{}/show')]".format(link_marker)): providers.add(sel.get_attribute(title, "title")) return providers
def get_all_providers(do_not_navigate=False): """Returns list of all providers""" if not do_not_navigate: navigate_to(CloudProvider, 'All') providers = set([]) link_marker = "ems_cloud" for page in paginator.pages(): for title in sel.elements("//div[@id='quadicon']/../../../tr/td/a[contains(@href," "'{}/show')]".format(link_marker)): providers.add(sel.get_attribute(title, "title")) return providers
def get_all_providers(do_not_navigate=False): """Returns list of all providers""" if not do_not_navigate: sel.force_navigate("clouds_providers") providers = set([]) link_marker = version.pick({version.LOWEST: "ext_management_system", "5.2.5": "ems_cloud"}) for page in paginator.pages(): for title in sel.elements( "//div[@id='quadicon']/../../../tr/td/a[contains(@href," "'{}/show')]".format(link_marker) ): providers.add(sel.get_attribute(title, "title")) return providers
def _setup_providers(prov_class, validate, check_existing): """Helper to set up all cloud, infra or container providers, and then validate them Args: prov_class: Provider class - 'cloud, 'infra', 'container' or 'middleware' (a string) validate: see description in :py:func:`setup_provider` check_existing: see description in :py:func:`setup_provider` Returns: A list of provider objects that have been created. """ # Check for existing providers all at once, to prevent reloading # the providers page for every provider in cfme_data if not list_providers(BaseProvider.type_mapping[prov_class].provider_types.keys()): return [] if check_existing: navigate = "{}_providers".format( BaseProvider.type_mapping[prov_class].page_name) sel.force_navigate(navigate) add_providers = [] for provider_key in list_providers( BaseProvider.type_mapping[prov_class].provider_types.keys()): provider_name = conf.cfme_data.get('management_systems', {})[provider_key]['name'] quad_name = BaseProvider.type_mapping[prov_class].quad_name quad = Quadicon(provider_name, quad_name) for page in paginator.pages(): if sel.is_displayed(quad): logger.debug('Provider %s exists, skipping', provider_key) break else: add_providers.append(provider_key) else: # Add all cloud, infra or container providers unconditionally add_providers = list_providers(BaseProvider.type_mapping[prov_class].provider_types.keys()) if add_providers: logger.info('Providers to be added: %s', ', '.join(add_providers)) # Save the provider objects for validation and return added_providers = [] for provider_name in add_providers: # Don't validate in this step; add all providers, then go back and validate in order provider = setup_provider(provider_name, validate=False, check_existing=False) added_providers.append(provider) if validate: for provider in added_providers: provider.validate() return added_providers
def get_saved_canned_reports(self, *path): navigate_to(self, "Saved") results = [] try: for page in paginator.pages(): for row in records_table.rows(): results.append( CannedSavedReport(path, sel.text(row.run_at).encode("utf-8")) ) except sel.NoSuchElementException: pass return results
def get_saved_canned_reports(*path): sel.force_navigate("report_canned_saved", context={"path": path}) results = [] try: for page in paginator.pages(): for row in records_table.rows(): results.append( CannedSavedReport(path, sel.text(row.run_at).encode("utf-8")) ) except sel.NoSuchElementException: pass return results
def _setup_providers(prov_class, validate, check_existing): """Helper to set up all cloud, infra or container providers, and then validate them Args: prov_class: Provider class - 'cloud, 'infra' or 'container' (a string) validate: see description in :py:func:`setup_provider` check_existing: see description in :py:func:`setup_provider` Returns: A list of provider objects that have been created. """ # Pivot behavior on prov_class options_map = { "cloud": {"navigate": "clouds_providers", "quad": "cloud_prov", "list": list_cloud_providers}, "infra": {"navigate": "infrastructure_providers", "quad": "infra_prov", "list": list_infra_providers}, "container": {"navigate": "containers_providers", "quad": None, "list": list_container_providers}, } # Check for existing providers all at once, to prevent reloading # the providers page for every provider in cfme_data if not options_map[prov_class]["list"](): return [] if check_existing: sel.force_navigate(options_map[prov_class]["navigate"]) add_providers = [] for provider_key in options_map[prov_class]["list"](): provider_name = conf.cfme_data.get("management_systems", {})[provider_key]["name"] quad = Quadicon(provider_name, options_map[prov_class]["quad"]) for page in paginator.pages(): if sel.is_displayed(quad): logger.debug('Provider "%s" exists, skipping' % provider_key) break else: add_providers.append(provider_key) else: # Add all cloud, infra or container providers unconditionally add_providers = options_map[prov_class]["list"]() if add_providers: logger.info("Providers to be added: %s" % ", ".join(add_providers)) # Save the provider objects for validation and return added_providers = [] for provider_name in add_providers: # Don't validate in this step; add all providers, then go back and validate in order provider = setup_provider(provider_name, validate=False, check_existing=False) added_providers.append(provider) if validate: map(methodcaller("validate"), added_providers) return added_providers
def find_quadicon(self): """Find and return the quadicon belonging to this stack Args: Returns: :py:class:`cfme.web_ui.Quadicon` instance """ for page in paginator.pages(): quadicon = Quadicon(self.name, self.quad_name) if sel.is_displayed(quadicon): return quadicon else: raise StackNotFound("Stack '{}' not found in UI!".format(self.name))
def get_saved_reports(self): sel.force_navigate("report_custom_saved", context={"report": self}) results = [] try: for page in paginator.pages(): for row in records_table.rows(): results.append( CustomSavedReport(self, sel.text(row.run_at).encode("utf-8")) ) except sel.NoSuchElementException: pass return results
def navigate_split_table(table, page_name, nav_limit, ui_worker_pid, prod_tail, soft_assert): pages = [] count = 0 if nav_limit == 0: count = -1 pages.extend(analyze_page_stat(perf_click(ui_worker_pid, prod_tail, False, sel.force_navigate, page_name), soft_assert)) # Obtain all items from Split Table item_names = [] for page in paginator.pages(): rows = table.rows() for row in rows: item_names.append(row.columns[2].text) logger.info('Discovered {} Split Table items.'.format(len(item_names))) pages.extend(analyze_page_stat(perf_click(ui_worker_pid, prod_tail, True, sel.force_navigate, page_name), soft_assert)) for item_name in item_names: logger.info('Navigating to Split Table Item: {}'.format(item_name)) page_found = False for page in paginator.pages(): cell_found = table.find_cell('name', item_name) if cell_found: page_found = True count += 1 pages.extend(analyze_page_stat(perf_click(ui_worker_pid, prod_tail, True, table.click_cell, 'name', item_name), soft_assert)) pages.extend(analyze_page_stat(perf_click(ui_worker_pid, prod_tail, True, sel.force_navigate, page_name), soft_assert)) break if not page_found: logger.error('Split Table Page was never found: page_name: {}, item: {}'.format( page_name, item_name)) # If nav_limit == 0 every item is navigated to if not nav_limit == 0 and count >= nav_limit: break return pages
def wait_for_request(cells): """helper function checks if a request is complete After finding the request's row using the ``cells`` argument, this will wait for a request to reach the 'Finished' state and return it. In the event of an 'Error' state, it will raise an AssertionError, for use with ``pytest.raises``, if desired. Args: cells: A dict of cells use to identify the request row to inspect in the :py:attr:`request_list` Table. See :py:meth:`cfme.web_ui.Table.find_rows_by_cells` for more. Usage: # Filter on the "Description" column description = 'Provision from [%s] to [%s]' % (template_name, vm_name) cells = {'Description': description} # Filter on the "Request ID" column # Text must match exactly, you can use "{:,}".format(request_id) to add commas if needed. request_id = '{:,}'.format(1000000000001) # Becomes '1,000,000,000,001', as in the table cells = {'Request ID': request_id} # However you construct the cells dict, pass it to wait_for_request # Provisioning requests often take more than 5 minutes but less than 10. wait_for(wait_for_request, [cells], num_sec=600) Raises: AssertionError: if the matched request has status 'Error' Returns: """ for page in paginator.pages(): try: # found the row! row, = request_list.find_rows_by_cells(cells) logger.debug(' Request Message: %s' % row.last_message.text) break except ValueError: # row not on this page, assume it has yet to appear # it might be nice to add an option to fail at this point continue else: # Request not found at all, can't continue return False assert row.status.text != 'Error' if row.request_state.text == 'Finished': return row else: return False
def delete(self, cancel=False, from_details=True, wait=True): if self.appliance.version < '5.7': raise OptionNotAvailable( 'Cannot delete cloud tenants in CFME < 5.7') if from_details: if cancel: raise OptionNotAvailable( 'Cannot cancel cloud tenant delete from details page') # Generates no alert or confirmation try: navigate_to(self, 'Details') except Exception as ex: # Catch general navigation exceptions and raise raise TenantNotFound( 'Exception while navigating to Tenant details: {}'.format( ex)) cfg_btn('Delete Cloud Tenant') else: # Have to select the row in the list navigate_to(self, 'All') # double check we're in List View tb.select('List View') found = False for page in paginator.pages(): try: listview_checktable.select_row_by_cells({ 'Name': self.name, 'Cloud Provider': self.provider.name }) found = True except NoSuchElementException: continue else: break if not found: raise TenantNotFound( 'Could not locate tenant for delete by selection') cfg_btn('Delete Cloud Tenants', invokes_alert=True) sel.handle_alert(cancel=cancel) if cancel: return self.exists() else: # Flash message is the same whether deleted from details or by selection result = flash.assert_success_message( 'Delete initiated for 1 Cloud Tenant.') if wait: self.provider.refresh_provider_relationships() result = self.wait_for_disappear(600) return result
def messagings(cls, provider=None, server=None): messagings = [] _get_messagings_page(provider=provider, server=server) if sel.is_displayed(list_tbl): for _ in paginator.pages(): for row in list_tbl.rows(): _server = MiddlewareServer(provider=provider, name=row.server.text) messagings.append(MiddlewareMessaging( provider=provider, server=_server, name=row.messaging_name.text, messaging_type=row.messaging_type.text)) return messagings
def get_saved_reports(self): navigate_to(self, 'Saved') results = [] try: for page in paginator.pages(): sel.wait_for_element(records_table) for row in records_table.rows(): results.append( CustomSavedReport(self, sel.text(row.run_at).encode("utf-8"), self.is_candu) ) except sel.NoSuchElementException: pass return results
def get_saved_reports(self): sel.force_navigate("report_custom_saved", context={"report": self}) results = [] try: for page in paginator.pages(): for row in records_table.rows(): results.append( CustomSavedReport(self, sel.text( row.run_at).encode("utf-8"))) except sel.NoSuchElementException: pass return results
def navigate_quadicons(q_names, q_type, page_name, nav_limit, ui_worker_pid, prod_tail, soft_assert, acc_topbars=[]): pages = [] count = 0 if nav_limit == 0: count = -1 assert len(q_names) > 0 while (count < nav_limit): for q in q_names: for page in paginator.pages(): quadicon = Quadicon(str(q), q_type) if sel.is_displayed(quadicon): pages.extend(analyze_page_stat(perf_click(ui_worker_pid, prod_tail, True, sel.click, quadicon), soft_assert)) for topbar in acc_topbars: try: if not list_acc.is_active(topbar): list_acc.click(topbar) links = list_acc.get_active_links(topbar) for link in range(len(links)): # Every click makes the previous list of links invalid links = list_acc.get_active_links(topbar) if link <= len(links): # Do not navigate to any link containing: dnn = ['parent', 'Capacity & Utilization', 'Timelines', 'Show tree of all VMs by Resource Pool in this Cluster', 'Show host drift history', 'Show VMs'] if any_in(dnn, links[link].title): logger.debug('DNN Skipping: {}'.format(links[link].title)) else: pages.extend(analyze_page_stat(perf_click(ui_worker_pid, prod_tail, True, links[link].click), soft_assert)) except NoSuchElementException: logger.warning('NoSuchElementException - page_name:{}, Quadicon:{},' ' topbar:{}'.format(page_name, q, topbar)) soft_assert(False, 'NoSuchElementException - page_name:{}, Quadicon:{},' ' topbar:{}'.format(page_name, q, topbar)) break count += 1 break pages.extend(analyze_page_stat(perf_click(ui_worker_pid, prod_tail, True, sel.force_navigate, page_name), soft_assert)) # If nav_limit == 0 , every item is navigated to if not nav_limit == 0 and count == nav_limit: break return pages
def test_ssa_packages(provider, instance, soft_assert): """ Tests SSA fetches correct results for packages Metadata: test_flag: vm_analysis """ if instance.system_type == WINDOWS: pytest.skip("Windows has no packages") expected = None if 'package' not in instance.system_type.keys(): pytest.skip("Don't know how to update packages for {}".format( instance.system_type)) package_name = instance.system_type['package'] package_command = instance.system_type['install-command'] package_number_command = instance.system_type['package-number'] cmd = package_command.format(package_name) output = instance.ssh.run_command(cmd.format(package_name)).output logger.info("{0} output:\n{1}".format(cmd, output)) expected = instance.ssh.run_command(package_number_command).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=('Configuration', 'Packages')) assert current == expected # Make sure new package is listed sel.click(InfoBlock("Configuration", "Packages")) template = '//div[@id="list_grid"]/div[@class="{}"]/table/tbody' packages = 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(): if packages.find_row('Name', package_name): return pytest.fail("Package {0} was not found".format(package_name))
def domains(cls, provider=None, strict=True): domains = [] _get_domains_page(provider=provider) if sel.is_displayed(list_tbl): _provider = provider for _ in paginator.pages(): for row in list_tbl.rows(): if strict: _provider = get_crud_by_name(row.provider.text) domains.append( MiddlewareDomain(name=row.domain_name.text, feed=row.feed.text, provider=_provider)) return domains