Example #1
0
    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)
Example #4
0
    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)
Example #5
0
    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)
Example #8
0
 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')
Example #10
0
    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)
Example #17
0
 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)
Example #18
0
 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.')
Example #21
0
    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)
Example #23
0
    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'))