def _wait_for_load_balancer_status(cls, load_balancer_id, provisioning_status='ACTIVE', operating_status='ONLINE', delete=False): interval_time = 1 timeout = 600 end_time = time.time() + timeout lb = {} while time.time() < end_time: try: lb = cls.load_balancers_client.get_load_balancer( load_balancer_id) if not lb: # loadbalancer not found if delete: break else: raise Exception( _("loadbalancer {lb_id} not" " found").format(lb_id=load_balancer_id)) if (lb.get('provisioning_status') == provisioning_status and lb.get('operating_status') == operating_status): break time.sleep(interval_time) except exceptions.NotFound as e: # if wait is for delete operation do break if delete: break else: # raise original exception raise e else: if delete: raise exceptions.TimeoutException( _("Waited for load balancer {lb_id} to be deleted for " "{timeout} seconds but can still observe that it " "exists.").format(lb_id=load_balancer_id, timeout=timeout)) else: raise exceptions.TimeoutException( _("Wait for load balancer ran for {timeout} seconds and " "did not observe {lb_id} reach {provisioning_status} " "provisioning status and {operating_status} " "operating status.").format( timeout=timeout, lb_id=load_balancer_id, provisioning_status=provisioning_status, operating_status=operating_status)) return lb
def wait_for_bm_node_status(client, node_id, attr, status): """Waits for a baremetal node attribute to reach given status. The client should have a show_node(node_uuid) method to get the node. """ _, node = client.show_node(node_id) start = int(time.time()) while node[attr] != status: time.sleep(client.build_interval) _, node = client.show_node(node_id) status_curr = node[attr] if status_curr == status: return if int(time.time()) - start >= client.build_timeout: message = ('Node %(node_id)s failed to reach %(attr)s=%(status)s ' 'within the required time (%(timeout)s s).' % { 'node_id': node_id, 'attr': attr, 'status': status, 'timeout': client.build_timeout }) message += ' Current state of %s: %s.' % (attr, status_curr) caller = misc_utils.find_test_caller() if caller: message = '(%s) %s' % (caller, message) raise lib_exc.TimeoutException(message)
def wait_execution(self, ex_body, timeout=180, url='executions', target_state='SUCCESS'): start_time = time.time() expected_states = [target_state, 'RUNNING'] while ex_body['state'] != target_state: if time.time() - start_time > timeout: msg = ("Execution exceeds timeout {0} " "to change state to {1}. " "Execution: {2}".format(timeout, target_state, ex_body)) raise exceptions.TimeoutException(msg) _, ex_body = self.get_object(url, ex_body['id']) if ex_body['state'] not in expected_states: msg = ("Execution state %s is not in expected " "states: %s" % (ex_body['state'], expected_states)) raise exceptions.TempestException(msg) time.sleep(1) return ex_body
def wait_for_resource_deletion(self, id): """Waits for a resource to be deleted This method will loop over is_resource_deleted until either is_resource_deleted returns True or the build timeout is reached. This depends on is_resource_deleted being implemented :param str id: The id of the resource to check :raises TimeoutException: If the build_timeout has elapsed and the resource still hasn't been deleted """ start_time = int(time.time()) while True: if self.is_resource_deleted(id): return if int(time.time()) - start_time >= self.build_timeout: message = ('Failed to delete %(resource_type)s %(id)s within ' 'the required time (%(timeout)s s).' % {'resource_type': self.resource_type, 'id': id, 'timeout': self.build_timeout}) caller = misc_utils.find_test_caller() if caller: message = '(%s) %s' % (caller, message) raise exceptions.TimeoutException(message) time.sleep(self.build_interval)
def wait_deployment_result(self, env_id, timeout=180): start_time = time.time() env = self.listing('environment-show', params=env_id) env_status = self.get_property_value(env, 'status') expected_statuses = ['ready', 'deploying'] while env_status != 'ready': if time.time() - start_time > timeout: msg = ("Environment exceeds timeout {0} to change state " "to Ready. Environment: {1}".format(timeout, env)) raise exceptions.TimeoutException(msg) env = self.listing('environment-show', params=env_id) env_status = self.get_property_value(env, 'status') if env_status not in expected_statuses: msg = ("Environment status %s is not in expected " "statuses: %s" % (env_status, expected_statuses)) raise exceptions.TempestException(msg) time.sleep(2) return True
def wait_execution_success(self, exec_id, timeout=180): start_time = time.time() ex = self.highlander_admin('execution-get', params=exec_id) exec_state = self.get_value_of_field(ex, 'State') expected_states = ['SUCCESS', 'RUNNING'] while exec_state != 'SUCCESS': if time.time() - start_time > timeout: msg = ("Execution exceeds timeout {0} to change state " "to SUCCESS. Execution: {1}".format(timeout, ex)) raise exceptions.TimeoutException(msg) ex = self.highlander_admin('execution-get', params=exec_id) exec_state = self.get_value_of_field(ex, 'State') if exec_state not in expected_states: msg = ("Execution state %s is not in expected " "states: %s" % (exec_state, expected_states)) raise exceptions.TempestException(msg) time.sleep(2) return True
def wait_for_share_status(self, share_id, status, status_attr='status', version=LATEST_MICROVERSION): """Waits for a share to reach a given status.""" body = self.get_share(share_id, version=version) share_status = body[status_attr] start = int(time.time()) while share_status != status: time.sleep(self.build_interval) body = self.get_share(share_id, version=version) share_status = body[status_attr] if share_status == status: return elif 'error' in share_status.lower(): raise share_exceptions.ShareBuildErrorException( share_id=share_id) if int(time.time()) - start >= self.build_timeout: message = ("Share's %(status_attr)s failed to transition to " "%(status)s within the required time %(seconds)s." % { "status_attr": status_attr, "status": status, "seconds": self.build_timeout }) raise exceptions.TimeoutException(message)
def wait_for_access_rule_deletion(self, share_id, access_id, microversion=None): try: access = self.get_access(share_id, access_id, microversion=microversion) except tempest_lib_exc.NotFound: return start = int(time.time()) while True: time.sleep(self.build_interval) try: access = self.get_access(share_id, access_id, microversion=microversion) except tempest_lib_exc.NotFound: return if access['state'] == 'error': raise exceptions.AccessRuleDeleteErrorException( access=access_id) if int(time.time()) - start >= self.build_timeout: message = ( "Access rule %(access)s failed to reach deleted state " "within the required time (%s s)." % self.build_timeout) raise tempest_lib_exc.TimeoutException(message)
def wait_for_access_rule_status(self, share_id, access_id, state='active', microversion=None): access = self.get_access(share_id, access_id, microversion=microversion) start = int(time.time()) while access['state'] != state: time.sleep(self.build_interval) access = self.get_access(share_id, access_id, microversion=microversion) if access['state'] == state: return elif access['state'] == 'error': raise exceptions.AccessRuleCreateErrorException( access=access_id) if int(time.time()) - start >= self.build_timeout: message = ( "Access rule %(access)s failed to reach %(state)s state " "within the required time (%(build_timeout)s s)." % { "access": access_id, "state": state, "build_timeout": self.build_timeout }) raise tempest_lib_exc.TimeoutException(message)
def wait_for_share_status(self, share, status, microversion=None): """Waits for a share to reach a given status.""" body = self.get_share(share, microversion=microversion) share_name = body['name'] share_status = body['status'] start = int(time.time()) while share_status != status: time.sleep(self.build_interval) body = self.get_share(share, microversion=microversion) share_status = body['status'] if share_status == status: return elif 'error' in share_status.lower(): raise exceptions.ShareBuildErrorException(share=share) if int(time.time()) - start >= self.build_timeout: message = ( "Share %(share_name)s failed to reach %(status)s status " "within the required time (%(build_timeout)s s)." % { "share_name": share_name, "status": status, "build_timeout": self.build_timeout }) raise tempest_lib_exc.TimeoutException(message)
def wait_for_migration_completed(self, share_id, dest_host, version=LATEST_MICROVERSION): """Waits for a share to migrate to a certain host.""" share = self.get_share(share_id, version=version) migration_timeout = CONF.share.migration_timeout start = int(time.time()) while share['task_state'] != 'migration_success': time.sleep(self.build_interval) share = self.get_share(share_id, version=version) if share['task_state'] == 'migration_success': return share elif share['task_state'] == 'migration_error': raise share_exceptions.ShareMigrationException( share_id=share['id'], src=share['host'], dest=dest_host) elif int(time.time()) - start >= migration_timeout: message = ('Share %(share_id)s failed to migrate from ' 'host %(src)s to host %(dest)s within the required ' 'time %(timeout)s.' % { 'src': share['host'], 'dest': dest_host, 'share_id': share['id'], 'timeout': self.build_timeout }) raise exceptions.TimeoutException(message)
def _validate_power_state(self, node_uuid, power_state): # Validate that power state is set within timeout if power_state == 'rebooting': power_state = 'power on' start = timeutils.utcnow() while timeutils.delta_seconds(start, timeutils.utcnow()) < self.power_timeout: _, node = self.client.show_node(node_uuid) if node['power_state'] == power_state: return message = ('Failed to set power state within ' 'the required time: %s sec.' % self.power_timeout) raise exceptions.TimeoutException(message)
def exec_command(self, cmd): """Execute the specified command on the server Note that this method is reading whole command outputs to memory, thus shouldn't be used for large outputs. :param str cmd: Command to run at remote server. :returns: data read from standard output of the command. :raises: SSHExecCommandFailed if command returns nonzero status. The exception contains command status stderr content. :raises: TimeoutException if cmd doesn't end when timeout expires. """ ssh = self._get_ssh_connection() transport = ssh.get_transport() channel = transport.open_session() channel.fileno() # Register event pipe channel.exec_command(cmd) channel.shutdown_write() out_data = [] err_data = [] poll = select.poll() poll.register(channel, select.POLLIN) start_time = time.time() while True: ready = poll.poll(self.channel_timeout) if not any(ready): if not self._is_timed_out(start_time): continue raise exceptions.TimeoutException( "Command: '{0}' executed on host '{1}'.".format( cmd, self.host)) if not ready[0]: # If there is nothing to read. continue out_chunk = err_chunk = None if channel.recv_ready(): out_chunk = channel.recv(self.buf_size) out_data += out_chunk, if channel.recv_stderr_ready(): err_chunk = channel.recv_stderr(self.buf_size) err_data += err_chunk, if channel.closed and not err_chunk and not out_chunk: break exit_status = channel.recv_exit_status() if 0 != exit_status: raise exceptions.SSHExecCommandFailed(command=cmd, exit_status=exit_status, stderr=err_data, stdout=out_data) return ''.join(out_data)
def wait_node(self, instance_id): """Waits for a node to be associated with instance_id.""" def _get_node(): node = None try: node = self.get_node(instance_id=instance_id) except lib_exc.NotFound: pass return node is not None if (not tempest.test.call_until_true( _get_node, CONF.baremetal.association_timeout, 1)): msg = ('Timed out waiting to get Ironic node by instance id %s' % instance_id) raise lib_exc.TimeoutException(msg)
def wait_for_resource_deletion(self, id): """Waits for a resource to be deleted.""" start_time = int(time.time()) while True: if self.is_resource_deleted(id): return if int(time.time()) - start_time >= self.build_timeout: message = ('Failed to delete %(resource_type)s %(id)s within ' 'the required time (%(timeout)s s).' % {'resource_type': self.resource_type, 'id': id, 'timeout': self.build_timeout}) caller = misc_utils.find_test_caller() if caller: message = '(%s) %s' % (caller, message) raise exceptions.TimeoutException(message) time.sleep(self.build_interval)
def test_list_alarm_definitions_with_offset_limit(self): helpers.delete_alarm_definitions(self.monasca_client) expression = "max(cpu.system_perc) > 0" self._create_alarm_definitions( expression=expression, number_of_definitions=NUM_ALARM_DEFINITIONS) resp, response_body = self.monasca_client.list_alarm_definitions() self._verify_list_alarm_definitions_response_body(resp, response_body) first_element = response_body['elements'][0] last_element = response_body['elements'][1] query_parms = '?limit=2' resp, response_body = self.monasca_client.list_alarm_definitions( query_parms) self.assertEqual(200, resp.status) elements = response_body['elements'] self.assertEqual(2, len(elements)) self.assertEqual(first_element, elements[0]) self.assertEqual(last_element, elements[1]) timeout = time.time() + 60 * 1 # 1 minute timeout for limit in xrange(1, 3): next_element = elements[limit - 1] while True: if time.time() < timeout: query_parms = '?offset=' + str(next_element['id']) + \ '&limit=' + str(limit) resp, response_body = self.monasca_client.\ list_alarm_definitions(query_parms) self.assertEqual(200, resp.status) new_elements = response_body['elements'] if len(new_elements) > limit - 1: self.assertEqual(limit, len(new_elements)) next_element = new_elements[limit - 1] elif 0 < len(new_elements) <= limit - 1: self.assertEqual(last_element, new_elements[0]) break else: self.assertEqual(last_element, next_element) break else: msg = "Failed " \ "test_list_alarm_definitions_with_offset_limit: " \ "one minute timeout" raise exceptions.TimeoutException(msg)
def _node_state_timeout(self, node_id, state_attr, target_states, timeout=10, interval=1): if not isinstance(target_states, list): target_states = [target_states] def check_state(): node = self.get_node(node_id=node_id) if node.get(state_attr) in target_states: return True return False if not tempest.test.call_until_true(check_state, timeout, interval): msg = ("Timed out waiting for node %s to reach %s state(s) %s" % (node_id, state_attr, target_states)) raise lib_exc.TimeoutException(msg)
def wait_for_cgsnapshot_status(self, cgsnapshot_id, status): """Waits for a cgsnapshot to reach a given status.""" body = self.get_cgsnapshot(cgsnapshot_id) cgsnapshot_name = body['name'] cgsnapshot_status = body['status'] start = int(time.time()) while cgsnapshot_status != status: time.sleep(self.build_interval) body = self.get_cgsnapshot(cgsnapshot_id) cgsnapshot_status = body['status'] if 'error' in cgsnapshot_status and status != 'error': raise share_exceptions.CGSnapshotBuildErrorException( cgsnapshot_id=cgsnapshot_id) if int(time.time()) - start >= self.build_timeout: message = ('CGSnapshot %s failed to reach %s status ' 'within the required time (%s s).' % (cgsnapshot_name, status, self.build_timeout)) raise exceptions.TimeoutException(message)
def wait_for_access_rule_status(self, share_id, rule_id, status): """Waits for an access rule to reach a given status.""" rule_status = "new" start = int(time.time()) while rule_status != status: time.sleep(self.build_interval) rules = self.list_access_rules(share_id) for rule in rules: if rule["id"] in rule_id: rule_status = rule['state'] break if 'error' in rule_status: raise share_exceptions.\ AccessRuleBuildErrorException(rule_id=rule_id) if int(time.time()) - start >= self.build_timeout: message = ('Share Access Rule %s failed to reach %s status ' 'within the required time (%s s).' % (rule_id, status, self.build_timeout)) raise exceptions.TimeoutException(message)
def wait_execution_success(self, ex_body, timeout=180): start_time = time.time() expected_states = ['SUCCESS', 'RUNNING'] while ex_body['state'] != 'SUCCESS': if time.time() - start_time > timeout: msg = ("Execution exceeds timeout {0} to change state " "to SUCCESS. Execution: {1}".format(timeout, ex_body)) raise exceptions.TimeoutException(msg) _, ex_body = self.get_object('executions', ex_body['id']) if ex_body['state'] not in expected_states: msg = ("Execution state %s is not in expected " "states: %s" % (ex_body['state'], expected_states)) raise exceptions.TempestException(msg) time.sleep(2) return True
def wait_for_consistency_group_status(self, consistency_group_id, status): """Waits for a consistency group to reach a given status.""" body = self.get_consistency_group(consistency_group_id) consistency_group_name = body['name'] consistency_group_status = body['status'] start = int(time.time()) while consistency_group_status != status: time.sleep(self.build_interval) body = self.get_consistency_group(consistency_group_id) consistency_group_status = body['status'] if 'error' in consistency_group_status and status != 'error': raise share_exceptions.ConsistencyGroupBuildErrorException( consistency_group_id=consistency_group_id) if int(time.time()) - start >= self.build_timeout: message = ( 'Consistency Group %s failed to reach %s status ' 'within the required time (%s s).' % (consistency_group_name, status, self.build_timeout)) raise exceptions.TimeoutException(message)
def wait_for_share_status(self, share_id, status): """Waits for a share to reach a given status.""" body = self.get_share(share_id) share_name = body['name'] share_status = body['status'] start = int(time.time()) while share_status != status: time.sleep(self.build_interval) body = self.get_share(share_id) share_status = body['status'] if share_status == status: return elif 'error' in share_status.lower(): raise share_exceptions.\ ShareBuildErrorException(share_id=share_id) if int(time.time()) - start >= self.build_timeout: message = ('Share %s failed to reach %s status within ' 'the required time (%s s).' % (share_name, status, self.build_timeout)) raise exceptions.TimeoutException(message)
def _update_ticket(self, role, ticket_id, workflow_id1, workflow_id2): """Update ticket data. :param role: running user. :param ticket_id: ticket id. :param workflow_id1: last workflow id. :param workflow_id2: next workflow id """ self.clients[role].run_command( 'ticket-update', params=' --id {0}' ' --last-workflow-id {1}' ' --next-workflow-id {2}' ' --last-status-code {3}' ' --next-status-code {4}' ' --additional-data {5}'.format( ticket_id[0], workflow_id1, workflow_id2, "applied", 'withdrew', '\'{"description": "test"}\'')) # Get records. for c in range(0, _RETRY_COUNT): st_work = self.clients[role].run_command( 'workflow-get', params='--id ' + ticket_id[0]) workflow = output_parser.tables(st_work)[0]['values'] now_status = filter(lambda row: row[3] == 'withdrew', workflow) # DB Entry is asynchronous process. # Wait for a seconds. if now_status[0][2] != '1': if c < _RETRY_COUNT - 1: time.sleep(1) else: raise exceptions.TimeoutException(str(st_work)) else: break
def _delete_ticket(self, role, ticket_id): """Delete ticket data. :param role: running user. :param ticket_id: ticket id. """ for id in ticket_id: self.clients[role].run_command('ticket-delete', params='--id ' + id) # Get records. for c in range(0, _RETRY_COUNT): st_list = self.clients[role].run_command( 'ticket-list', params='') # DB Entry is asynchronous process. # Wait for a seconds. if len(output_parser.tables(st_list)[0]['values']) != 0: if c < _RETRY_COUNT - 1: time.sleep(1) else: raise exceptions.TimeoutException(str(st_list)) else: break
def wait_for_share_instance_status(self, instance_id, status, version=LATEST_MICROVERSION): """Waits for a share to reach a given status.""" body = self.get_share_instance(instance_id, version=version) instance_status = body['status'] start = int(time.time()) while instance_status != status: time.sleep(self.build_interval) body = self.get_share(instance_id) instance_status = body['status'] if instance_status == status: return elif 'error' in instance_status.lower(): raise share_exceptions. \ ShareInstanceBuildErrorException(id=instance_id) if int(time.time()) - start >= self.build_timeout: message = ('Share instance %s failed to reach %s status within' ' the required time (%s s).' % (instance_id, status, self.build_timeout)) raise exceptions.TimeoutException(message)
def test_list_notification_methods_with_offset_limit(self): name1 = data_utils.rand_name('notification') name2 = data_utils.rand_name('notification') name3 = data_utils.rand_name('notification') name4 = data_utils.rand_name('notification') notification1 = helpers.create_notification(name=name1) notification2 = helpers.create_notification(name=name2) notification3 = helpers.create_notification(name=name3) notification4 = helpers.create_notification(name=name4) resp, response_body = self.monasca_client.create_notifications( notification1) id1 = response_body['id'] self.assertEqual(201, resp.status) resp, response_body = self.monasca_client.create_notifications( notification2) id2 = response_body['id'] self.assertEqual(201, resp.status) resp, response_body = self.monasca_client.create_notifications( notification3) id3 = response_body['id'] self.assertEqual(201, resp.status) resp, response_body = self.monasca_client.create_notifications( notification4) id4 = response_body['id'] self.assertEqual(201, resp.status) resp, response_body = self.monasca_client.list_notification_methods() elements = response_body['elements'] first_element = elements[0] last_element = elements[3] query_parms = '?limit=4' resp, response_body = self.monasca_client.\ list_notification_methods(query_parms) self.assertEqual(200, resp.status) self.assertEqual(4, len(elements)) self.assertEqual(first_element, elements[0]) timeout = time.time() + 60 * 1 # 1 minute timeout for limit in xrange(1, 5): next_element = elements[limit - 1] while True: if time.time() < timeout: query_parms = '?offset=' + str(next_element['id']) + \ '&limit=' + str(limit) resp, response_body = self.monasca_client.\ list_notification_methods(query_parms) self.assertEqual(200, resp.status) new_elements = response_body['elements'] if len(new_elements) > limit - 1: self.assertEqual(limit, len(new_elements)) next_element = new_elements[limit - 1] elif 0 < len(new_elements) <= limit - 1: self.assertEqual(last_element, new_elements[0]) break else: self.assertEqual(last_element, next_element) break else: msg = "Failed " \ "test_list_notification_methods_with_offset_limit:" \ " one minute timeout on offset limit test loop." raise exceptions.TimeoutException(msg) resp, response_body = self.monasca_client.\ delete_notification_method(id1) self.assertEqual(204, resp.status) resp, response_body = self.monasca_client.\ delete_notification_method(id2) self.assertEqual(204, resp.status) resp, response_body = self.monasca_client.\ delete_notification_method(id3) self.assertEqual(204, resp.status) resp, response_body = self.monasca_client.\ delete_notification_method(id4) self.assertEqual(204, resp.status)
def _list_ticket(self, role, ticket_id): """List ticket data. :param role: running user. :param ticket_id: ticket id. """ for c in range(0, _RETRY_COUNT): st_list = self.clients[role].run_command('ticket-list') # DB Entry is asynchronous process. # Wait for a seconds. if len(output_parser.tables(st_list)[0]['values']) \ < _CREATE_TICKET_COUNT: if c < _RETRY_COUNT - 1: time.sleep(1) else: raise exceptions.TimeoutException(str(st_list)) else: break # Search data not exists, # data by all setting filter condition. st_list = self.clients[role].run_command( 'ticket-list', params=' --tenant-id {0}' ' --last-status-code {1}' ' --ticket-template-id {2}' ' --ticket-type {3}' ' --target-id {4}' ' --owner-at-from {5}' ' --owner-at-to {6}' ' --owner-id {7}' ' --last-confirmed-at-from {8}' ' --last-confirmed-at-to {9}' ' --last-confirmer-id {10}' ' --sort-key {11}' ' --sort-dir {12}' ' --limit {13}' ' --marker {14}' ' --ticket-template-name {15}' ' --application-kinds-name {16}'.format( self.clients[role].tenant_name, 'applied', '2', 'goods', '3902653a15f74b55912b812f1f537e87', '2015-07-01T00:00:00.000000', '2015-07-01T00:00:00.000000', '99b3abc617c14a258190096e0258aa9b', '2015-07-20T00:00:00.000000', '2015-07-20T00:00:00.000000', '99b3abc617c14a258190096e0258aa9b', 'created_at', 'asc', '1', ticket_id[0], '"flat-rate-1(ja) *root:three"', 'application_kinds_2(ja)')) self.assertEqual(len(output_parser.tables(st_list)[0]['values']), 0) # Search all data. st_list = self.clients[role].run_command( 'ticket-list', params='') self.assertEqual(len(output_parser.tables(st_list)[0]['values']), _CREATE_TICKET_COUNT) # Search data not exists, # data by template contents invalid condition. self._ticket_list_irregular_template_contents(role)