def test_insert_image(self): """ A test case for insert_image. """ # Set request param. image_lib = 'baiduyun_test' source = 'http://baidu.com/test.jpg' description = 'for test' # Set mock. error = {'code': 'InvalidLibName', 'message': 'invalid libName'} headers = {'status': 'failed', 'source': source, 'lib': image_lib, 'description': description} response_mock = BceResponse() response_mock.set_metadata_from_headers(headers) response_mock.error = dict_to_python_object(error) self.the_client._send_request = mock.Mock(return_value=response_mock) # Run. response = self.the_client.insert_image(image_lib, source, description=description) # Validate result. self.assertEqual(response.status, response_mock.status) self.assertEqual(response.source, response_mock.source) self.assertEqual(response.lib, response_mock.lib) self.assertEqual(response.description, response_mock.description) self.assertEqual(response.error.code, response_mock.error.code) self.assertEqual(response.error.message, response_mock.error.message)
def test_search_image_by_image(self): """ A test case for search_image_by_image. """ # Set request param. image_lib = 'baiduyun_test' source = 'http://baidu.com/test.jpg' description = 'for test' # Set mock. result_item = {'score': 99.9, 'source': source, 'description': 'test'} results = [dict_to_python_object(result_item)] headers = {'status': 'failed', 'source': source, 'lib': image_lib, 'description': description} response_mock = BceResponse() response_mock.set_metadata_from_headers(headers) response_mock.results = results self.the_client._send_request = mock.Mock(return_value=response_mock) # Run. response = self.the_client.search_image_by_image(image_lib, source, description=description) # Validate result. self.assertEqual(response.status, response_mock.status) self.assertEqual(response.source, response_mock.source) self.assertEqual(response.lib, response_mock.lib) self.assertEqual(response.description, response_mock.description) self.assertEqual(response.results[0].score, response_mock.results[0].score) self.assertEqual(response.results[0].source, response_mock.results[0].source) self.assertEqual(response.results[0].description, response_mock.results[0].description)
def test_parse_json(self): """test abort parse_json function in handler""" # test has body json_content = {"message": "error", "code": 123, "requestId": 12345} http_response = MockHttpResponse(status=508, content=json.dumps(json_content)) response = BceResponse() self.assertTrue(handler.parse_json(http_response, response)) self.assertTrue(hasattr(response, "message")) self.assertTrue(hasattr(response, "code")) self.assertTrue(hasattr(response, "request_id")) # test doesn't have body http_response = MockHttpResponse(status=508) response = BceResponse() old_len = len(response.__dict__) self.assertTrue(handler.parse_json(http_response, response)) self.assertEqual(len(response.__dict__), old_len)
def test_parse_error(self): """test abort parse_error function in handler""" # test normal 2xx http_response = MockHttpResponse(status=208) self.assertFalse(handler.parse_error(http_response, None)) # test abnormal 1xx http_response = MockHttpResponse(status=108) err = None try: handler.parse_error(http_response, None) except BceClientError as e: err = e finally: self.assertIsNotNone(err) # test abnormal 3xx 4xx 5xx with json body json_content = {"message": "error", "code": 123, "requestId": 12345} http_response = MockHttpResponse(status=508, content=json.dumps(json_content)) err = None try: handler.parse_error(http_response, None) except BceServerError as e: err = e finally: self.assertIsNotNone(err) self.assertEqual(compat.convert_to_string(err), "error") self.assertEqual(err.code, 123) self.assertEqual(err.request_id, 12345) self.assertEqual(err.status_code, 508) # test abnormal 3xx 4xx 5xx without json body http_response = MockHttpResponse(status=508) response = BceResponse() response.metadata.bce_request_id = 12345 err = None try: handler.parse_error(http_response, response) except BceServerError as e: err = e finally: self.assertIsNotNone(err) self.assertEqual(compat.convert_to_string(err), "Mock") self.assertEqual(err.request_id, 12345) self.assertEqual(err.status_code, 508)
def send_request(config, sign_function, response_handler_functions, http_method, path, body, headers, params): """ Send request to BCE services. :param config :type config: baidubce.BceClientConfiguration :param sign_function: :param response_handler_functions: :type response_handler_functions: list :param request: :type request: baidubce.internal.InternalRequest :return: :rtype: baidubce.BceResponse """ _logger.debug(b'%s request start: %s %s, %s, %s', http_method, path, headers, params, body) headers = headers or {} user_agent = 'bce-sdk-python/%s/%s/%s' % (compat.convert_to_string( baidubce.SDK_VERSION), sys.version, sys.platform) user_agent = user_agent.replace('\n', '') user_agent = compat.convert_to_bytes(user_agent) headers[http_headers.USER_AGENT] = user_agent should_get_new_date = False if http_headers.BCE_DATE not in headers: should_get_new_date = True headers[http_headers.HOST] = config.endpoint if isinstance(body, str): body = body.encode(baidubce.DEFAULT_ENCODING) if not body: headers[http_headers.CONTENT_LENGTH] = 0 elif isinstance(body, bytes): headers[http_headers.CONTENT_LENGTH] = len(body) elif http_headers.CONTENT_LENGTH not in headers: raise ValueError(b'No %s is specified.' % http_headers.CONTENT_LENGTH) # store the offset of fp body offset = None if hasattr(body, "tell") and hasattr(body, "seek"): offset = body.tell() protocol, host, port = utils.parse_host_port(config.endpoint, config.protocol) headers[http_headers.HOST] = host if port != config.protocol.default_port: headers[http_headers.HOST] += b':' + compat.convert_to_bytes(port) headers[http_headers.AUTHORIZATION] = sign_function( config.credentials, http_method, path, headers, params) encoded_params = utils.get_canonical_querystring(params, False) if len(encoded_params) > 0: uri = path + b'?' + encoded_params else: uri = path check_headers(headers) retries_attempted = 0 errors = [] while True: conn = None try: # restore the offset of fp body when retrying if should_get_new_date is True: headers[http_headers.BCE_DATE] = utils.get_canonical_time() headers[http_headers.AUTHORIZATION] = sign_function( config.credentials, http_method, path, headers, params) if retries_attempted > 0 and offset is not None: body.seek(offset) conn = _get_connection(protocol, host, port, config.connection_timeout_in_mills) _logger.debug( 'request args:method=%s, uri=%s, headers=%s,patams=%s, body=%s', http_method, uri, headers, params, body) http_response = _send_http_request(conn, http_method, uri, headers, body, config.send_buf_size) headers_list = http_response.getheaders() # on py3 ,values of headers_list is decoded with ios-8859-1 from # utf-8 binary bytes # headers_list[*][0] is lowercase on py2 # headers_list[*][0] is raw value py3 if compat.PY3 and isinstance(headers_list, list): temp_heads = [] for k, v in headers_list: k = k.encode('latin-1').decode('utf-8') v = v.encode('latin-1').decode('utf-8') k = k.lower() temp_heads.append((k, v)) headers_list = temp_heads _logger.debug('request return: status=%d, headers=%s' % (http_response.status, headers_list)) response = BceResponse() response.set_metadata_from_headers(dict(headers_list)) for handler_function in response_handler_functions: if handler_function(http_response, response): break return response except Exception as e: if conn is not None: conn.close() # insert ">>>>" before all trace back lines and then save it errors.append('\n'.join( '>>>>' + line for line in traceback.format_exc().splitlines())) if config.retry_policy.should_retry(e, retries_attempted): delay_in_millis = config.retry_policy.get_delay_before_next_retry_in_millis( e, retries_attempted) time.sleep(delay_in_millis / 1000.0) else: raise BceHttpClientError( 'Unable to execute HTTP request. Retried %d times. ' 'All trace backs:\n%s' % (retries_attempted, '\n'.join(errors)), e) retries_attempted += 1
def send_request( config, sign_function, response_handler_functions, http_method, path, body, headers, params): """ Send request to BCE services. :param config :type config: baidubce.BceClientConfiguration :param sign_function: :param response_handler_functions: :type response_handler_functions: list :param request: :type request: baidubce.internal.InternalRequest :return: :rtype: baidubce.BceResponse """ _logger.debug('%s request start: %s %s, %s, %s', http_method, path, headers, params, body) headers = headers or {} user_agent = 'bce-sdk-python/%s/%s/%s' % ( baidubce.SDK_VERSION, sys.version, sys.platform) user_agent = user_agent.replace('\n', '') headers[http_headers.USER_AGENT] = user_agent should_get_new_date = False if http_headers.BCE_DATE not in headers: should_get_new_date = True headers[http_headers.HOST] = config.endpoint if isinstance(body, unicode): body = body.encode(baidubce.DEFAULT_ENCODING) if not body: headers[http_headers.CONTENT_LENGTH] = 0 elif isinstance(body, str): headers[http_headers.CONTENT_LENGTH] = len(body) elif http_headers.CONTENT_LENGTH not in headers: raise ValueError('No %s is specified.' % http_headers.CONTENT_LENGTH) # store the offset of fp body offset = None if hasattr(body, "tell") and hasattr(body, "seek"): offset = body.tell() protocol, host, port = utils.parse_host_port(config.endpoint, config.protocol) headers[http_headers.HOST] = host if port != config.protocol.default_port: headers[http_headers.HOST] += ':' + str(port) headers[http_headers.AUTHORIZATION] = sign_function( config.credentials, http_method, path, headers, params) encoded_params = utils.get_canonical_querystring(params, False) if len(encoded_params) > 0: uri = path + '?' + encoded_params else: uri = path check_headers(headers) retries_attempted = 0 errors = [] while True: conn = None try: # restore the offset of fp body when retrying if should_get_new_date is True: headers[http_headers.BCE_DATE] = utils.get_canonical_time() headers[http_headers.AUTHORIZATION] = sign_function( config.credentials, http_method, path, headers, params) if retries_attempted > 0 and offset is not None: body.seek(offset) conn = _get_connection(protocol, host, port, config.connection_timeout_in_mills) http_response = _send_http_request( conn, http_method, uri, headers, body, config.send_buf_size) headers_list = http_response.getheaders() _logger.debug( 'request return: status=%d, headers=%s' % (http_response.status, headers_list)) response = BceResponse() response.set_metadata_from_headers(dict(headers_list)) for handler_function in response_handler_functions: if handler_function(http_response, response): break return response except Exception as e: if conn is not None: conn.close() # insert ">>>>" before all trace back lines and then save it errors.append('\n'.join('>>>>' + line for line in traceback.format_exc().splitlines())) if config.retry_policy.should_retry(e, retries_attempted): delay_in_millis = config.retry_policy.get_delay_before_next_retry_in_millis( e, retries_attempted) time.sleep(delay_in_millis / 1000.0) else: raise BceHttpClientError('Unable to execute HTTP request. Retried %d times. ' 'All trace backs:\n%s' % (retries_attempted, '\n'.join(errors)), e) retries_attempted += 1