def test_server_error_with_valid_json_no_code_or_message(self): # test valid json format but no Code or Message def _handle_request(context): context.retry_flag = False context.http_response = Response() context.http_response.status_code = 400 context.http_response.headers = {} context.http_response._content = b"""{"key" : "this is a valid json string"}""" ecs_client = EcsClient(self.client_config, self.init_credentials_provider()) ecs_client.handlers = DEFAULT_HANDLERS with patch.object(http_handler, "handle_request", wraps=_handle_request): try: ecs_client.describe_instances() assert False except ServerException as e: self.assertEqual(400, e.http_status) self.assertEqual("Ecs", e.service_name) self.assertEqual("ecs-cn-hangzhou.aliyuncs.com", e.endpoint) self.assertEqual("SDK.UnknownServerError", e.error_code) if six.PY2: self.assertEqual( 'ServerResponseBody: {"key" : "this is a valid json string"}', e.error_message) else: self.assertEqual( """ServerResponseBody: b'{"key" : "this is a valid json string"}'""", e.error_message)
def test_default_user_agent(self): client_config = self.init_temp_client_config() client = EcsClient(client_config, self.init_credentials_provider()) with MyServer() as s: client.describe_instances() user_agent = s.headers.get('User-Agent') self.assertEqual(self.joint_default_user_agent(), user_agent)
def test_normal_backoff(self): config = self.client_config config.max_retry_times = 10 config.endpoint = "somewhere.you.will.never.get" client = EcsClient(config, self.init_credentials_provider()) request = APIRequest('DescribeInstances', 'GET', 'http', 'RPC') globals()['_test_compute_delay'] = [] def record_sleep(delay): global _test_compute_delay _test_compute_delay.append(delay) with patch.object(time, "sleep", wraps=record_sleep) as monkey: try: client._handle_request(request) assert False except HttpErrorException as e: self.assertTrue( e.error_message.startswith( "HTTPConnectionPool(host='somewhere.you.will.never.get', port=80)" )) # self.assertEqual(10, monkey.call_count) self.assertEqual([0.1, 0.2, 0.4, 0.8, 1.6, 3.2, 6.4, 12.8, 20.0, 20.0], _test_compute_delay)
def test_missing_message_in_response2(self): # test missing Code in response def _handle_request(context): context.retry_flag = False context.http_response = Response() context.http_response.status_code = 400 context.http_response.headers = {} context.http_response._content = b"{\"Code\": \"YouMessedSomethingUp\"}" ecs_client = EcsClient(self.client_config, self.init_credentials_provider()) ecs_client.handlers = DEFAULT_HANDLERS with patch.object(http_handler, "handle_request", wraps=_handle_request): try: ecs_client.describe_regions() assert False except ServerException as e: self.assertEqual(400, e.http_status) self.assertEqual("Ecs", e.service_name) self.assertEqual("ecs-cn-hangzhou.aliyuncs.com", e.endpoint) self.assertEqual("YouMessedSomethingUp", e.error_code) if six.PY2: self.assertEqual('ServerResponseBody: {"Code": "YouMessedSomethingUp"}', e.error_message) else: self.assertEqual("""ServerResponseBody: b'{"Code": "YouMessedSomethingUp"}'""", e.error_message)
def test_server_error_with_a_bad_json(self): def _handle_request(context): context.retry_flag = False context.http_response = Response() context.http_response.status_code = 400 context.http_response.headers = {} context.http_response._content = b"bad-json" ecs_client = EcsClient(self.client_config, self.init_credentials_provider()) ecs_client.handlers = DEFAULT_HANDLERS with patch.object(http_handler, "handle_request", wraps=_handle_request): try: ecs_client.delete_instance() assert False except ServerException as e: self.assertEqual(400, e.http_status) self.assertEqual("Ecs", e.service_name) self.assertEqual("ecs-cn-hangzhou.aliyuncs.com", e.endpoint) self.assertEqual("SDK.UnknownServerError", e.error_code) if six.PY2: self.assertEqual('ServerResponseBody: bad-json', e.error_message) else: self.assertEqual("ServerResponseBody: b'bad-json'", e.error_message)
def test_client_customized_timeout(self): config = self.client_config config.read_timeout = 7 config.connection_timeout = 8 client = EcsClient(config, self.init_credentials_provider()) api_request = APIRequest('DescribeInstances', 'GET', 'http', 'RPC') context = client._handle_request(api_request, _raise_exception=False) self.assertEqual((8, 7), context.http_request.timeout)
def test_default_timeout(self): config = self.client_config config.connection_timeout = None config.enable_retry = False client = EcsClient(config, self.init_credentials_provider()) api_request = APIRequest('DescribeInstances', 'GET', 'http', 'RPC') context = client._handle_request(api_request, _raise_exception=False) self.assertEqual((5, 10), context.http_request.timeout)
def test_server_error_normal(self): ecs_client = EcsClient(self.client_config, self.init_credentials_provider()) try: ecs_client.delete_instance(instance_id="blah") assert False except ServerException as e: self.assertEqual("InvalidInstanceId.NotFound", e.error_code) self.assertEqual("The specified InstanceId does not exist.", e.error_message)
def test_stream_logger(self, formatter, get_logger): client = EcsClient(self.client_config, self.init_credentials_provider()) client.add_stream_log_handler(logger_name='foo.bar', log_level=40, format_string='foo') get_logger.assert_called_with('foo.bar') get_logger.return_value.setLevel.assert_called_with(logging.ERROR) formatter.assert_called_with('foo')
def test_server_timeout(self): self.client_config.read_timeout = 0.001 ecs_client = EcsClient(self.client_config, self.init_credentials_provider()) try: ecs_client.create_instance(image_id="coreos_1745_7_0_64_30G_alibase_20180705.vhd", instance_type="ecs.cn-hangzhou.invalid", system_disk_category="cloud_ssd") assert False except HttpErrorException as e: self.assertEqual("HTTPConnectionPool(host='ecs-cn-hangzhou.aliyuncs.com'," " port=80): Read timed out. (read timeout=0.001)", e.error_message)
def test_rpc_query_list(self): # check one ecs_client = EcsClient(self.client_config, self.init_credentials_provider()) tag = 'hi' try: context = ecs_client.describe_tags(list_of_tag=tag) assert False except ParamValidationException as e: if six.PY2: self.assertEqual(e.error_message, "Parameter validation failed: Invalid type for parameter Tag, value: hi, type: <type 'str'>, valid types: <type 'list'>") else: self.assertEqual(e.error_message, "Parameter validation failed: Invalid type for parameter Tag, value: hi, type: <class 'str'>, valid types: <class 'list'>")
def test_no_retry(self): client = EcsClient(self.client_config, self.init_credentials_provider()) tempdir = tempfile.mkdtemp() temp_file = os.path.join(tempdir, 'file_logger') client.add_rotating_file_log_handler(log_level=logging.DEBUG, path=temp_file) context = client.describe_instances() self.assertTrue(os.path.isfile(temp_file)) with open(temp_file) as logfile: s = logfile.read() self.assertTrue('alibabacloud-' in s) self.assertTrue('DEBUG' in s)
def test_rpc_query_get(self): # TODO ecs_client = EcsClient(self.client_config, self.init_credentials_provider()) tag = "hi" try: context = ecs_client.add_tags(list_of_tag=tag, resource_type="instance", resource_id="i-bp13ozj6v9ckzcq8sjxw") assert False except ParamValidationException as e: if six.PY2: self.assertEqual(e.error_message, "Parameter validation failed: Invalid type for parameter Tag, value: hi, type: <type 'str'>, valid types: <type 'list'>") else: self.assertEqual(e.error_message, "Parameter validation failed: Invalid type for parameter Tag, value: hi, type: <class 'str'>, valid types: <class 'list'>")
def test_default_retry_times(self): config = self.client_config config.endpoint = "somewhere.you.will.never.get" client = EcsClient(config, self.init_credentials_provider()) with patch.object(client.handlers[-1], "handle_request", wraps=client.handlers[-1].handle_request) as monkey: try: context = client.describe_instances() assert False except HttpErrorException as e: self.assertTrue( e.error_message.startswith( "HTTPConnectionPool(host='somewhere.you.will.never.get', port=80):" " Max retries exceeded with url:")) self.assertEqual(4, monkey.call_count)
def test_no_retry(self): config = self.client_config config.enable_retry = False config.endpoint = 'somewhere.you.never' client = EcsClient(config, self.init_credentials_provider()) with patch.object(client, "_handle_request", wraps=client._handle_request) as monkey: try: context = client.describe_instances() assert False except HttpErrorException as e: self.assertTrue(e.error_message.startswith( "HTTPConnectionPool(host='somewhere.you.never', port=80): " "Max retries exceeded with url: /")) self.assertEqual(1, monkey.call_count)
def test_no_retry_on_parameter_invalid(self): config = self.client_config client = EcsClient(config, self.init_credentials_provider()) with patch.object(client.handlers[-1], "handle_request", wraps=client.handlers[-1].handle_request) as monkey: try: context = client.run_instances() assert False except ServerException as e: self.assertEqual(e.http_status, 400) self.assertEqual(e.service_name, 'Ecs') self.assertEqual(e.error_code, 'MissingParameter') self.assertTrue( e.error_message.startswith( "The input parameter ImageId that is")) self.assertEqual(e.endpoint, 'ecs-cn-hangzhou.aliyuncs.com') self.assertEqual(1, monkey.call_count)
def test_config_enable_default(self): config = self.client_config self.assertEqual(config.enable_https, True) self.assertEqual(config.enable_retry, True) self.assertEqual(config.enable_http_debug, False) client = EcsClient(config, self.init_credentials_provider()) self.assertEqual(client.config.enable_https, True) self.assertEqual(client.config.enable_retry, True) self.assertEqual(client.config.enable_http_debug, False)
def test_config_enable_custom(self): config = self.client_config config.enable_http_debug = True config.enable_https = False config.enable_retry = False client = EcsClient(config, self.init_credentials_provider()) self.assertEqual(client.config.enable_https, False) self.assertEqual(client.config.enable_retry, False) self.assertEqual(client.config.enable_http_debug, True)
def test_invalid_max_retry_times(self): config = self.client_config config.max_retry_times = -1 try: client = EcsClient(config, self.init_credentials_provider()) assert False except ParamTypeInvalidException as e: self.assertEqual( "The type of param max_retry_times must be positive integer.", e.error_message)
def test_rpc_query_list(self): ecs_client = EcsClient(self.client_config, self.init_credentials_provider()) tag = [ {"xxx": 123, "aaaa": 456, }, {"Key": 234, "qqq": 345, }, ] try: context = ecs_client.add_tags(list_of_tag=tag, resource_type="instance", resource_id="i-bp13ozj6v9ckzcq8sjxw") assert False except ServerException as e: self.assertEqual(e.http_status, 400) self.assertEqual(e.endpoint, 'ecs-cn-hangzhou.aliyuncs.com') self.assertEqual(e.error_code, 'InvalidTagValue.Malformed') self.assertEqual(e.error_message, 'The specified Tag.n.Value is not valid.')
def test_config_from_env(self): config = self.client_config os.environ.setdefault('HTTPS_PROXY', 'https://alibabacloud-sdk.com') os.environ.setdefault('HTTP_PROXY', 'http://alibabacloud-sdk.com') os.environ.setdefault('DEBUG', 'sdk') client = EcsClient(config, self.init_credentials_provider()) self.assertEqual(client.config.enable_http_debug, False) os.environ.pop('HTTPS_PROXY') os.environ.pop('HTTP_PROXY') os.environ.pop('DEBUG')
def test_retry_with_client_token(self): config = self.client_config client = EcsClient(config, self.init_credentials_provider()) client.max_retry_times = 3 client.handlers = DEFAULT_HANDLERS api_request = APIRequest('CreateInstance', 'GET', 'http', 'RPC') api_request._params = { 'ImageId': "coreos_1745_7_0_64_30G_alibase_20180705.vhd", 'InstanceType': "ecs.n2.small", } globals()['_test_client_token'] = None globals()['_test_retry_times'] = 0 def _handle_request(context): global _test_client_token global _test_retry_times context.retry_flag = False request = context.api_request if _test_retry_times > 0: assert _test_client_token == request._params.get("ClientToken") _test_retry_times += 1 _test_client_token = request._params.get("ClientToken") context.exception = HttpErrorException(http_error="some error") from alibabacloud.request import HTTPResponse context.http_response = HTTPResponse('', None, {}, None) def no_sleep(delay): pass with patch.object(time, "sleep", no_sleep): with patch.object(client.handlers[6], "handle_request", wraps=_handle_request) as monkey: try: ret = client._handle_request(api_request) assert False except HttpErrorException as e: self.assertEqual("some error", e.error_message) self.assertEqual(4, monkey.call_count)
def test_missing_message_in_response(self): # test missing message in response def _handle_request(context): context.retry_flag = False context.http_response = Response() context.http_response.status_code = 400 context.http_response.headers = {} context.http_response._content = b"{\"Message\": \"Some message\"}" ecs_client = EcsClient(self.client_config, self.init_credentials_provider()) ecs_client.handlers = DEFAULT_HANDLERS with patch.object(http_handler, "handle_request", wraps=_handle_request): try: ecs_client.describe_regions() assert False except ServerException as e: self.assertEqual(400, e.http_status) self.assertEqual("Ecs", e.service_name) self.assertEqual("ecs-cn-hangzhou.aliyuncs.com", e.endpoint) self.assertEqual("SDK.UnknownServerError", e.error_code) self.assertEqual("""Some message""", e.error_message)
def test_endpoint_comes_from_location_service(self): temp_client = self.temp_client('ECS', None, None, 'ecs') self.init_env(temp_client.config, temp_client.credentials_provider, "{}") # empty local config from alibabacloud.clients.ecs_20140526 import EcsClient ecs_client = EcsClient(self.client_config, self.init_credentials_provider()) ecs_client.describe_regions() ecs_client.endpoint_resolver = DefaultEndpointResolver( ecs_client.config, ecs_client.credentials_provider) with patch.object(self._location_service_endpoint_resolver, '_call_location_service', wraps=self._location_service_endpoint_resolver. _call_location_service) as monkey: for i in range(3): self.assertEqual( "ecs-cn-hangzhou.aliyuncs.com", ecs_client.endpoint_resolver.resolve( self.resolve_request("cn-hangzhou", "ecs", "ecs", None))) self.assertEqual(0, monkey.call_count)
def test_retry_to_create_instance(self): config = ClientConfig(region_id=self.region_id, connection_timeout=120, endpoint="nowhere") client = EcsClient(config, self.init_credentials_provider()) from alibabacloud.services.ecs import ECSResource with patch.object(client.handlers[-1], "handle_request", wraps=client.handlers[-1].handle_request) as monkey: ecs_resource = ECSResource(_client=client) try: ecs_resource.create_instance(image_id=self.image_id, instance_type="ecs.n2.small") assert False except HttpErrorException as e: pass self.assertEqual(4, monkey.call_count)
def test_connect_timeout_priority(self): # read config config = self.client_config config.connection_timeout = "20" client = EcsClient(config, self.init_credentials_provider()) api_request = APIRequest('RunInstances', 'GET', 'http', 'RPC') context = client._handle_request(api_request, _raise_exception=False) self.assertEqual((20.0, 86), context.http_request.timeout) # read file config = self.client_config config.connection_timeout = None client = EcsClient(config, self.init_credentials_provider()) context = client._handle_request(api_request, _raise_exception=False) self.assertEqual((5, 86), context.http_request.timeout)
def test_throttled_backoff(self): def _handle_response(context): context.exception = ServerException("Throttling", "some error") config = self.client_config config.max_retry_times = 10 config.endpoint = "somewhere.you.will.never.get" client = EcsClient(config, self.init_credentials_provider()) api_request = APIRequest('DescribeInstances', 'GET', 'http', 'RPC') globals()["_test_compute_delay"] = [] def record_sleep(delay): global _test_compute_delay _test_compute_delay.append(delay) from alibabacloud.handlers.api_protocol_handler import APIProtocolHandler from alibabacloud.handlers.credentials_handler import CredentialsHandler from alibabacloud.handlers.signer_handler import SignerHandler from alibabacloud.handlers.timeout_config_reader import TimeoutConfigReader from alibabacloud.handlers.endpoint_handler import EndpointHandler from alibabacloud.handlers.retry_handler import RetryHandler from alibabacloud.handlers.server_error_handler import ServerErrorHandler from alibabacloud.handlers.http_handler import HttpHandler DEFAULT_HANDLERS = [ RetryHandler(), APIProtocolHandler(), CredentialsHandler(), SignerHandler(), TimeoutConfigReader(), EndpointHandler(), ServerErrorHandler(), HttpHandler(), ] client.handlers = DEFAULT_HANDLERS client.config = config with patch.object(time, "sleep", wraps=record_sleep) as monkey: with patch.object(ServerErrorHandler, "handle_response", wraps=_handle_response): try: client._handle_request(api_request) assert False except ServerException as e: self.assertEqual("Throttling", e.error_code) self.assertEqual(10, monkey.call_count) self.assertEqual(10, len(_test_compute_delay))
def test_doc_help_sample(self): self.client_config.endpoint = "ecs-cn-hangzhou.aliyuncs.com" ecs_client = EcsClient(self.client_config, self.init_credentials_provider()) response = ecs_client.describe_instances() self.assertTrue(response.get('RequestId'))
def test_retry_conditions(self): import alibabacloud.retry.retry_policy as retry_policy from alibabacloud.retry.retry_condition import RetryCondition from alibabacloud.retry.retry_policy_context import RetryPolicyContext config = self.client_config client = EcsClient(config, self.init_credentials_provider()) default_retry_policy = retry_policy.get_default_retry_policy() def HE(): return HttpErrorException(http_error="some error") def SE(code): return ServerException(code, "some error") def _get_retryable(*conditions): context = RetryPolicyContext(*conditions) return default_retry_policy.should_retry(context) def _assert_not_retryable(*conditions): retryable = _get_retryable(*conditions) self.assertTrue(retryable & RetryCondition.NO_RETRY) def _assert_retryable(*conditions): retryable = _get_retryable(*conditions) self.assertFalse(retryable & RetryCondition.NO_RETRY) def _assert_retryable_with_client_token(request): conditions = [ request, SE("InternalError"), 0, 500, 'ecs', '2014-05-26' ] retryable = _get_retryable(*conditions) self.assertTrue( retryable & RetryCondition.SHOULD_RETRY_WITH_THROTTLING_BACKOFF) def _assert_not_retryable_with_client_token(request): conditions = [ request, SE("InternalError"), 0, 500, 'ecs', '2014-05-26' ] retryable = _get_retryable(*conditions) self.assertFalse( retryable & RetryCondition.SHOULD_RETRY_WITH_THROTTLING_BACKOFF) # retryable api_request = APIRequest('DescribeInstances', 'GET', 'http', 'RPC') timeout_exception = HE() invalid_param_excpetion = SE("MissingParameter") unknown_error = SE("SDK_UNKNOWN_SERVER_ERROR") internal_error = SE("InternalError") product_code = client.product_code.lower() api_version = client.api_version _assert_retryable(api_request, timeout_exception, 0, 500, product_code, api_version) _assert_retryable(api_request, timeout_exception, 2, 500, product_code, api_version) _assert_retryable(api_request, unknown_error, 0, 500, product_code, api_version) _assert_retryable(api_request, unknown_error, 0, 502, product_code, api_version) _assert_retryable(api_request, unknown_error, 0, 503, product_code, api_version) _assert_retryable(api_request, unknown_error, 0, 504, product_code, api_version) _assert_retryable(api_request, internal_error, 0, 500, product_code, api_version) _assert_retryable(api_request, SE("Throttling"), 0, 400, product_code, api_version) _assert_retryable(api_request, SE("ServiceUnavailable"), 0, 503, product_code, api_version) _assert_not_retryable(api_request, invalid_param_excpetion, 0, 400, product_code, api_version) _assert_not_retryable(api_request, timeout_exception, 3, 500, product_code, api_version) _assert_not_retryable(api_request, SE("InvalidAccessKeyId.NotFound"), 0, 404, product_code, api_version) request1 = APIRequest('DescribeInstanceHistoryEvents', 'GET', 'http', 'RPC') _assert_retryable(request1, SE("ServiceUnavailable"), 0, 503, product_code, api_version) request2 = APIRequest('DescribeDisks', 'GET', 'http', 'RPC') _assert_retryable(request2, SE("ServiceUnavailable"), 0, 503, product_code, api_version) # no_retry no_retry_request = APIRequest('AttachDisk', 'GET', 'http', 'RPC') _assert_not_retryable(no_retry_request, timeout_exception, 0, 500, product_code, api_version) _assert_not_retryable(no_retry_request, unknown_error, 0, 504, product_code, api_version) _assert_not_retryable(no_retry_request, invalid_param_excpetion, 0, 400, product_code, api_version) request1 = APIRequest('CreateInstance', 'GET', 'http', 'RPC') _assert_retryable_with_client_token(request1) request1 = APIRequest('RunInstances', 'GET', 'http', 'RPC') _assert_retryable_with_client_token(request1) request1 = APIRequest('AttachDisk', 'GET', 'http', 'RPC') _assert_not_retryable_with_client_token(request1) request1 = APIRequest('DescribeInstances', 'GET', 'http', 'RPC') _assert_not_retryable_with_client_token(request1)
def test_call_rpc_request_with_client(self): ecs_client = EcsClient(self.client_config, self.init_credentials_provider()) response = ecs_client.describe_regions() self.assertTrue(response.get('RequestId'))