def curl(): try: return subprocess.check_output(shlex.split(cmd)) except subprocess.CalledProcessError: LOG.error("Checking output of curl to the service IP %s " "failed" % self.service_ip) raise lib_exc.UnexpectedResponseCode()
def curl(): output = self.exec_command_in_pod(pod_name, cmd) # check if the curl command succeeded if not output: LOG.error("Curl the service IP %s failed" % self.service_ip) raise lib_exc.UnexpectedResponseCode() return output
def test_namespace(self): # Check resources are created namespace_name, namespace = self.create_namespace() existing_namespaces = [ ns.metadata.name for ns in self.list_namespaces().items ] self.assertIn(namespace_name, existing_namespaces) subnet_name = 'ns/' + namespace_name + '-subnet' kuryr_net_crd_name = 'ns-' + namespace_name seen_subnets = self.os_admin.subnets_client.list_subnets() seen_subnet_names = [n['name'] for n in seen_subnets['subnets']] self.assertIn(subnet_name, seen_subnet_names) subnet_id = [ n['id'] for n in seen_subnets['subnets'] if n['name'] == subnet_name ] net_id = [ n['network_id'] for n in seen_subnets['subnets'] if n['name'] == subnet_name ] kuryr_net_crd = self.get_kuryr_net_crds(kuryr_net_crd_name) self.assertIn(kuryr_net_crd_name, kuryr_net_crd['metadata']['name']) self.assertIn(kuryr_net_crd['spec']['subnetId'], subnet_id) self.assertIn(kuryr_net_crd['spec']['netId'], net_id) # Check namespace pod connectivity pod_name, pod = self.create_pod(labels={"app": 'pod-label'}, namespace=namespace_name) svc_name, _ = self.create_service(pod_label=pod.metadata.labels, spec_type='LoadBalancer', namespace=namespace_name) svc_service_ip = self.get_service_ip(service_name=svc_name, spec_type='LoadBalancer', namespace=namespace_name) self.wait_service_status(svc_service_ip, CONF.kuryr_kubernetes.lb_build_timeout) cmd = "curl {dst_ip}".format(dst_ip=svc_service_ip) try: subprocess.check_output(shlex.split(cmd)) except subprocess.CalledProcessError: LOG.error("Checking output of curl to the service IP %s " "failed" % svc_service_ip) raise lib_exc.UnexpectedResponseCode() # Check resources are deleted self._delete_namespace_resources(namespace_name, kuryr_net_crd, subnet_name)
def create_object_continue(self, container, object_name, data, metadata=None): """Put an object using Expect:100-continue""" headers = {} if metadata: for key in metadata: headers[str(key)] = metadata[key] headers['X-Auth-Token'] = self.token headers['content-length'] = 0 if data is None else len(data) headers['Expect'] = '100-continue' parsed = urlparse.urlparse(self.base_url) path = str(parsed.path) + "/" path += "%s/%s" % (str(container), str(object_name)) conn = create_connection(parsed) # Send the PUT request and the headers including the "Expect" header conn.putrequest('PUT', path) for header, value in six.iteritems(headers): conn.putheader(header, value) conn.endheaders() # Read the 100 status prior to sending the data response = conn.response_class(conn.sock, strict=conn.strict, method=conn._method) _, status, _ = response._read_status() # toss the CRLF at the end of the response response._safe_read(2) # Expecting a 100 here, if not close and throw an exception if status != 100: conn.close() pattern = "%s %s" % ( """Unexpected http success status code {0}.""", """The expected status code is {1}""") details = pattern.format(status, 100) raise exceptions.UnexpectedResponseCode(details) # If a continue was received go ahead and send the data # and get the final response conn.send(data) resp = conn.getresponse() return resp.status, resp.reason
def _wait(): try: res = cls.client.get_resource("instances", id) cur_status = res["instance"]["status"] except exceptions.NotFound: if need_delete or "DELETED" in expected_status: LOG.info('Instance %s is deleted', id) raise loopingcall.LoopingCallDone() return if cur_status in expected_status: LOG.info('Instance %s becomes %s', id, cur_status) raise loopingcall.LoopingCallDone() elif "ERROR" not in expected_status and cur_status == "ERROR": # If instance status goes to ERROR but is not expected, stop # waiting res = cls.admin_client.get_resource("instances", id) LOG.info(f'Instance fault msg: {res["instance"].get("fault")}') # Show trove-guestagent log for debug purpose. # Only admin user is able to publish and show the trove guest # agent log. Make sure the container is deleted after fetching # the log. try: LOG.info(f"Publishing guest log for instance {id}") cls.publish_log(id, 'guest') LOG.info(f"Getting guest log content for instance {id}") log_gen = cls.log_generator(id, 'guest', lines=0) log_content = "".join([chunk for chunk in log_gen()]) LOG.info( f"\n=============================================\n" f"Trove guest agent log for instance {id}\n" f"=============================================") LOG.info(log_content) except Exception as err: LOG.warning(f"Failed to get guest log for instance {id}, " f"error: {str(err)}") finally: # Remove the swift container of database logs. LOG.info(f"Deleting swift container " f"{CONF.database.database_log_container}") cls.delete_swift_containers( cls.admin_container_client, cls.admin_object_client, CONF.database.database_log_container) message = "Instance status is ERROR." caller = test_utils.find_test_caller() if caller: message = '({caller}) {message}'.format(caller=caller, message=message) raise exceptions.UnexpectedResponseCode(message)
def test_lb_service_curl(self): cmd_output_list = list() LOG.info("Trying to curl the service IP %s" % self.service_ip) cmd = "curl {dst_ip}".format(dst_ip=self.service_ip) for i in range(2): try: cmd_output_list.append( subprocess.check_output(shlex.split(cmd))) except subprocess.CalledProcessError: LOG.error("Checking output of curl to the service IP %s " "failed" % self.service_ip) raise lib_exc.UnexpectedResponseCode() self.assertNotEqual(cmp(cmd_output_list[0], cmd_output_list[1]), '0')
def test_pod_service_curl(self): cmd_output_list = list() pod_name, pod = self.create_pod() self.addCleanup(self.delete_pod, pod_name) cmd = [ "/bin/sh", "-c", "curl {dst_ip}".format(dst_ip=self.service_ip)] for i in range(2): cmd_output_list.append(self.exec_command_in_pod(pod_name, cmd)) # check if the curl command succeeded if not cmd_output_list[i]: LOG.error("Curl the service IP %s failed" % self.service_ip) raise lib_exc.UnexpectedResponseCode() self.assertNotEqual(cmp(cmd_output_list[0], cmd_output_list[1]), '0')
def _wait(): try: res = cls.client.get_resource("backups", id) cur_status = res["backup"]["status"] except exceptions.NotFound: if need_delete or "DELETED" in expected_status: LOG.info('Backup %s is deleted', id) raise loopingcall.LoopingCallDone() return if cur_status in expected_status: LOG.info('Backup %s becomes %s', id, cur_status) raise loopingcall.LoopingCallDone() elif "FAILED" not in expected_status and cur_status == "FAILED": # If backup status goes to FAILED but is not expected, stop # waiting message = "Backup status is FAILED." caller = test_utils.find_test_caller() if caller: message = '({caller}) {message}'.format(caller=caller, message=message) raise exceptions.UnexpectedResponseCode(message)
def _error_checker(self, method, url, headers, body, resp, resp_body): # NOTE(mtreinish): Check for httplib response from glance_http. The # object can't be used here because importing httplib breaks httplib2. # If another object from a class not imported were passed here as # resp this could possibly fail if str(type(resp)) == "<type 'instance'>": ctype = resp.getheader('content-type') else: try: ctype = resp['content-type'] # NOTE(mtreinish): Keystone delete user responses doesn't have a # content-type header. (They don't have a body) So just pretend it # is set. except KeyError: ctype = 'application/json' # It is not an error response if resp.status < 400: return JSON_ENC = ['application/json', 'application/json; charset=utf-8'] # NOTE(mtreinish): This is for compatibility with Glance and swift # APIs. These are the return content types that Glance api v1 # (and occasionally swift) are using. TXT_ENC = [ 'text/plain', 'text/html', 'text/html; charset=utf-8', 'text/plain; charset=utf-8' ] if ctype.lower() in JSON_ENC: parse_resp = True elif ctype.lower() in TXT_ENC: parse_resp = False else: raise exceptions.UnexpectedContentType(str(resp.status), resp=resp) if resp.status == 401: if parse_resp: resp_body = self._parse_resp(resp_body) raise exceptions.Unauthorized(resp_body, resp=resp) if resp.status == 403: if parse_resp: resp_body = self._parse_resp(resp_body) raise exceptions.Forbidden(resp_body, resp=resp) if resp.status == 404: if parse_resp: resp_body = self._parse_resp(resp_body) raise exceptions.NotFound(resp_body, resp=resp) if resp.status == 400: if parse_resp: resp_body = self._parse_resp(resp_body) raise exceptions.BadRequest(resp_body, resp=resp) if resp.status == 410: if parse_resp: resp_body = self._parse_resp(resp_body) raise exceptions.Gone(resp_body, resp=resp) if resp.status == 409: if parse_resp: resp_body = self._parse_resp(resp_body) raise exceptions.Conflict(resp_body, resp=resp) if resp.status == 413: if parse_resp: resp_body = self._parse_resp(resp_body) if self.is_absolute_limit(resp, resp_body): raise exceptions.OverLimit(resp_body, resp=resp) else: raise exceptions.RateLimitExceeded(resp_body, resp=resp) if resp.status == 415: if parse_resp: resp_body = self._parse_resp(resp_body) raise exceptions.InvalidContentType(resp_body, resp=resp) if resp.status == 422: if parse_resp: resp_body = self._parse_resp(resp_body) raise exceptions.UnprocessableEntity(resp_body, resp=resp) if resp.status in (500, 501): message = resp_body if parse_resp: try: resp_body = self._parse_resp(resp_body) except ValueError: # If response body is a non-json string message. # Use resp_body as is and raise InvalidResponseBody # exception. raise exceptions.InvalidHTTPResponseBody(message) else: if isinstance(resp_body, dict): # I'm seeing both computeFault # and cloudServersFault come back. # Will file a bug to fix, but leave as is for now. if 'cloudServersFault' in resp_body: message = resp_body['cloudServersFault']['message'] elif 'computeFault' in resp_body: message = resp_body['computeFault']['message'] elif 'error' in resp_body: message = resp_body['error']['message'] elif 'message' in resp_body: message = resp_body['message'] else: message = resp_body if resp.status == 501: raise exceptions.NotImplemented(resp_body, resp=resp, message=message) else: raise exceptions.ServerFault(resp_body, resp=resp, message=message) if resp.status >= 400: raise exceptions.UnexpectedResponseCode(str(resp.status), resp=resp)
def wait_for_status(show_client, id, status_key, status, check_interval, check_timeout, root_tag=None, error_ok=False, **kwargs): """Waits for an object to reach a specific status. :param show_client: The tempest service client show method. Ex. cls.os_primary.servers_client.show_server :param id: The id of the object to query. :param status_key: The key of the status field in the response. Ex. provisioning_status :param status: The status to wait for. Ex. "ACTIVE" :check_interval: How often to check the status, in seconds. :check_timeout: The maximum time, in seconds, to check the status. :root_tag: The root tag on the response to remove, if any. :error_ok: When true, ERROR status will not raise an exception. :raises CommandFailed: Raised if the object goes into ERROR and ERROR was not the desired status. :raises TimeoutException: The object did not achieve the status or ERROR in the check_timeout period. :returns: The object details from the show client. """ start = int(time.time()) LOG.info('Waiting for {name} status to update to {status}'.format( name=show_client.__name__, status=status)) while True: if status == const.DELETED: try: response = show_client(id, **kwargs) except exceptions.NotFound: return else: response = show_client(id, **kwargs) if root_tag: object_details = response[root_tag] else: object_details = response if object_details[status_key] == status: LOG.info('{name}\'s status updated to {status}.'.format( name=show_client.__name__, status=status)) return object_details elif object_details[status_key] == 'ERROR': message = ('{name} {field} updated to an invalid state of ' 'ERROR'.format(name=show_client.__name__, field=status_key)) caller = test_utils.find_test_caller() if caller: message = '({caller}) {message}'.format(caller=caller, message=message) if not error_ok: raise exceptions.UnexpectedResponseCode(message) elif int(time.time()) - start >= check_timeout: message = ( '{name} {field} failed to update to {expected_status} within ' 'the required time {timeout}. Current status of {name}: ' '{status}'.format(name=show_client.__name__, timeout=check_timeout, status=object_details[status_key], expected_status=status, field=status_key)) caller = test_utils.find_test_caller() if caller: message = '({caller}) {message}'.format(caller=caller, message=message) raise exceptions.TimeoutException(message) time.sleep(check_interval)