def check_compliance_multiple_images(self, image_entities, check_on_entity=True, timeout=240): """Initiates compliance check and waits for it to finish on several Images. Args: image_entities: list of Image entities that need to perform compliance check on them check_on_entity (bool): check the compliance status on the entity summary view if True, only run compliance otherwise. timeout (seconds): time for waiting for compliance status """ # Chose Check Compliance of Last Known Configuration images_view = navigate_to(self, 'All') self.check_image_entities(image_entities) wait_for(lambda: images_view.toolbar.policy.is_enabled, num_sec=5, message='Policy drop down menu is disabled after checking some Images') images_view.toolbar.policy.item_select('Check Compliance of Last Known Configuration', handle_alert=True) images_view.flash.assert_no_error() # Verify Image summary if check_on_entity: for image_instance in image_entities: original_state = 'never verified' try: wait_for( lambda: image_instance.compliance_status.lower() != original_state, num_sec=timeout, delay=5, message='compliance state of Image ID, "{}", still matches {}' .format(image_instance.id, original_state) ) except TimedOutError: logger.error('compliance state of Image ID, "{}", is {}' .format(image_instance.id, image_instance.compliance_status)) raise TimedOutError('Timeout exceeded, Waited too much' ' time for check Compliance finish ({}).'.format(timeout))
def perform_smartstate_analysis(self, wait_for_finish=False, timeout='7M'): """Performing SmartState Analysis on this Image """ # task_name change from str to regular expression pattern following Bugzilla Bug 1483590 # task name will contain also Image name # the str compile on tasks module view = navigate_to(self, 'Details') view.toolbar.configuration.item_select('Perform SmartState Analysis', handle_alert=True) # TODO: Modify accordingly once there is FlashMessages.assert_massage_contains() assert filter(lambda m: 'Analysis successfully initiated' in m.text, view.flash.messages) if wait_for_finish: try: wait_for(tasks.is_analysis_finished, func_kwargs={ 'name': '(?i)(Container Image.*)', 'task_type': 'container' }, timeout=timeout, fail_func=self.appliance.server.browser.refresh) except TimedOutError: raise TimedOutError( 'Timeout exceeded, Waited too much time for SSA to finish ({}).' .format(timeout))
def _pick_responding_ip(vm, port): for ip in _trying_ips(vm): if net_check(port, ip): return ip else: raise TimedOutError( f"Coudln't find an IP of vm {vm} with port {port} responding")
def perform_smartstate_analysis_multiple_images( self, image_entities, wait_for_finish=False, timeout='20M'): """Performing SmartState Analysis on this Image """ # task_name change from str to regular expression # the str compile on tasks module image_enities_names = [] images_view = navigate_to(self, 'All') self.check_image_entities(image_entities) images_view.toolbar.configuration.item_select( 'Perform SmartState Analysis', handle_alert=True) for image_entity in image_entities: image_enities_names.append(image_entity.name) images_view.flash.assert_success_message( '"{}": Analysis successfully initiated'.format(image_entity.name), partial=True ) if wait_for_finish: try: col = self.appliance.collections.tasks.filter({'tab': 'AllTasks'}) col.wait_for_finished(image_enities_names, timeout=timeout) # check all task passed successfully with no error if col.is_successfully_finished(image_enities_names, silent_failure=True): return True else: logger.error('Some Images SSA tasks finished with error message,' ' see logger for more details.') return False except TimedOutError: raise TimedOutError('Timeout exceeded, Waited too much time for SSA to finish ({}).' .format(timeout))
def is_task_finished(destination, task_name, expected_status, clear_tasks_after_success=True): view = navigate_to(Tasks, destination) tab_view = getattr(view.tabs, destination.lower()) try: row = tab_view.table.row(task_name=task_name, state=expected_status) except IndexError: logger.warn( 'IndexError exception suppressed when searching for task row, no match found.' ) return False # throw exception if error in message message = row.message.text.lower() if 'error' in message: raise Exception("Task {} error: {}".format(task_name, message)) elif 'timed out' in message: raise TimedOutError("Task {} timed out: {}".format(task_name, message)) elif 'failed' in message: raise Exception("Task {} has a failure: {}".format(task_name, message)) if clear_tasks_after_success: # Remove all finished tasks so they wouldn't poison other tests delete_all_tasks(destination) return True
def is_refreshed(self, refresh_timer=None, refresh_delta=600): """ Overrides cfme.common.provider.BaseProvider#is_refreshed. Add validate_status check after provider creation, In order to make sure that openshift provider data refresh completed Args: refresh_timer : wait_for.RefreshTimer Object or None refresh_delta : refresh delta between times on second Returns: Boolean or TimedOutError exception in case data referesh didn't completed """ valid = False # check refresh time if not super(OpenshiftProvider, self).is_refreshed(): return valid # check the detail page matches the Providers information try: self.validate_stats(ui=False) valid = True except TimedOutError: raise TimedOutError( 'Timeout exceeded, openShift provider data refresh did not completed on time' ) finally: return valid
def is_successfully_finished(self, silent_failure=False, *tasks): view = navigate_to(self, self.tab) tab_view = getattr(view.tabs, self.tab.lower()) rows = [] # expected_status support also regular expression pattern expected_status = re.compile('finished', re.IGNORECASE) for task in tasks: try: rows.append( list( tab_view.table.rows(task_name=task, state=expected_status)).pop()) except IndexError: logger.warn( 'IndexError exception suppressed when searching for task row,' ' no match found.') return False for row in rows: message = row.message.text.lower() if row[1].browser.is_displayed( 'i[@class="pficon pficon-error-circle-o"]', parent=row[1]): if silent_failure: logger.warning("Task {} error: {}".format( row.task_name.text, message)) return False elif 'timed out' in message: raise TimedOutError("Task {} timed out: {}".format( row.task_name.text, message)) else: Exception("Task {} error: {}".format( row.task_name.text, message)) return True
def wait_analysis_finished_multiple_tasks(task_name, task_type, expected_num_of_tasks, delay=5, timeout='5M'): """ Wait until analysis is finished (or timeout exceeded)""" row_completed = [] # get view for reload button view = navigate_to(Tasks, 'AllTasks') def tasks_finished(output_rows, task_name, task_type, expected_num_of_tasks): is_succeed, num_of_succeed_tasks = are_all_tasks_match_status( task_name, expected_num_of_tasks, task_type) output_rows.append(num_of_succeed_tasks) return is_succeed try: wait_for(tasks_finished, func_kwargs={ 'output_rows': row_completed, 'task_name': task_name, 'task_type': task_type, 'expected_num_of_tasks': expected_num_of_tasks }, delay=delay, timeout=timeout, fail_func=view.reload.click) return row_completed[-1] except TimedOutError as e: logger.error("Only {} Tasks out of {}, Finished".format( row_completed[-1], expected_num_of_tasks)) raise TimedOutError('exception {}'.format(e))
def perform_smartstate_analysis(self, wait_for_finish=False, timeout='20M'): """Performing SmartState Analysis on this Image """ # task_name change from str to regular expression pattern following Bugzilla Bug 1483590 # task name will contain also Image name # the str compile on tasks module view = navigate_to(self, 'Details') view.toolbar.configuration.item_select('Perform SmartState Analysis', handle_alert=True) # TODO: Modify accordingly once there is FlashMessages.assert_massage_contains() assert [ m for m in view.flash.messages if 'Analysis successfully initiated' in m.text ] if wait_for_finish: try: task = self.appliance.collections.tasks.instantiate( name="Container Image Analysis: '{}'".format(self.name), tab='AllTasks') task.wait_for_finished(timeout=timeout) except TimedOutError: raise TimedOutError( 'Timeout exceeded, Waited too much time for SSA to finish ({}).' .format(timeout))
def check_tasks_have_no_errors(task_name, task_type, expected_num_of_tasks, silent_failure=False, clear_tasks_after_success=False): """ Check if all tasks analysis match state with no errors""" tabs_data = TABS_DATA_PER_PROVIDER[task_type] destination = tabs_data['tab'] task_name = tabs_data['task'].format(task_name) expected_status = tabs_data['state'] view = navigate_to(Tasks, destination) tab_view = getattr(view.tabs, destination.lower()) # task_name change from str to support also regular expression pattern task_name = re.compile(task_name) # expected_status change from str to support also regular expression pattern expected_status = re.compile(expected_status, re.IGNORECASE) try: rows = list( tab_view.table.rows(task_name=task_name, state=expected_status)) except IndexError: logger.warn( 'IndexError exception suppressed when searching for task row, no match found.' ) return False # check state for all tasks if expected_num_of_tasks != len(rows): logger.warn('There is no match between expected number of tasks "{}",' ' and number of tasks on state "{}'.format( expected_num_of_tasks, expected_status)) return False # throw exception if error in message for row in rows: message = row.message.text.lower() for term in ('error', 'timed out', 'failed', 'unable to run openscap'): if term in message: if silent_failure: logger.warning("Task {} error: {}".format( row.task_name.text, message)) return False elif term == 'timed out': raise TimedOutError("Task {} timed out: {}".format( row.task_name.text, message)) else: raise TaskFailedException(task_name=row.task_name.text, message=message) if clear_tasks_after_success: # Remove all finished tasks so they wouldn't poison other tests delete_all_tasks(destination) return True
def is_successfully_finished(self): message = self.message.lower() if self.status == self.ERROR: if 'timed out' in message: raise TimedOutError("Task {} timed out: {}".format(self.name, message)) else: raise Exception("Task {} error: {}".format(self.name, message)) if self.state.lower() == 'finished' and self.status == self.OK: return True return False
def perform_smartstate_analysis_multiple_images(self, image_entities, wait_for_finish=False, timeout='20M'): """Performing SmartState Analysis on this Image """ # task_name change from str to regular expression # the str compile on tasks module task_name = '(?i)(Container Image.*)' task_type = 'container' num_of_tasks = len(image_entities) images_view = navigate_to(self, 'All') self.check_image_entities(image_entities) images_view.toolbar.configuration.item_select( 'Perform SmartState Analysis', handle_alert=True) for image_entity in image_entities: images_view.flash.assert_success_message( '"{}": Analysis successfully initiated'.format( image_entity.name), partial=True) if wait_for_finish: try: # check all tasks state finished tasks.wait_analysis_finished_multiple_tasks(task_name, task_type, num_of_tasks, timeout=timeout) # check all task passed successfully with no error if tasks.check_tasks_have_no_errors( task_name, task_type, num_of_tasks, silent_failure=True, clear_tasks_after_success=False): return True else: logger.error( 'Some Images SSA tasks finished with error message,' ' see logger for more details.') return False except TimedOutError: raise TimedOutError( 'Timeout exceeded, Waited too much time for SSA to finish ({}).' .format(timeout))
def connect_ssh(vm, creds): for ip in _trying_ips(vm): try: with SSHClient(hostname=ip, username=creds.principal, password=creds.secret) as client: logger.info("SSH connected to IP %s", ip) result = client.run_command("true") if not result.success: raise Exception(f"Command `true` failed on ip {ip}.") yield client return except Exception as ex: logger.info("Failed to connect with SSH to %s: %s", ip, ex) else: raise TimedOutError( f"Coudln't find an IP responding to ssh for vm {vm}")
def perform_smartstate_analysis(self, wait_for_finish=False, timeout='7M'): """Performing SmartState Analysis on this Image """ view = navigate_to(self, 'Details') view.toolbar.configuration.item_select('Perform SmartState Analysis', handle_alert=True) # TODO: Modify accordingly once there is FlashMessages.assert_massage_contains() assert filter(lambda m: 'Analysis successfully initiated' in m.text, view.flash.messages) if wait_for_finish: try: wait_for(tasks.is_analysis_finished, func_kwargs={'task_name': 'Container image analysis', 'task_type': 'container'}, timeout=timeout, fail_func=self.appliance.server.browser.refresh) except TimedOutError: raise TimedOutError('Timeout exceeded, Waited too much time for SSA to finish ({}).' .format(timeout))
def perform_smartstate_analysis(self, wait_for_finish=False, timeout='7M'): """Performing SmartState Analysis on this Image """ navigate_to(self, 'Details') tb.select('Configuration', 'Perform SmartState Analysis', invokes_alert=True) sel.handle_alert() flash.assert_message_contain('Analysis successfully initiated') if wait_for_finish: try: tasks.wait_analysis_finished('Container image analysis', 'container', timeout=timeout) except TimedOutError: raise TimedOutError( 'Timeout exceeded, Waited too much time for SSA to finish ({}).' .format(timeout))
def is_successfully_finished(self, silent_failure=False, *tasks): view = navigate_to(self, self.tab) tab_view = getattr(view.tabs, self.tab.lower()) rows = [] for task in tasks: rows.append(tab_view.table.rows(task_name=task, state='finished')) for row in rows: message = row.message.text.lower() if row[1].browser.is_displayed( 'i[@class="pficon pficon-error-circle-o"]', parent=row[1]): if silent_failure: logger.warning("Task {} error: {}".format( row.task_name.text, message)) return False elif 'timed out' in message: raise TimedOutError("Task {} timed out: {}".format( row.task_name.text, message)) else: Exception("Task {} error: {}".format( row.task_name.text, message)) return True
def handle_alert(self, cancel=False, wait=30.0, squash=False, prompt=None, check_present=False): """Handles an alert popup. Args: cancel: Whether or not to cancel the alert. Accepts the Alert (False) by default. wait: Time to wait for an alert to appear. Default 30 seconds, can be set to 0 to disable waiting. squash: Whether or not to squash errors during alert handling. Default False prompt: If the alert is a prompt, specify the keys to type in here check_present: Does not squash :py:class:`selenium.common.exceptions.NoAlertPresentException` Returns: ``True`` if the alert was handled, ``False`` if exceptions were squashed, ``None`` if there was no alert. No exceptions will be raised if ``squash`` is True and ``check_present`` is False. Raises: :py:class:`wait_for.TimedOutError`: If the alert popup does not appear :py:class:`selenium.common.exceptions.NoAlertPresentException`: If no alert is present when accepting or dismissing the alert. """ if not self.handles_alerts: return None # throws timeout exception if not found try: if wait: popup = wait_for(self.get_alert, num_sec=wait, fail_condition=None).out if isinstance(popup, Modal) and BZ(1713399).blocks: # infinispinner if accept button is clicked too quick in modal sleep(1) else: popup = self.get_alert() if popup is None: raise TimedOutError('Pretending to timeout, no wait') # same logging self.logger.info('handling alert: %r', popup.text) if prompt is not None: self.logger.info(' answering prompt: %r', prompt) if isinstance(popup, Modal): popup.fill(prompt) else: popup.send_keys(prompt) if cancel: self.logger.info(' dismissing') popup.dismiss() else: self.logger.info(' accepting') popup.accept() # Should any problematic "double" alerts appear here, we don't care, just blow'em away. if not self.IGNORE_SUBSEQUENT_ALERTS: self.dismiss_any_alerts() return True except TimedOutError: # we waited (or didn't), and there was no alert if check_present: self.logger.error('handle_alert timed out with wait of %s, raising', wait) raise else: self.logger.info('handle_alert found no alert with wait of %s', wait) return None except Exception: if squash: return False else: raise