From eba44ffb458e0c0053f529e41637415666140582 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=82=B9=E6=96=87=E6=9D=B0?= <72617766+19916302128@users.noreply.github.com> Date: Tue, 3 Sep 2024 11:52:36 +0800 Subject: [PATCH 1/3] Add files via upload --- 1hunyuan/__init__.py | 0 1hunyuan/test_chat_completions.py | 62 +++++++++ 1hunyuan/test_chat_completions_request.py | 67 ++++++++++ 1hunyuan/test_chat_completions_response.py | 47 +++++++ 1hunyuan/test_hunyuan_choice.py | 28 ++++ 1hunyuan/test_hunyuan_content.py | 30 +++++ 1hunyuan/test_hunyuan_delta.py | 27 ++++ 1hunyuan/test_hunyuan_embedding_data.py | 31 +++++ 1hunyuan/test_hunyuan_embedding_usage.py | 25 ++++ 1hunyuan/test_hunyuan_error_msg.py | 26 ++++ 1hunyuan/test_hunyuan_get_embedding.py | 39 ++++++ .../test_hunyuan_get_embedding_request.py | 21 +++ .../test_hunyuan_get_embedding_response.py | 27 ++++ 1hunyuan/test_hunyuan_get_token_count.py | 40 ++++++ .../test_hunyuan_get_token_count_request.py | 18 +++ .../test_hunyuan_get_token_count_response.py | 31 +++++ 1hunyuan/test_hunyuan_image_url.py | 18 +++ 1hunyuan/test_hunyuan_message.py | 39 ++++++ 1hunyuan/test_hunyuan_tool.py | 26 ++++ 1hunyuan/test_hunyuan_tool_call.py | 30 +++++ 1hunyuan/test_hunyuan_tool_call_function.py | 25 ++++ 1hunyuan/test_hunyuan_tool_function.py | 30 +++++ 1hunyuan/test_hunyuan_usage.py | 31 +++++ .../test_query_hunyuan_image_job_request.py | 18 +++ .../test_query_hunyuan_image_job_response.py | 57 ++++++++ 1hunyuan/test_submit_hunyuan_image_job.py | 39 ++++++ .../test_submit_hunyuan_image_job_request.py | 37 ++++++ .../test_submit_hunyuan_image_job_response.py | 21 +++ common/__init__.py | 0 common/test.log | 0 common/test_build_req_inter.py | 36 ++++++ ...test_build_req_with_old_signature_inter.py | 41 ++++++ common/test_build_req_without_signature.py | 122 ++++++++++++++++++ common/test_call_with_region_breaker.py | 49 +++++++ common/test_cvm_role_credential_init.py | 26 ++++ common/test_default_credential_provider.py | 69 ++++++++++ ...test_default_tke_oidc_role_arn_provider.py | 15 +++ common/test_empty_handle.py | 14 ++ .../test_environment_variable_credential.py | 29 +++++ common/test_get_role_name.py | 17 +++ common/test_https_pre_conn_pool.py | 11 ++ common/test_init_credential.py | 32 +++++ common/test_need_refresh_has_None.py | 11 ++ common/test_oidc_role_arn_credential.py | 73 +++++++++++ common/test_on_failure.py | 31 +++++ common/test_on_success_or_failure.py | 36 ++++++ .../test_params_is_dict_and_format_params.py | 67 ++++++++++ common/test_pre_conn_adapter.py | 8 ++ common/test_process_response.py | 25 ++++ common/test_process_response_sse.py | 97 ++++++++++++++ .../test_profile_credential_get_credential.py | 12 ++ common/test_response_pretty_formatter.py | 36 ++++++ common/test_set_file_logger.py | 15 +++ common/test_set_stream_logger.py | 12 ++ .../test_sts_assume_role_credential_init.py | 41 ++++++ common/test_switch_state.py | 12 ++ common/test_tencent_cloud_sdk_exception.py | 10 ++ common/test_to_new_generation.py | 22 ++++ 58 files changed, 1859 insertions(+) create mode 100644 1hunyuan/__init__.py create mode 100644 1hunyuan/test_chat_completions.py create mode 100644 1hunyuan/test_chat_completions_request.py create mode 100644 1hunyuan/test_chat_completions_response.py create mode 100644 1hunyuan/test_hunyuan_choice.py create mode 100644 1hunyuan/test_hunyuan_content.py create mode 100644 1hunyuan/test_hunyuan_delta.py create mode 100644 1hunyuan/test_hunyuan_embedding_data.py create mode 100644 1hunyuan/test_hunyuan_embedding_usage.py create mode 100644 1hunyuan/test_hunyuan_error_msg.py create mode 100644 1hunyuan/test_hunyuan_get_embedding.py create mode 100644 1hunyuan/test_hunyuan_get_embedding_request.py create mode 100644 1hunyuan/test_hunyuan_get_embedding_response.py create mode 100644 1hunyuan/test_hunyuan_get_token_count.py create mode 100644 1hunyuan/test_hunyuan_get_token_count_request.py create mode 100644 1hunyuan/test_hunyuan_get_token_count_response.py create mode 100644 1hunyuan/test_hunyuan_image_url.py create mode 100644 1hunyuan/test_hunyuan_message.py create mode 100644 1hunyuan/test_hunyuan_tool.py create mode 100644 1hunyuan/test_hunyuan_tool_call.py create mode 100644 1hunyuan/test_hunyuan_tool_call_function.py create mode 100644 1hunyuan/test_hunyuan_tool_function.py create mode 100644 1hunyuan/test_hunyuan_usage.py create mode 100644 1hunyuan/test_query_hunyuan_image_job_request.py create mode 100644 1hunyuan/test_query_hunyuan_image_job_response.py create mode 100644 1hunyuan/test_submit_hunyuan_image_job.py create mode 100644 1hunyuan/test_submit_hunyuan_image_job_request.py create mode 100644 1hunyuan/test_submit_hunyuan_image_job_response.py create mode 100644 common/__init__.py create mode 100644 common/test.log create mode 100644 common/test_build_req_inter.py create mode 100644 common/test_build_req_with_old_signature_inter.py create mode 100644 common/test_build_req_without_signature.py create mode 100644 common/test_call_with_region_breaker.py create mode 100644 common/test_cvm_role_credential_init.py create mode 100644 common/test_default_credential_provider.py create mode 100644 common/test_default_tke_oidc_role_arn_provider.py create mode 100644 common/test_empty_handle.py create mode 100644 common/test_environment_variable_credential.py create mode 100644 common/test_get_role_name.py create mode 100644 common/test_https_pre_conn_pool.py create mode 100644 common/test_init_credential.py create mode 100644 common/test_need_refresh_has_None.py create mode 100644 common/test_oidc_role_arn_credential.py create mode 100644 common/test_on_failure.py create mode 100644 common/test_on_success_or_failure.py create mode 100644 common/test_params_is_dict_and_format_params.py create mode 100644 common/test_pre_conn_adapter.py create mode 100644 common/test_process_response.py create mode 100644 common/test_process_response_sse.py create mode 100644 common/test_profile_credential_get_credential.py create mode 100644 common/test_response_pretty_formatter.py create mode 100644 common/test_set_file_logger.py create mode 100644 common/test_set_stream_logger.py create mode 100644 common/test_sts_assume_role_credential_init.py create mode 100644 common/test_switch_state.py create mode 100644 common/test_tencent_cloud_sdk_exception.py create mode 100644 common/test_to_new_generation.py diff --git a/1hunyuan/__init__.py b/1hunyuan/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/1hunyuan/test_chat_completions.py b/1hunyuan/test_chat_completions.py new file mode 100644 index 000000000..d4a69c664 --- /dev/null +++ b/1hunyuan/test_chat_completions.py @@ -0,0 +1,62 @@ +import json +import os +import types + +import pytest + +from tencentcloud.common import credential +from tencentcloud.common.exception import TencentCloudSDKException +from tencentcloud.common.profile.client_profile import ClientProfile +from tencentcloud.common.profile.http_profile import HttpProfile +from tencentcloud.hunyuan.v20230901 import hunyuan_client, models + + +def test_chat_completions(): + cred = credential.Credential( + os.environ.get("TENCENTCLOUD_SECRET_ID"), + os.environ.get("TENCENTCLOUD_SECRET_KEY")) + httpProfile = HttpProfile() + httpProfile.endpoint = "hunyuan.tencentcloudapi.com" + + clientProfile = ClientProfile() + clientProfile.httpProfile = httpProfile + client = hunyuan_client.HunyuanClient(cred, "", clientProfile) + + req = models.ChatCompletionsRequest() + params = { + "Model": "hunyuan-pro", + "Messages": [ + { + "Role": "user", + "Content": "你好啊,早上好" + } + ] + } + req.from_json_string(json.dumps(params)) + + # 返回的resp是一个ChatCompletionsResponse的实例,与请求对象对应 + resp = client.ChatCompletions(req) + assert isinstance(resp, types.GeneratorType) is False + + req1 = models.ChatCompletionsRequest() + params = { + "Model": "hunyuan-pro", + "Messages": [ + { + "Role": "user", + "Content": "你好啊,早上好" + } + ], + "Stream": True + } + req1.from_json_string(json.dumps(params)) + + resp = client.ChatCompletions(req1) + assert isinstance(resp, types.GeneratorType) is True + + +def test_chat_completions_with_exception(): + with pytest.raises(TencentCloudSDKException): + client = hunyuan_client.HunyuanClient(None, "", None) + params = {} + client.ChatCompletions(params) diff --git a/1hunyuan/test_chat_completions_request.py b/1hunyuan/test_chat_completions_request.py new file mode 100644 index 000000000..f8cb62aa3 --- /dev/null +++ b/1hunyuan/test_chat_completions_request.py @@ -0,0 +1,67 @@ +import warnings + +from tencentcloud.hunyuan.v20230901.models import ChatCompletionsRequest + + +def test_chat_completions_request_init(): + request = ChatCompletionsRequest() + request.Model = 'gpt-3.5-turbo-0613' + assert request.Model == 'gpt-3.5-turbo-0613' + + request.Messages = [ + { + 'role': 'user', + 'content': 'Hello, world!' + } + ] + assert request.Messages[0]['role'] == 'user' + assert request.Messages[0]['content'] == 'Hello, world!' + + request.Stream = True + assert request.Stream is True + + request.StreamModeration = True + assert request.StreamModeration is True + + request.TopP = 0.9 + assert request.TopP == 0.9 + + request.Temperature = 0.9 + assert request.Temperature == 0.9 + + request.EnableEnhancement = True + assert request.EnableEnhancement is True + + request.Tools = ['gpt-3.5-turbo-0613', ''] + assert request.Tools == ['gpt-3.5-turbo-0613', ''] + + request.ToolChoice = 'gpt-3.5-turbo-0613' + assert request.ToolChoice == 'gpt-3.5-turbo-0613' + + request.CustomTool = ['gpt-3.5-turbo'] + assert request.CustomTool == ['gpt-3.5-turbo'] + + +def test_chat_completions_request_deserialize(mocker): + request = ChatCompletionsRequest() + params = { + "Model": "TestModel", + "Messages": [{"message_id": 1, "content": "Test message"}], + "Stream": "TestStream", + "StreamModeration": "TestStreamModeration", + "TopP": "TestTopP", + "Temperature": "TestTemperature", + "EnableEnhancement": "TestEnableEnhancement", + "Tools": [1, 2, 3], + "ToolChoice": "TestToolChoice", + "CustomTool": "111", + "test": "test" + } + + with mocker.patch('tencentcloud.hunyuan.v20230901.models.Message._deserialize', return_value=111) as mock_Message, \ + mocker.patch('tencentcloud.hunyuan.v20230901.models.Tool._deserialize', return_value=222) as mock_Tool, \ + warnings.catch_warnings(record=True) as w: + request._deserialize(params) + assert request._Model == 'TestModel' + assert len(request.Messages) == 1 + assert str(w.pop().message) == "test fileds are useless." diff --git a/1hunyuan/test_chat_completions_response.py b/1hunyuan/test_chat_completions_response.py new file mode 100644 index 000000000..2b6e2c098 --- /dev/null +++ b/1hunyuan/test_chat_completions_response.py @@ -0,0 +1,47 @@ +from datetime import datetime + +from tencentcloud.hunyuan.v20230901.models import ChatCompletionsResponse + + +def test_chat_completions_response(): + response = ChatCompletionsResponse() + + response.Created = datetime(year=2020, month=1, day=1) + assert response.Created == datetime(year=2020, month=1, day=1) + + response.Usage = 10 + assert response.Usage == 10 + + response.Note = "test" + assert response.Note == "test" + + response.Id = 123456 + assert response.Id == 123456 + + response.Choices = 1 + assert response.Choices == 1 + + response.RequestId = 'a-dm338d-s3ms3k4s-sa' + assert response.RequestId == 'a-dm338d-s3ms3k4s-sa' + + response.ErrorMsg = "test" + assert response.ErrorMsg == "test" + + +def test_chat_completions_response_deserialize(mocker): + response = ChatCompletionsResponse() + params = { + "Created": "2020-01-01", + "Usage": 10, + "Note": "test", + "Id": 123456, + "Choices": [1, 2, 3], + "RequestId": "a-dm338d-s3ms3k4s-sa", + "ErrorMsg": "test" + } + with mocker.patch('tencentcloud.hunyuan.v20230901.models.Usage._deserialize', return_value=111) as mock_usage, \ + mocker.patch('tencentcloud.hunyuan.v20230901.models.Choice._deserialize', return_value=222) as mock_Choice, \ + mocker.patch('tencentcloud.hunyuan.v20230901.models.ErrorMsg._deserialize', + return_value=333) as mock_ErrorMsg: + response._deserialize(params) + assert response._Created == "2020-01-01" diff --git a/1hunyuan/test_hunyuan_choice.py b/1hunyuan/test_hunyuan_choice.py new file mode 100644 index 000000000..5f3880c6c --- /dev/null +++ b/1hunyuan/test_hunyuan_choice.py @@ -0,0 +1,28 @@ +import warnings +import unittest +from tencentcloud.hunyuan.v20230901.models import Choice + + +def test_hunyuan_choice(): + choice = Choice() + + choice.FinishReason = "test" + assert choice.FinishReason == "test" + + choice.Delta = "test" + assert choice.Delta == "test" + + choice.Message = "test" + assert choice.Message == "test" + + +def test_hunyuan_choice_deserialize(mocker): + choice = Choice() + params = {"Delta": "111", "Message": "222", "FinishReason": "333", "fake": "444"} + with mocker.patch('tencentcloud.hunyuan.v20230901.models.Message._deserialize', return_value=111) as mock_Message, \ + mocker.patch('tencentcloud.hunyuan.v20230901.models.Delta._deserialize', return_value=222) as mock_Delta, \ + warnings.catch_warnings(record=True) as captured_warnings: + choice._deserialize(params) + assert choice._FinishReason == "333" + assert len(captured_warnings) == 1 + assert 'fake fileds are useless.' in str(captured_warnings[0].message) \ No newline at end of file diff --git a/1hunyuan/test_hunyuan_content.py b/1hunyuan/test_hunyuan_content.py new file mode 100644 index 000000000..745305393 --- /dev/null +++ b/1hunyuan/test_hunyuan_content.py @@ -0,0 +1,30 @@ +import warnings + +from tencentcloud.hunyuan.v20230901.models import Content + + +def test_hunyuan_content(): + content = Content() + + content.Type = 1 + content.Text = "111.text" + content.ImageUrl = "https://hunyuan.com" + assert content.Type == 1 + assert content.Text == "111.text" + assert content.ImageUrl == "https://hunyuan.com" + + +def test_hunyuan_deserialize(mocker): + content = Content() + params = { + "Type": 1, + "Text": "111.text", + "ImageUrl": "https://hunyuan.com", + "test": "test" + } + with mocker.patch('tencentcloud.hunyuan.v20230901.models.ImageUrl._deserialize', return_value=111), \ + warnings.catch_warnings(record=True) as captured_warnings: + content._deserialize(params) + assert content._Type == 1 + assert content._Text == "111.text" + assert str(captured_warnings.pop().message) == "test fileds are useless." diff --git a/1hunyuan/test_hunyuan_delta.py b/1hunyuan/test_hunyuan_delta.py new file mode 100644 index 000000000..8e87efee6 --- /dev/null +++ b/1hunyuan/test_hunyuan_delta.py @@ -0,0 +1,27 @@ +import warnings + +from tencentcloud.hunyuan.v20230901.models import Delta, Tool + + +def test_hunyuan_delta(): + delta = Delta() + + delta.Role = 'normal_user' + assert delta.Role == 'normal_user' + + delta.Content = 'hello world' + assert delta.Content == 'hello world' + + delta.ToolCalls = "tool test" + assert delta.ToolCalls == "tool test" + + +def test_hunyuan_delta_deserialize(mocker): + delta = Delta() + params = {'Role': 'normal_user', 'Content': 'hello world', 'ToolCalls': [1, 2, 3], "test": "test"} + with mocker.patch('tencentcloud.hunyuan.v20230901.models.ToolCall._deserialize', return_value=111), \ + warnings.catch_warnings(record=True) as captured_warnings: + delta._deserialize(params) + assert delta.Role == 'normal_user' + assert delta.Content == 'hello world' + assert str(captured_warnings.pop().message) == "test fileds are useless." diff --git a/1hunyuan/test_hunyuan_embedding_data.py b/1hunyuan/test_hunyuan_embedding_data.py new file mode 100644 index 000000000..2b79bfee0 --- /dev/null +++ b/1hunyuan/test_hunyuan_embedding_data.py @@ -0,0 +1,31 @@ +import warnings + +from tencentcloud.hunyuan.v20230901.models import EmbeddingData + + +def test_hunyuan_embedding_data(): + embedding = EmbeddingData() + embedding.Embedding = 'test/embedding/embedding' + assert embedding.Embedding == 'test/embedding/embedding' + + embedding.Index = 'test/embedding/index' + assert embedding.Index == 'test/embedding/index' + + embedding.Object = True + assert embedding.Object is True + + +def test_hunyuan_embedding_data_deserialize(): + embedding = EmbeddingData() + params = { + 'Embedding': 'test/embedding/embedding', + 'Index': 'test/embedding/index', + 'Object': True, + "test": "test" + } + with warnings.catch_warnings(record=True) as w: + embedding._deserialize(params) + assert embedding.Embedding == 'test/embedding/embedding' + assert embedding.Index == 'test/embedding/index' + assert embedding.Object is True + assert str(w.pop().message) == "test fileds are useless." diff --git a/1hunyuan/test_hunyuan_embedding_usage.py b/1hunyuan/test_hunyuan_embedding_usage.py new file mode 100644 index 000000000..c7f09970b --- /dev/null +++ b/1hunyuan/test_hunyuan_embedding_usage.py @@ -0,0 +1,25 @@ +import warnings + +from tencentcloud.hunyuan.v20230901.models import EmbeddingUsage + + +def test_hunyuan_embedding_usage(): + embedding = EmbeddingUsage() + embedding.PromptTokens = 100 + assert embedding.PromptTokens == 100 + embedding.TotalTokens = 1000 + assert embedding.TotalTokens == 1000 + + +def test_hunyuan_embedding_usage_deserialize(): + embedding = EmbeddingUsage() + params = { + "PromptTokens": 100, + "TotalTokens": 1000, + "test": "test" + } + with warnings.catch_warnings(record=True) as w: + embedding._deserialize(params) + assert embedding.PromptTokens == 100 + assert embedding.TotalTokens == 1000 + assert str(w.pop().message) == "test fileds are useless." diff --git a/1hunyuan/test_hunyuan_error_msg.py b/1hunyuan/test_hunyuan_error_msg.py new file mode 100644 index 000000000..e8572a556 --- /dev/null +++ b/1hunyuan/test_hunyuan_error_msg.py @@ -0,0 +1,26 @@ +import warnings + +from tencentcloud.hunyuan.v20230901.models import ErrorMsg + + +def test_hunyuan_error_msg(): + msg = ErrorMsg() + msg.Msg = "Hello World!" + assert msg.Msg == "Hello World!" + + msg.Code = "InternalError" + assert msg.Code == "InternalError" + + +def test_hunyuan_error_msg_deserialize(): + msg = ErrorMsg() + params = { + "Msg": "Hello World!", + "Code": "InternalError", + "test": "test" + } + with warnings.catch_warnings(record=True) as w: + msg._deserialize(params) + assert msg.Msg == "Hello World!" + assert msg.Code == "InternalError" + assert str(w.pop().message) == "test fileds are useless." diff --git a/1hunyuan/test_hunyuan_get_embedding.py b/1hunyuan/test_hunyuan_get_embedding.py new file mode 100644 index 000000000..b3329c7ef --- /dev/null +++ b/1hunyuan/test_hunyuan_get_embedding.py @@ -0,0 +1,39 @@ +import json +import os + +import pytest + +from tencentcloud.common import credential +from tencentcloud.common.exception import TencentCloudSDKException +from tencentcloud.common.profile.client_profile import ClientProfile +from tencentcloud.common.profile.http_profile import HttpProfile +from tencentcloud.hunyuan.v20230901 import hunyuan_client, models + + +def test_hunyuan_get_embedding(): + cred = credential.Credential( + os.environ.get("TENCENTCLOUD_SECRET_ID"), + os.environ.get("TENCENTCLOUD_SECRET_KEY")) + + httpProfile = HttpProfile() + httpProfile.endpoint = "hunyuan.tencentcloudapi.com" + + clientProfile = ClientProfile() + clientProfile.httpProfile = httpProfile + client = hunyuan_client.HunyuanClient(cred, "", clientProfile) + + req = models.GetEmbeddingRequest() + params = { + "Input": "你好" + } + req.from_json_string(json.dumps(params)) + + resp = client.GetEmbedding(req) + assert resp is not None + + +def test_hunyuan_get_embedding_with_exception(): + with pytest.raises(TencentCloudSDKException): + client = hunyuan_client.HunyuanClient(None, "", None) + params = {} + client.GetEmbedding(params) diff --git a/1hunyuan/test_hunyuan_get_embedding_request.py b/1hunyuan/test_hunyuan_get_embedding_request.py new file mode 100644 index 000000000..54e6a0af6 --- /dev/null +++ b/1hunyuan/test_hunyuan_get_embedding_request.py @@ -0,0 +1,21 @@ +import warnings + +from tencentcloud.hunyuan.v20230901.models import GetEmbeddingRequest + + +def test_hunyuan_get_embedding_request(): + req = GetEmbeddingRequest() + req.Input = "test_input" + assert req.Input == "test_input" + + +def test_hunyuan_get_embedding_request_deserialize(): + req = GetEmbeddingRequest() + params = { + "Input": "test_input", + "test": "test" + } + with warnings.catch_warnings(record=True) as w: + req._deserialize(params) + assert req.Input == "test_input" + assert str(w.pop().message) == "test fileds are useless." diff --git a/1hunyuan/test_hunyuan_get_embedding_response.py b/1hunyuan/test_hunyuan_get_embedding_response.py new file mode 100644 index 000000000..237ce773f --- /dev/null +++ b/1hunyuan/test_hunyuan_get_embedding_response.py @@ -0,0 +1,27 @@ +import warnings + +from tencentcloud.hunyuan.v20230901.models import GetEmbeddingResponse + + +def test_hunyuan_get_embedding_response(): + resp = GetEmbeddingResponse() + resp.Data = 1 + assert resp.Data == 1 + resp.Usage = 10 + assert resp.Usage == 10 + resp.RequestId = "123-ss-2-d-r4-f-42" + assert resp.RequestId == "123-ss-2-d-r4-f-42" + + +def test_hunyuan_get_embedding_response_deserialize(mocker): + resp = GetEmbeddingResponse() + params = { + "Data": [1, 2, 3], + "Usage": 10, + "RequestId": "123-ss-2-d-r4-f-42" + } + with mocker.patch('tencentcloud.hunyuan.v20230901.models.EmbeddingData._deserialize', return_value=111), \ + mocker.patch('tencentcloud.hunyuan.v20230901.models.EmbeddingUsage._deserialize', return_value=222), \ + warnings.catch_warnings(record=True) as w: + resp._deserialize(params) + assert resp.RequestId == "123-ss-2-d-r4-f-42" diff --git a/1hunyuan/test_hunyuan_get_token_count.py b/1hunyuan/test_hunyuan_get_token_count.py new file mode 100644 index 000000000..ad993118d --- /dev/null +++ b/1hunyuan/test_hunyuan_get_token_count.py @@ -0,0 +1,40 @@ +import json +import os + +import pytest + +from tencentcloud.common import credential +from tencentcloud.common.exception import TencentCloudSDKException +from tencentcloud.common.profile.client_profile import ClientProfile +from tencentcloud.common.profile.http_profile import HttpProfile +from tencentcloud.hunyuan.v20230901 import hunyuan_client, models + + +def test_hunyuan_get_token_count(): + cred = credential.Credential( + os.environ.get("TENCENTCLOUD_SECRET_ID"), + os.environ.get("TENCENTCLOUD_SECRET_KEY")) + httpProfile = HttpProfile() + httpProfile.endpoint = "hunyuan.tencentcloudapi.com" + + clientProfile = ClientProfile() + clientProfile.httpProfile = httpProfile + client = hunyuan_client.HunyuanClient(cred, "", clientProfile) + + req = models.GetTokenCountRequest() + params = { + "Prompt": "你好" + } + req.from_json_string(json.dumps(params)) + + resp = client.GetTokenCount(req) + assert resp.TokenCount == 1 + assert resp.CharacterCount == 2 + assert resp.Tokens == ["你好"] + + +def test_hunyuan_get_token_count_with_exception(): + with pytest.raises(TencentCloudSDKException): + client = hunyuan_client.HunyuanClient(None, "", None) + params = {} + client.GetTokenCount(params) diff --git a/1hunyuan/test_hunyuan_get_token_count_request.py b/1hunyuan/test_hunyuan_get_token_count_request.py new file mode 100644 index 000000000..eec1f86d7 --- /dev/null +++ b/1hunyuan/test_hunyuan_get_token_count_request.py @@ -0,0 +1,18 @@ +import warnings + +from tencentcloud.hunyuan.v20230901.models import GetTokenCountRequest + + +def test_hunyuan_get_token_count_request(): + req = GetTokenCountRequest() + req.Prompt = 1 + assert req.Prompt == 1 + + +def test_hunyuan_get_token_count_request_deserialize(): + req = GetTokenCountRequest() + params = {"Prompt": 1, "test": "test"} + with warnings.catch_warnings(record=True) as w: + req._deserialize(params) + assert req.Prompt == 1 + assert str(w.pop().message) == "test fileds are useless." diff --git a/1hunyuan/test_hunyuan_get_token_count_response.py b/1hunyuan/test_hunyuan_get_token_count_response.py new file mode 100644 index 000000000..9702bbf6b --- /dev/null +++ b/1hunyuan/test_hunyuan_get_token_count_response.py @@ -0,0 +1,31 @@ +from tencentcloud.hunyuan.v20230901.models import GetTokenCountResponse + + +def test_hunyuan_get_token_count_response(): + resp = GetTokenCountResponse() + resp.TokenCount = 10 + assert resp.TokenCount == 10 + + resp.CharacterCount = 100 + assert resp.CharacterCount == 100 + + resp.RequestId = "123456" + assert resp.RequestId == "123456" + + resp.Tokens = "1m2ks29sk2www" + assert resp.Tokens == "1m2ks29sk2www" + + +def test_hunyuan_get_token_count_response_deserialize(): + resp = GetTokenCountResponse() + params = { + "TokenCount": 10, + "CharacterCount": 100, + "RequestId": "123456", + "Tokens": "1m2ks29sk2www" + } + resp._deserialize(params) + assert resp.TokenCount == 10 + assert resp.CharacterCount == 100 + assert resp.RequestId == "123456" + assert resp.Tokens == "1m2ks29sk2www" diff --git a/1hunyuan/test_hunyuan_image_url.py b/1hunyuan/test_hunyuan_image_url.py new file mode 100644 index 000000000..20a79592a --- /dev/null +++ b/1hunyuan/test_hunyuan_image_url.py @@ -0,0 +1,18 @@ +import warnings + +from tencentcloud.hunyuan.v20230901.models import ImageUrl + + +def test_hunyuan_image_url(): + image = ImageUrl() + image.Url = "https://hunyuan.com" + assert image.Url == "https://hunyuan.com" + + +def test_hunyuan_image_url_deserialize(): + image = ImageUrl() + params = {"Url": "https://hunyuan.com", "test": "test"} + with warnings.catch_warnings(record=True) as w: + image._deserialize(params) + assert image.Url == "https://hunyuan.com" + assert str(w.pop().message) == "test fileds are useless." diff --git a/1hunyuan/test_hunyuan_message.py b/1hunyuan/test_hunyuan_message.py new file mode 100644 index 000000000..eef69b9cb --- /dev/null +++ b/1hunyuan/test_hunyuan_message.py @@ -0,0 +1,39 @@ +import warnings + +from tencentcloud.hunyuan.v20230901.models import Message + + +def test_hunyuan_message(): + msg = Message() + msg.Role = "admin" + assert msg.Role == "admin" + + msg.Content = "hello" + assert msg.Content == "hello" + + msg.Contents = ["hello", "world"] + assert msg.Contents == ["hello", "world"] + + msg.ToolCallId = "123456" + assert msg.ToolCallId == "123456" + + msg.ToolCalls = ["123456", "789012"] + assert msg.ToolCalls == ["123456", "789012"] + + +def test_hunyuan_message_deserialize(mocker): + msg = Message() + params = { + "Role": "admin", + "Content": ["hello"], + "Contents": ["hello", "world"], + "ToolCallId": "123456", + "ToolCalls": ["123456", "789012"], + "test": "test", + } + with mocker.patch('tencentcloud.hunyuan.v20230901.models.Content._deserialize', return_value=111), \ + mocker.patch('tencentcloud.hunyuan.v20230901.models.ToolCall._deserialize', return_value=222), \ + warnings.catch_warnings(record=True) as w: + msg._deserialize(params) + assert msg.Role == "admin" + assert str(w.pop().message) == "test fileds are useless." diff --git a/1hunyuan/test_hunyuan_tool.py b/1hunyuan/test_hunyuan_tool.py new file mode 100644 index 000000000..ab71f9c7f --- /dev/null +++ b/1hunyuan/test_hunyuan_tool.py @@ -0,0 +1,26 @@ +import warnings + +from tencentcloud.hunyuan.v20230901.models import Tool + + +def test_hunyuan_tool(): + tool = Tool() + tool.Type = 'form-data' + assert tool.Type == 'form-data' + + tool.Function = 'mock_function' + assert tool.Function == 'mock_function' + + +def test_hunyuan_tool_deserialize(mocker): + tool = Tool() + params = { + 'Type': 'form-data', + 'Function': 'mock_function', + 'test': 'test' + } + with mocker.patch('tencentcloud.hunyuan.v20230901.models.ToolFunction._deserialize', return_value=111), \ + warnings.catch_warnings(record=True) as w: + tool._deserialize(params) + assert tool.Type == 'form-data' + assert str(w.pop().message) == "test fileds are useless." diff --git a/1hunyuan/test_hunyuan_tool_call.py b/1hunyuan/test_hunyuan_tool_call.py new file mode 100644 index 000000000..018b33cac --- /dev/null +++ b/1hunyuan/test_hunyuan_tool_call.py @@ -0,0 +1,30 @@ +import warnings + +from tencentcloud.hunyuan.v20230901.models import ToolCall + + +def test_hunyuan_tool_call(): + call = ToolCall() + call.Type = 'test' + assert call.Type == 'test' + + call.Id = '123456' + assert call.Id == '123456' + + call.Function = 'mock_function' + assert call.Function == 'mock_function' + + +def test_hunyuan_tool_call_deserialize(mocker): + call = ToolCall() + params = { + 'Type': 'test', + 'Id': '123456', + 'Function': 'mock_function', + 'test': 'test' + } + with mocker.patch('tencentcloud.hunyuan.v20230901.models.ToolCallFunction._deserialize', return_value=111), \ + warnings.catch_warnings(record=True) as w: + call._deserialize(params) + assert call.Type == 'test' + assert str(w.pop().message) == "test fileds are useless." diff --git a/1hunyuan/test_hunyuan_tool_call_function.py b/1hunyuan/test_hunyuan_tool_call_function.py new file mode 100644 index 000000000..07d9757ed --- /dev/null +++ b/1hunyuan/test_hunyuan_tool_call_function.py @@ -0,0 +1,25 @@ +import warnings + +from tencentcloud.hunyuan.v20230901.models import ToolCallFunction + + +def test_hunyuan_tool_call_function(): + function = ToolCallFunction() + function.Name = "function" + assert function.Name == "function" + + function.Arguments = ["arg1", "arg2"] + assert function.Arguments == ["arg1", "arg2"] + + +def test_hunyuan_tool_call_function_deserialize(): + function = ToolCallFunction() + params = { + "Name": "function", + "Arguments": ["arg1", "arg2"], + "test": "test" + } + with warnings.catch_warnings(record=True) as w: + function._deserialize(params) + assert function.Name == "function" + assert str(w.pop().message) == "test fileds are useless." diff --git a/1hunyuan/test_hunyuan_tool_function.py b/1hunyuan/test_hunyuan_tool_function.py new file mode 100644 index 000000000..70b4e3292 --- /dev/null +++ b/1hunyuan/test_hunyuan_tool_function.py @@ -0,0 +1,30 @@ +import warnings + +from tencentcloud.hunyuan.v20230901.models import ToolFunction + + +def test_hunyuan_tool_function(): + function = ToolFunction() + function.Name = 'Test' + assert function.Name == 'Test' + + function.Parameters = ["a", "b"] + assert function.Parameters == ["a", "b"] + + function.Description = 'this is a test' + assert function.Description == 'this is a test' + + +def test_hunyuan_tool_function_deserialize(): + function = ToolFunction() + params = { + "Name": "test", + "Description": "this is a test", + "Parameters": ["a", "b"], + "test": "test" + } + with warnings.catch_warnings(record=True) as w: + function._deserialize(params) + assert function.Name == "test" + assert function.Description == "this is a test" + assert str(w.pop().message) == "test fileds are useless." diff --git a/1hunyuan/test_hunyuan_usage.py b/1hunyuan/test_hunyuan_usage.py new file mode 100644 index 000000000..4b2311028 --- /dev/null +++ b/1hunyuan/test_hunyuan_usage.py @@ -0,0 +1,31 @@ +import warnings + +from tencentcloud.hunyuan.v20230901.models import Usage + + +def test_hunyuan_usage(): + usage = Usage() + usage.TotalTokens = 100 + assert usage.TotalTokens == 100 + + usage.PromptTokens = 10 + assert usage.PromptTokens == 10 + + usage.CompletionTokens = 9 + assert usage.CompletionTokens == 9 + + +def test_hunyuan_usage_deserialize(): + usage = Usage() + params = { + "TotalTokens": 100, + "PromptTokens": 999, + "CompletionTokens": 888, + "test": "test" + } + with warnings.catch_warnings(record=True) as w: + usage._deserialize(params) + assert usage.TotalTokens == 100 + assert usage.PromptTokens == 999 + assert usage.CompletionTokens == 888 + assert str(w.pop().message) == "test fileds are useless." diff --git a/1hunyuan/test_query_hunyuan_image_job_request.py b/1hunyuan/test_query_hunyuan_image_job_request.py new file mode 100644 index 000000000..d0069d293 --- /dev/null +++ b/1hunyuan/test_query_hunyuan_image_job_request.py @@ -0,0 +1,18 @@ +import warnings + +from tencentcloud.hunyuan.v20230901.models import QueryHunyuanImageJobRequest + + +def test_query_hunyuan_image_job_request(): + req = QueryHunyuanImageJobRequest() + req.JobId = 123 + assert req.JobId == 123 + + +def test_query_hunyuan_image_job_deserialize(): + req = QueryHunyuanImageJobRequest() + params = {"JobId": 123, "test": "test"} + with warnings.catch_warnings(record=True) as w: + req._deserialize(params) + req.JobId = 123 + assert str(w.pop().message) == "test fileds are useless." diff --git a/1hunyuan/test_query_hunyuan_image_job_response.py b/1hunyuan/test_query_hunyuan_image_job_response.py new file mode 100644 index 000000000..8351ed91d --- /dev/null +++ b/1hunyuan/test_query_hunyuan_image_job_response.py @@ -0,0 +1,57 @@ +from tencentcloud.hunyuan.v20230901.models import QueryHunyuanImageJobResponse + + +def test_query_hunyuan_image_job_response(): + resp = QueryHunyuanImageJobResponse() + resp.RequestId = "83k2-2ked02-3sl3" + assert resp.RequestId == "83k2-2ked02-3sl3" + + resp.JobStatusCode = '0' + assert resp.JobStatusCode == '0' + + resp.JobStatusMsg = 'success' + assert resp.JobStatusMsg == 'success' + + resp.JobErrorCode = '704' + assert resp.JobErrorCode == '704' + + resp.JobErrorMsg = 'job not found' + assert resp.JobErrorMsg == 'job not found' + + resp.ResultImage = 'http://example.com' + assert resp.ResultImage == 'http://example.com' + + resp.ResultDetails = { + '1': 'http://example.com/1', + '2': 'http://example.com/2', + } + assert resp.ResultDetails == { + '1': 'http://example.com/1', + '2': 'http://example.com/2', } + + resp.RevisedPrompt = 'hello' + assert resp.RevisedPrompt == 'hello' + + +def test_query_hunyuan_image_job_response_deserialize(): + resp = QueryHunyuanImageJobResponse() + params = { + 'RequestId': '83k2-2ked02-3sl3', + 'JobStatusCode': '0', + 'JobStatusMsg': 'success', + 'JobErrorCode': '704', + 'JobErrorMsg': 'job not found', + 'ResultImage': 'http://example.com', + 'ResultDetails': { + '1': 'http://example.com/1', + '2': 'http://example.com/2', + }, + 'RevisedPrompt': 'hello', + } + resp._deserialize(params) + assert resp.RequestId == '83k2-2ked02-3sl3' + assert resp.JobStatusCode == '0' + assert resp.JobStatusMsg == 'success' + assert resp.JobErrorCode == '704' + assert resp.JobErrorMsg == 'job not found' + assert resp.ResultImage == 'http://example.com' diff --git a/1hunyuan/test_submit_hunyuan_image_job.py b/1hunyuan/test_submit_hunyuan_image_job.py new file mode 100644 index 000000000..5c5d15e13 --- /dev/null +++ b/1hunyuan/test_submit_hunyuan_image_job.py @@ -0,0 +1,39 @@ +import json +import os + +import pytest + +from tencentcloud.common import credential +from tencentcloud.common.exception import TencentCloudSDKException +from tencentcloud.common.profile.client_profile import ClientProfile +from tencentcloud.common.profile.http_profile import HttpProfile +from tencentcloud.hunyuan.v20230901 import hunyuan_client, models + + +def test_submit_hunyuan_image_job(): + cred = credential.Credential( + os.environ.get("TENCENTCLOUD_SECRET_ID"), + os.environ.get("TENCENTCLOUD_SECRET_KEY")) + + httpProfile = HttpProfile() + httpProfile.endpoint = "hunyuan.tencentcloudapi.com" + + clientProfile = ClientProfile() + clientProfile.httpProfile = httpProfile + client = hunyuan_client.HunyuanClient(cred, "ap-guangzhou", clientProfile) + + req = models.SubmitHunyuanImageJobRequest() + params = { + "Prompt": "火山" + } + req.from_json_string(json.dumps(params)) + + resp = client.SubmitHunyuanImageJob(req) + assert resp is not None + + +def test_submit_hunyuan_image_job_with_exception(): + with pytest.raises(TencentCloudSDKException): + client = hunyuan_client.HunyuanClient(None, "", None) + params = {} + client.SubmitHunyuanImageJob(params) diff --git a/1hunyuan/test_submit_hunyuan_image_job_request.py b/1hunyuan/test_submit_hunyuan_image_job_request.py new file mode 100644 index 000000000..47975ade8 --- /dev/null +++ b/1hunyuan/test_submit_hunyuan_image_job_request.py @@ -0,0 +1,37 @@ +import warnings + +from tencentcloud.hunyuan.v20230901.models import SubmitHunyuanImageJobRequest + + +def test_submit_hunyuan_image_job_request(): + req = SubmitHunyuanImageJobRequest() + req.Prompt = "test" + assert req.Prompt == "test" + + req.Style = "code" + assert req.Style == "code" + + req.Resolution = 1 + assert req.Resolution == 1 + + req.LogoAdd = True + assert req.LogoAdd == True + + req.Revise = "test" + assert req.Revise == "test" + + +def test_submit_hunyuan_image_job_request_deserialize(): + req = SubmitHunyuanImageJobRequest() + params = { + "Prompt": "test", + "Style": "code", + "Resolution": 1, + "LogoAdd": True, + "Revise": "test", + "test": "test", + } + with warnings.catch_warnings(record=True) as w: + req._deserialize(params) + assert req.Prompt == "test" + assert str(w.pop().message) == "test fileds are useless." diff --git a/1hunyuan/test_submit_hunyuan_image_job_response.py b/1hunyuan/test_submit_hunyuan_image_job_response.py new file mode 100644 index 000000000..5bd215e85 --- /dev/null +++ b/1hunyuan/test_submit_hunyuan_image_job_response.py @@ -0,0 +1,21 @@ +from tencentcloud.hunyuan.v20230901.models import SubmitHunyuanImageJobResponse + + +def test_submit_hunyuan_image_job_response(): + resp = SubmitHunyuanImageJobResponse() + resp.JobId = "11111" + assert resp.JobId == "11111" + + resp.RequestId = "22222" + assert resp.RequestId == "22222" + + +def test_submit_hunyuan_image_job_response_deserialize(): + resp = SubmitHunyuanImageJobResponse() + params = { + "JobId": "11111", + "RequestId": "992js8-2sss-22222", + } + resp._deserialize(params) + assert resp.JobId == "11111" + assert resp.RequestId == "992js8-2sss-22222" diff --git a/common/__init__.py b/common/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/common/test.log b/common/test.log new file mode 100644 index 000000000..e69de29bb diff --git a/common/test_build_req_inter.py b/common/test_build_req_inter.py new file mode 100644 index 000000000..cb411cb17 --- /dev/null +++ b/common/test_build_req_inter.py @@ -0,0 +1,36 @@ +import pytest + +from tencentcloud.common import abstract_client +from tencentcloud.common.exception import TencentCloudSDKException + + +def test_build_req_inter_skip_sign(mocker): + options = {'SkipSign': True} + client = abstract_client.AbstractClient(None, None, None) + mock_method = mocker.patch.object(client, '_build_req_without_signature') + client._build_req_inter('action', {'param': 'value'}, 'req_inter', options) + assert mock_method.called + + +def test_build_req_inter_tc3_signature(mocker): + client = abstract_client.AbstractClient(None, None, None) + mock_method = mocker.patch.object(client, '_build_req_with_tc3_signature') + client._build_req_inter('action', {'param': 'value'}, 'req_inter') + assert mock_method.called + + +def test_build_req_inter_old_signature(mocker): + client = abstract_client.AbstractClient(None, None, None) + client.profile.signMethod = "HmacSHA1" + mock_method = mocker.patch.object(client, '_build_req_with_old_signature') + client._build_req_inter('action', {'param': 'value'}, 'req_inter') + assert mock_method.called + + +def test_build_req_inter_invalid_signature_method(): + client = abstract_client.AbstractClient(None, None, None) + client.profile.signMethod = "InvalidMethod" + with pytest.raises(TencentCloudSDKException) as context: + client._build_req_inter('action', {'param': 'value'}, 'req_inter') + assert context.value.code == "ClientError" + assert context.value.message == "Invalid signature method." diff --git a/common/test_build_req_with_old_signature_inter.py b/common/test_build_req_with_old_signature_inter.py new file mode 100644 index 000000000..3c783e001 --- /dev/null +++ b/common/test_build_req_with_old_signature_inter.py @@ -0,0 +1,41 @@ +import os + +from tencentcloud.common import abstract_client, credential +from tencentcloud.common.profile.client_profile import ClientProfile +from tencentcloud.common.profile.http_profile import HttpProfile + + +class Request: + def __init__(self, data, header): + self.data = data + self.header = header + + +def test_build_req_with_old_signature_inter_correct(mocker): + cred = credential.Credential( + os.environ.get("TENCENTCLOUD_SECRET_ID"), + os.environ.get("TENCENTCLOUD_SECRET_KEY")) + httpProfile = HttpProfile() + httpProfile.endpoint = "sts.tencentcloudapi.com" + + clientProfile = ClientProfile() + clientProfile.httpProfile = httpProfile + clientProfile.signMethod = "HmacSHA256" + + client = abstract_client.AbstractClient(cred, None, profile=clientProfile) + + req = Request({ + "data": { + "name": "张三", + "age": 30, + "email": "zhangsan@example.com" + } + }, + { + "header": { + "Content-Type": "application/json" + }}) + with mocker.patch('time.time', return_value=1634567890), mocker.patch('random.randint', return_value=123456): + """设置mock对象,固定时间戳和随机数""" + client._build_req_with_old_signature('action', {}, req) + assert req.header["Content-Type"] == "application/x-www-form-urlencoded" diff --git a/common/test_build_req_without_signature.py b/common/test_build_req_without_signature.py new file mode 100644 index 000000000..adedb55e0 --- /dev/null +++ b/common/test_build_req_without_signature.py @@ -0,0 +1,122 @@ +import copy +import json +import os +from unittest.mock import MagicMock, patch +from tencentcloud.common import credential, abstract_client +from urllib.parse import urlencode +from tencentcloud.common.profile.client_profile import ClientProfile +from tencentcloud.common.profile.http_profile import HttpProfile + +_default_content_type = "application/json" +_form_urlencoded_content = "application/x-www-form-urlencoded" +_json_content = "application/json" +_multipart_content = "multipart/form-data" +_octet_stream = "application/octet-stream" + + +def get_client(): + cred = credential.Credential( + os.environ.get("TENCENTCLOUD_SECRET_ID"), + os.environ.get("TENCENTCLOUD_SECRET_KEY")) + httpProfile = HttpProfile() + httpProfile.endpoint = "sts.tencentcloudapi.com" + + clientProfile = ClientProfile() + clientProfile.httpProfile = httpProfile + clientProfile.signMethod = "HmacSHA256" + + client = abstract_client.AbstractClient(cred, "ap-shanghai", profile=clientProfile) + return client + + +class Request: + def __init__(self, data, header, method): + self.data = data + self.header = header + self.method = method + + +def test_build_req_without_signature_get_method(): + """测试 GET 请求""" + client = get_client() + req = Request({}, {}, "GET") + action = 'DescribeServices' + params = {'service': 'cvm'} + options = None + client._build_req_without_signature(action, params, req, options) + print(req.header) + assert req.header["Content-Type"] == _form_urlencoded_content + assert req.data == urlencode(copy.deepcopy(client._fix_params(params))) + + +def test_build_req_without_signature_post_method(): + """测试 POST 请求""" + client = get_client() + req = Request({}, {}, "GET") + action = 'DescribeServices' + params = {'service': 'cvm'} + options = None + req.method = 'POST' + client._build_req_without_signature(action, params, req, options) + assert req.header["Content-Type"] == _json_content + assert req.data == json.dumps(params) + + +def test_build_req_without_signature_multipart_method(mocker): + """测试 multipart格式""" + client = get_client() + req = Request({}, {}, "GET") + action = 'DescribeServices' + params = {'service': 'cvm'} + options = {"IsMultipart": True} + req.method = 'POST' + with mocker.patch('uuid.uuid4', return_value=MagicMock(hex="123456")): + client._build_req_without_signature(action, params, req, options) + expected_content_type = f"{_multipart_content}; boundary=123456" + assert req.header["Content-Type"] == expected_content_type + + +def test_build_req_without_signature_octet_stream_method(): + """测试 octet-stream""" + client = get_client() + req = Request({}, {}, "POST") + action = 'DescribeServices' + params = {'service': 'cvm'} + options = {"IsOctetStream": True} + client._build_req_without_signature(action, params, req, options) + assert req.header["Content-Type"] == _octet_stream + + +def test_build_req_without_signature_unsigned_payload(): + """测试无签名""" + client = get_client() + req = Request({}, {}, "POST") + action = 'DescribeServices' + params = {'service': 'cvm'} + options = None + client.profile.unsignedPayload = True + client._build_req_without_signature(action, params, req, options) + assert req.header["X-TC-Content-SHA256"] == "UNSIGNED-PAYLOAD" + + +def test_build_req_without_signature_region(): + """测试 region""" + client = get_client() + req = Request({}, {}, "POST") + action = 'DescribeServices' + params = {'service': 'cvm'} + options = None + client._build_req_without_signature(action, params, req, options) + assert req.header['X-TC-Region'] == client.region + + +def test_build_req_without_signature_language(): + """测试所选语言""" + client = get_client() + req = Request({}, {}, "POST") + action = 'DescribeServices' + params = {'service': 'cvm'} + options = None + client.profile.language = 'zh-CN' + client._build_req_without_signature(action, params, req, options) + assert req.header['X-TC-Language'] == client.profile.language diff --git a/common/test_call_with_region_breaker.py b/common/test_call_with_region_breaker.py new file mode 100644 index 000000000..b4071591f --- /dev/null +++ b/common/test_call_with_region_breaker.py @@ -0,0 +1,49 @@ +import os + + +from tencentcloud.common import abstract_client, credential +from tencentcloud.common.profile.client_profile import ClientProfile +from tencentcloud.common.profile.http_profile import HttpProfile + + +def test_normal_request(mocker): + cred = credential.Credential( + os.environ.get("TENCENTCLOUD_SECRET_ID"), + os.environ.get("TENCENTCLOUD_SECRET_KEY")) + httpProfile = HttpProfile() + httpProfile.endpoint = "sts.tencentcloudapi.com" + + clientProfile = ClientProfile() + clientProfile.httpProfile = httpProfile + clientProfile.signMethod = "HmacSHA256" + clientProfile.disable_region_breaker = False + + client = abstract_client.AbstractClient(cred, None, profile=clientProfile) + action = "DescribeServices" + params = {"service": "cvm"} + mock_request = mocker.patch.object(client, 'request') + client._call_with_region_breaker(action, params) + mock_request.send_request.assert_called_once() + + +def test_circuit_breaker_open(mocker): + cred = credential.Credential( + os.environ.get("TENCENTCLOUD_SECRET_ID"), + os.environ.get("TENCENTCLOUD_SECRET_KEY")) + httpProfile = HttpProfile() + httpProfile.endpoint = "sts.tencentcloudapi.com" + + clientProfile = ClientProfile() + clientProfile.httpProfile = httpProfile + clientProfile.signMethod = "HmacSHA256" + clientProfile.disable_region_breaker = False + + client = abstract_client.AbstractClient(cred, None, profile=clientProfile) + + action = "DescribeServices" + params = {"service": "cvm"} + mocker_circuit_breaker = mocker.patch.object(client, 'circuit_breaker') + mocker_circuit_breaker.before_requests.return_value = 1, True + client._call_with_region_breaker(action, params) + assert ".tencentcloudapi.com" in client._get_endpoint() + diff --git a/common/test_cvm_role_credential_init.py b/common/test_cvm_role_credential_init.py new file mode 100644 index 000000000..bc777d945 --- /dev/null +++ b/common/test_cvm_role_credential_init.py @@ -0,0 +1,26 @@ +from tencentcloud.common.credential import CVMRoleCredential + + +def test_cvm_role_credential_init_id(mocker): + credential = CVMRoleCredential("cvm") + update_credential = mocker.patch.object(credential, "update_credential") + _secret_id = credential.secret_id + update_credential.assert_called_once() + assert _secret_id == credential.secretId + + +def test_cvm_role_credential_init_key(mocker): + credential = CVMRoleCredential("cvm") + update_credential = mocker.patch.object(credential, "update_credential") + _secret_key = credential.secret_key + update_credential.assert_called_once() + assert _secret_key == credential.secretId + assert credential.secretKey is None + + +def test_cvm_role_credential_init_token(mocker): + credential = CVMRoleCredential("cvm") + update_credential = mocker.patch.object(credential, "update_credential") + credential.token + update_credential.assert_called_once() + assert credential.token is None diff --git a/common/test_default_credential_provider.py b/common/test_default_credential_provider.py new file mode 100644 index 000000000..b1aa1956d --- /dev/null +++ b/common/test_default_credential_provider.py @@ -0,0 +1,69 @@ +from tencentcloud.common.credential import DefaultCredentialProvider, EnvironmentVariableCredential +from tencentcloud.common.exception import TencentCloudSDKException + + +def test_get_credential(mocker): + credential = DefaultCredentialProvider() + mock_get_credentials = mocker.patch.object(credential, 'get_credentials') + credential.get_credential() + mock_get_credentials.assert_called_once_with() + + +def test_get_credentials_with_cred(): + credential = DefaultCredentialProvider() + credential.cred = 'test' + assert credential.get_credentials() == 'test' + + +def test_get_credentials_without_cred_env(mocker): + credential = DefaultCredentialProvider() + credential.cred = None + with mocker.patch('tencentcloud.common.credential.EnvironmentVariableCredential.get_credential', + return_value="env_cred"): + cred = credential.get_credentials() + assert cred == "env_cred" + + +def test_get_credential_without_cred_pro(mocker): + credential = DefaultCredentialProvider() + credential.cred = None + with mocker.patch('tencentcloud.common.credential.EnvironmentVariableCredential.get_credential', return_value=None), \ + mocker.patch('tencentcloud.common.credential.ProfileCredential.get_credential', return_value="env_cred"): + cred = credential.get_credentials() + assert cred == "env_cred" + + +def test_get_credential_without_cred_cvm(mocker): + credential = DefaultCredentialProvider() + credential.cred = None + with mocker.patch('tencentcloud.common.credential.EnvironmentVariableCredential.get_credential', return_value=None), \ + mocker.patch('tencentcloud.common.credential.ProfileCredential.get_credential', return_value=None), \ + mocker.patch('tencentcloud.common.credential.CVMRoleCredential.get_credential', return_value="env_cred"): + cred = credential.get_credentials() + assert cred == "env_cred" + + +def test_get_credential_without_cred_default(mocker): + credential = DefaultCredentialProvider() + credential.cred = None + with mocker.patch('tencentcloud.common.credential.EnvironmentVariableCredential.get_credential', return_value=None), \ + mocker.patch('tencentcloud.common.credential.ProfileCredential.get_credential', return_value=None), \ + mocker.patch('tencentcloud.common.credential.CVMRoleCredential.get_credential', return_value=None), \ + mocker.patch('tencentcloud.common.credential.DefaultTkeOIDCRoleArnProvider.get_credential', return_value="env_cred"): + cred = credential.get_credentials() + assert cred == "env_cred" + + +def test_get_credential_without_cred_exception(mocker): + credential = DefaultCredentialProvider() + credential.cred = None + with mocker.patch('tencentcloud.common.credential.EnvironmentVariableCredential.get_credential', return_value=None), \ + mocker.patch('tencentcloud.common.credential.ProfileCredential.get_credential', return_value=None), \ + mocker.patch('tencentcloud.common.credential.CVMRoleCredential.get_credential', return_value=None), \ + mocker.patch('tencentcloud.common.credential.DefaultTkeOIDCRoleArnProvider.get_credential', return_value=None): + try: + cred = credential.get_credentials() + assert cred == "env_cred" + except TencentCloudSDKException as e: + assert e.message == "no valid credentail." + assert e.code == "ClientSideError" diff --git a/common/test_default_tke_oidc_role_arn_provider.py b/common/test_default_tke_oidc_role_arn_provider.py new file mode 100644 index 000000000..fd4049856 --- /dev/null +++ b/common/test_default_tke_oidc_role_arn_provider.py @@ -0,0 +1,15 @@ +from tencentcloud.common.credential import DefaultTkeOIDCRoleArnProvider, OIDCRoleArnCredential + + +def test_default_tke_oidc_role_arn_provider_get_credential(mocker): + provider = DefaultTkeOIDCRoleArnProvider() + get_credentials = mocker.patch.object(provider, "get_credentials") + provider.get_credential() + get_credentials.assert_called_once() + + +def test_default_tke_oidc_role_arn_provider_get_credentials(mocker): + provider = DefaultTkeOIDCRoleArnProvider() + with mocker.patch('tencentcloud.common.credential.OIDCRoleArnCredential._init_from_tke', return_value=None): + cred = provider.get_credentials() + assert cred._is_tke is True diff --git a/common/test_empty_handle.py b/common/test_empty_handle.py new file mode 100644 index 000000000..772928cf3 --- /dev/null +++ b/common/test_empty_handle.py @@ -0,0 +1,14 @@ +import warnings +import pytest + +import logging +from tencentcloud.common import abstract_client + + +def test_empty_handler_emit(): + warnings.simplefilter('error') + empty_handler = abstract_client.EmptyHandler() + + log_record = logging.LogRecord("test_logger", logging.INFO, "", 0, "Test message", (), None) + empty_handler.emit(log_record) + assert True diff --git a/common/test_environment_variable_credential.py b/common/test_environment_variable_credential.py new file mode 100644 index 000000000..9cb885df0 --- /dev/null +++ b/common/test_environment_variable_credential.py @@ -0,0 +1,29 @@ +import os + +from tencentcloud.common.credential import EnvironmentVariableCredential + + +def test_get_credential_with_valid_env_vars(): + credential = EnvironmentVariableCredential() + os.environ['TENCENTCLOUD_SECRET_ID'] = 'valid_secret_id' + os.environ['TENCENTCLOUD_SECRET_KEY'] = 'valid_secret_key' + assert credential.get_credential() is not None + assert credential.secret_id == 'valid_secret_id' + assert credential.secret_key == 'valid_secret_key' + + +def test_get_credential_with_missing_env_vars(): + credential = EnvironmentVariableCredential() + # 清除环境变量 + if 'TENCENTCLOUD_SECRET_ID' in os.environ: + del os.environ['TENCENTCLOUD_SECRET_ID'] + if 'TENCENTCLOUD_SECRET_KEY' in os.environ: + del os.environ['TENCENTCLOUD_SECRET_KEY'] + assert credential.get_credential() is None + + +def test_get_credential_with_empty_env_vars(): + credential = EnvironmentVariableCredential() + os.environ['TENCENTCLOUD_SECRET_ID'] = '' + os.environ['TENCENTCLOUD_SECRET_KEY'] = '' + assert credential.get_credential() is None diff --git a/common/test_get_role_name.py b/common/test_get_role_name.py new file mode 100644 index 000000000..7d2eb706a --- /dev/null +++ b/common/test_get_role_name.py @@ -0,0 +1,17 @@ +from tencentcloud.common.credential import CVMRoleCredential +from tencentcloud.common.exception import TencentCloudSDKException + + +def test_get_role_name(): + credential = CVMRoleCredential("cvm") + assert credential.get_role_name() == "cvm" + + +def test_need_refresh(mocker): + credential = CVMRoleCredential() + with mocker.patch("time.time", return_value=0): + assert credential._need_refresh() is True + + with mocker.patch("time.time", return_value=-400): + assert credential._need_refresh() is False + diff --git a/common/test_https_pre_conn_pool.py b/common/test_https_pre_conn_pool.py new file mode 100644 index 000000000..6028c7f3f --- /dev/null +++ b/common/test_https_pre_conn_pool.py @@ -0,0 +1,11 @@ +from tencentcloud.common.http.pre_conn import PreConnPoolManager, HTTPSPreConnPool, HTTPPreConnPool + + +def test_https_pre_conn_pool(mocker): + pool_manager = PreConnPoolManager(pool_size=10) + assert pool_manager._pool_size == 10 + pool = pool_manager._new_pool('https', 'example.com', 80, None) + assert isinstance(pool, HTTPSPreConnPool) + + pool = pool_manager._new_pool('http', 'example.com', 80, None) + assert isinstance(pool, HTTPPreConnPool) diff --git a/common/test_init_credential.py b/common/test_init_credential.py new file mode 100644 index 000000000..e2f966c6a --- /dev/null +++ b/common/test_init_credential.py @@ -0,0 +1,32 @@ +from tencentcloud.common.credential import Credential +from tencentcloud.common.exception import TencentCloudSDKException + + +def test_init_credential(): + try: + credential = Credential(None, None) + except TencentCloudSDKException as e: + assert e.message == "secret id should not be none or empty" + assert e.code == "InvalidCredential" + try: + credential = Credential(" 123456", None) + except TencentCloudSDKException as e: + assert e.message == "secret id should not contain spaces" + assert e.code == "InvalidCredential" + + try: + credential = Credential("123456", None) + except TencentCloudSDKException as e: + assert e.message == "secret key should not be none or empty" + assert e.code == "InvalidCredential" + try: + credential = Credential("123456"," 123456") + except TencentCloudSDKException as e: + assert e.message == "secret key should not contain spaces" + assert e.code == "InvalidCredential" + + +def test_init_credential_return_value(): + credential = Credential("secret_id", "secret_key") + assert credential.secretId == "secret_id" + assert credential.secretKey == "secret_key" diff --git a/common/test_need_refresh_has_None.py b/common/test_need_refresh_has_None.py new file mode 100644 index 000000000..0481335a8 --- /dev/null +++ b/common/test_need_refresh_has_None.py @@ -0,0 +1,11 @@ +from tencentcloud.common.credential import STSAssumeRoleCredential, Credential +from tencentcloud.common.common_client import CommonClient + + +def test_need_refresh_has_None(mocker): + credential = STSAssumeRoleCredential(None, None, None, None, 7200, "us-east-1") + get_sts_tmp_role_arn = mocker.patch.object(credential, "get_sts_tmp_role_arn") + credential._need_refresh() + get_sts_tmp_role_arn.assert_called_once() + + diff --git a/common/test_oidc_role_arn_credential.py b/common/test_oidc_role_arn_credential.py new file mode 100644 index 000000000..a4857d541 --- /dev/null +++ b/common/test_oidc_role_arn_credential.py @@ -0,0 +1,73 @@ +from unittest import mock + +from tencentcloud.common.credential import OIDCRoleArnCredential + + +def test_oidc_role_arn_credential_secretId(mocker): + cred = OIDCRoleArnCredential('', '', '', '', '', 7200) + _keep_fresh = mocker.patch.object(cred, '_keep_fresh') + cred.secretId + _keep_fresh.assert_called_once() + assert cred._tmp_secret_id is None + + +def test_oidc_role_arn_credential_secretKey(mocker): + cred = OIDCRoleArnCredential('', '', '', '', '', 7200) + _keep_fresh = mocker.patch.object(cred, '_keep_fresh') + cred.secretKey + _keep_fresh.assert_called_once() + assert cred._tmp_secret_key is None + + +def test_oidc_role_arn_credential_secret_id(mocker): + cred = OIDCRoleArnCredential('', '', '', '', '', 7200) + _keep_fresh = mocker.patch.object(cred, '_keep_fresh') + cred.secret_id + _keep_fresh.assert_called_once() + assert cred._tmp_secret_id is None + + +def test_oidc_role_arn_credential_secret_key(mocker): + cred = OIDCRoleArnCredential('', '', '', '', '', 7200) + _keep_fresh = mocker.patch.object(cred, '_keep_fresh') + cred.secret_key + _keep_fresh.assert_called_once() + assert cred._tmp_secret_key is None + + +def test_oidc_role_arn_credential_secret_token(mocker): + cred = OIDCRoleArnCredential('', '', '', '', '', 7200) + _keep_fresh = mocker.patch.object(cred, '_keep_fresh') + cred.token + _keep_fresh.assert_called_once() + assert cred._token is None + + +def test_oidc_role_arn_credential_keep_fresh(mocker): + cred = OIDCRoleArnCredential('', '', '', '', '', 7200) + refresh = mocker.patch.object(cred, 'refresh') + cred._keep_fresh() + refresh.assert_called_once() + + +def test_oidc_role_arn_credential_refresh(mocker): + cred = OIDCRoleArnCredential('ap-shanghai', '', '', '', '', 7200) + _init_from_tke = mocker.patch.object(cred, '_init_from_tke') + cred._is_tke = True + rsp = { + "Response": { + "Credentials": { + "Token": "your_token", + "TmpSecretId": "your_tmp_secret_id", + "TmpSecretKey": "your_tmp_secret_key" + }, + "ExpiredTime": 1000 # 例如:设置为某个时间点的时间戳 + } + } + with mock.patch('tencentcloud.common.common_client.CommonClient.call_json', return_value=rsp): + cred.refresh() + _init_from_tke.assert_called_once() + assert cred._token == 'your_token' + assert cred._tmp_secret_id == 'your_tmp_secret_id' + assert cred._tmp_secret_key == 'your_tmp_secret_key' + assert cred._expired_time == 280 diff --git a/common/test_on_failure.py b/common/test_on_failure.py new file mode 100644 index 000000000..d44a279bf --- /dev/null +++ b/common/test_on_failure.py @@ -0,0 +1,31 @@ +from tencentcloud.common.circuit_breaker import Counter + + +def test_on_failure(): + counter = Counter() + counter.on_failure() + assert counter.failures == 1 + assert counter.total == 1 + assert counter.consecutive_failures == 1 + assert counter.consecutive_successes == 0 + + +def test_clear(): + counter = Counter() + counter.clear() + assert counter.failures == 0 + assert counter.total == 0 + assert counter.consecutive_failures == 0 + assert counter.consecutive_successes == 0 + + +def test_get_failure_rate(): + counter = Counter() + counter.total = 0 + assert counter.get_failure_rate() == 0.0 + counter.total = 10 + assert counter.get_failure_rate() == 0.0 + counter.failures = 10 + assert counter.get_failure_rate() == 1.0 + counter.failures = 5 + assert counter.get_failure_rate() == 0.5 diff --git a/common/test_on_success_or_failure.py b/common/test_on_success_or_failure.py new file mode 100644 index 000000000..926b8b10e --- /dev/null +++ b/common/test_on_success_or_failure.py @@ -0,0 +1,36 @@ +from tencentcloud.common.circuit_breaker import CircuitBreaker, Counter + + +class BreakerSetting: + def __init__(self, window_interval, timeout, max_requests=0, max_fail_num=0, max_fail_percent=0): + self.window_interval = window_interval + self.timeout = timeout + self.max_requests = max_requests + self.max_fail_num = max_fail_num + self.max_fail_percent = max_fail_percent + + +def test_on_success(mocker): + breaker_setting = BreakerSetting(10, 10) + cb = CircuitBreaker(breaker_setting) + mock_counter = mocker.patch.object(cb, 'counter') + cb.on_success(0, 1) + mock_counter.on_success.assert_called_once() + + cb1 = CircuitBreaker(breaker_setting) + mock_switch = mocker.patch.object(cb1, 'switch_state') + cb1.on_success(1, 1) + mock_switch.assert_called_once() + + +def test_on_failure(mocker): + breaker_setting = BreakerSetting(10, 10) + cb = CircuitBreaker(breaker_setting) + mock_switch = mocker.patch.object(cb, 'switch_state') + cb.on_failure(0, 1) + mock_switch.assert_called_once() + + cb1 = CircuitBreaker(breaker_setting) + mock_switch1 = mocker.patch.object(cb1, 'switch_state') + cb1.on_failure(1, 1) + mock_switch1.assert_called_once() diff --git a/common/test_params_is_dict_and_format_params.py b/common/test_params_is_dict_and_format_params.py new file mode 100644 index 000000000..1e225321a --- /dev/null +++ b/common/test_params_is_dict_and_format_params.py @@ -0,0 +1,67 @@ +import pytest +from tencentcloud.common import abstract_client +from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException + + +# 是否能正确处理非字典类型的参数 +def test_fix_params_non_dict(): + client = abstract_client.AbstractClient(None, None, None) + params = [1, 2, 3] + result = client._fix_params(params) + assert result == [1, 2, 3] + + +def test_fix_params_dict(): + """是否能正确处理字典类型的参数""" + client = abstract_client.AbstractClient(None, None, None) + params = {'a': 1, 'b': 2} + result = client._fix_params(params) + assert result == {'a': 1, 'b': 2} + + +def test_format_params_none(): + """是否能正确处理None类型的参数""" + client = abstract_client.AbstractClient(None, None, None) + params = None + result = client._format_params('prefix', params) + assert result == {} + + +def test_format_params_list(): + """是否能正确处理list类型的参数""" + client = abstract_client.AbstractClient(None, None, None) + params = [1, {'a': 2}, 3] + result = client._format_params('', params) + expected = {'0': 1, '1.a': 2, '2': 3} + assert result == expected + + +def test_format_params_tuple(): + """是否能正确处理tuple类型的参数""" + client = abstract_client.AbstractClient(None, None, None) + params = (1, {'a': 2}, 3) + result = client._format_params('', params) + expected = {'0': 1, '1.a': 2, '2': 3} + assert result == expected + + +def test_format_params_dict(): + """是否能正确处理dict类型的参数""" + client = abstract_client.AbstractClient(None, None, None) + params = {'a': 1, 'b': {'c': 2}} + result = client._format_params('', params) + expected = {'a': 1, 'b.c': 2} + assert result == expected + + +def test_format_params_unsupported_type(): + """是否能正确处理不支持的类型""" + client = abstract_client.AbstractClient(None, None, None) + params = set([1, 2, 3]) + try: + with pytest.raises(TencentCloudSDKException) as context: + client._format_params('', params) + assert context.exception.code == "ClientParamsError" + assert context.exception.message == "some params type error" + except pytest.fail.Exception as e: + assert True diff --git a/common/test_pre_conn_adapter.py b/common/test_pre_conn_adapter.py new file mode 100644 index 000000000..0d20f6f38 --- /dev/null +++ b/common/test_pre_conn_adapter.py @@ -0,0 +1,8 @@ +from tencentcloud.common.http.pre_conn import PreConnAdapter, PreConnPoolManager + + +def test_pre_conn_adapter(): + adapter = PreConnAdapter(conn_pool_size=10) + assert adapter._conn_pool_size == 10 + adapter.init_poolmanager() + assert isinstance(adapter.poolmanager, PreConnPoolManager) diff --git a/common/test_process_response.py b/common/test_process_response.py new file mode 100644 index 000000000..1162f5b44 --- /dev/null +++ b/common/test_process_response.py @@ -0,0 +1,25 @@ +from tencentcloud.common import abstract_client + + +class Response: + def __init__(self, headers, body): + self.headers = headers + self.body = body + + +def test_process_response_sse(mocker): + client = abstract_client.AbstractClient(None, None) + resp = Response({'Content-Type': 'text/event-stream'}, None) + resp_type = 'json' + _process_response_sse = mocker.patch.object(client, '_process_response_sse') + client._process_response(resp, resp_type) + client._process_response_sse.assert_called_once() + + +def test_process_response_json(mocker): + client = abstract_client.AbstractClient(None, None) + resp = Response({'Content-Type': 'json/event-stream'}, None) + resp_type = 'json' + _process_response_sse = mocker.patch.object(client, '_process_response_json') + client._process_response(resp, resp_type) + client._process_response_json.assert_called_once() \ No newline at end of file diff --git a/common/test_process_response_sse.py b/common/test_process_response_sse.py new file mode 100644 index 000000000..6a2596eb9 --- /dev/null +++ b/common/test_process_response_sse.py @@ -0,0 +1,97 @@ +from tencentcloud.common.abstract_client import AbstractClient + + +def test_empty_response(mocker): + """测试空响应""" + resp = mocker.MagicMock() + resp.iter_lines.return_value = [] + result = list(AbstractClient._process_response_sse(resp)) + assert result == [] + + +def test_single_event(mocker): + resp = mocker.MagicMock() + resp.iter_lines.return_value = [ + b'data:some data', + b'event:myevent', + b'id:123', + b'retry:10', + 0 + ] + expected = [{'data': 'some data', 'event': 'myevent', 'id': '123', 'retry': 10}] + # 直接迭代生成器而不是转换为列表 + result = [] + for e in AbstractClient._process_response_sse(resp): + result.append(e) + assert result == expected + + +def test_multiple_events(mocker): + resp = mocker.MagicMock() + resp.iter_lines.return_value = [ + b'data:data1', + b'event:event1', + b'id:1', + b'', + b'data:data2', + b'event:event2', + b'id:2', + b'retry:20', + 0 + ] + expected1 = {'data': 'data1', 'event': 'event1', 'id': '1'} + expected2 = {'data': 'data2', 'event': 'event2', 'id': '2', 'retry': 20} + result = list(AbstractClient._process_response_sse(resp)) + assert result == [expected1, expected2] + + +def test_comment_line(mocker): + resp = mocker.MagicMock() + resp.iter_lines.return_value = [ + b':this is a comment', + b'data:some data', + b'event:myevent', + 0 + ] + expected = {'data': 'some data', 'event': 'myevent'} + result = list(AbstractClient._process_response_sse(resp)) + assert result == [expected] + + +def test_data_concatenation(mocker): + resp = mocker.MagicMock() + resp.iter_lines.return_value = [ + b'data:some data', + b'data:more data', + b'event:myevent', + 0 + ] + expected = {'data': 'some data\nmore data', 'event': 'myevent'} + result = list(AbstractClient._process_response_sse(resp)) + assert result == [expected] + + +def test_unexpected_fields(mocker): + resp = mocker.MagicMock() + resp.iter_lines.return_value = [ + b'data:some data', + b'event:myevent', + b'unknown:some value', + 0 + ] + expected = {'data': 'some data', 'event': 'myevent'} + result = list(AbstractClient._process_response_sse(resp)) + assert result == [expected] + + +def test_retry_conversion(mocker): + resp = mocker.MagicMock() + resp.iter_lines.return_value = [ + b'data:some data', + b'event:myevent', + b'retry:10', + 0 + ] + expected = {'data': 'some data', 'event': 'myevent', 'retry': 10} + result = list(AbstractClient._process_response_sse(resp)) + assert result == [expected] diff --git a/common/test_profile_credential_get_credential.py b/common/test_profile_credential_get_credential.py new file mode 100644 index 000000000..e4450a2b3 --- /dev/null +++ b/common/test_profile_credential_get_credential.py @@ -0,0 +1,12 @@ +import os + +from tencentcloud.common.credential import ProfileCredential + + +def test_get_credential_file_not_exists(mocker): + os.environ['HOME'] = "tencent" + cred = ProfileCredential() + assert cred.get_credential() is None + assert cred.secret_id is None + assert cred.secret_key is None + assert cred.role_arn is None diff --git a/common/test_response_pretty_formatter.py b/common/test_response_pretty_formatter.py new file mode 100644 index 000000000..790c060a3 --- /dev/null +++ b/common/test_response_pretty_formatter.py @@ -0,0 +1,36 @@ +from tencentcloud.common.http.request import ResponsePrettyFormatter + + +class HttpResponse: + def __init__(self, raw, status_code, reason, headers, text): + self.raw = raw + self.status_code = status_code + self.reason = reason + self.headers = headers + self.text = text + + +class Raw: + def __init__(self, version): + self.version = version + + +def test_response_pretty_formatter(): + raw = Raw("2020-01-01T00:00:") + resp = HttpResponse(raw, status_code=200, reason="OK", headers={"Content-Type": "application/json"}, + text="{\"name\": \"zhangsan\"}") + formatter = ResponsePrettyFormatter(resp) + assert formatter._format_body is True + result = formatter.__str__() + assert '{"name": "zhangsan"}' in result + assert "2020-01-01T00:00:" in result + assert "Content-Type" in result + assert "OK" in result + assert "200" in result + + +def test_response_pretty_formatter_str_ver(): + assert ResponsePrettyFormatter.str_ver(10) == "HTTP/1.0" + assert ResponsePrettyFormatter.str_ver(11) == "HTTP/1.1" + assert ResponsePrettyFormatter.str_ver(20) == "HTTP/2.0" + assert ResponsePrettyFormatter.str_ver(99) == "99" diff --git a/common/test_set_file_logger.py b/common/test_set_file_logger.py new file mode 100644 index 000000000..425e0e7a7 --- /dev/null +++ b/common/test_set_file_logger.py @@ -0,0 +1,15 @@ +import logging +import logging.handlers + +from tencentcloud.common import abstract_client +from tencentcloud.common.abstract_client import logger + +LOGGER_NAME = "tencentcloud_sdk_common" + + +def test_set_file_logger_default(): + client = abstract_client.AbstractClient(None, None, None) + client.set_file_logger('test.log') + assert len(logging.getLogger(LOGGER_NAME).handlers) == 2 + assert hasattr(logger, 'handlers') is True + assert logger.level == logging.DEBUG diff --git a/common/test_set_stream_logger.py b/common/test_set_stream_logger.py new file mode 100644 index 000000000..d034e0e81 --- /dev/null +++ b/common/test_set_stream_logger.py @@ -0,0 +1,12 @@ +import logging +import logging.handlers + +from tencentcloud.common import abstract_client + +LOGGER_NAME = "tencentcloud_sdk_common" + + +def test_set_stream_logger_default(): + client = abstract_client.AbstractClient(None, None, None) + client.set_stream_logger() + assert len(logging.getLogger(LOGGER_NAME).handlers) == 3 diff --git a/common/test_sts_assume_role_credential_init.py b/common/test_sts_assume_role_credential_init.py new file mode 100644 index 000000000..cf9621bb5 --- /dev/null +++ b/common/test_sts_assume_role_credential_init.py @@ -0,0 +1,41 @@ +from tencentcloud.common.credential import STSAssumeRoleCredential + + +def test_sts_assume_role_credential_init(mocker): + credential = STSAssumeRoleCredential(None, None, None, None, 7200, "us-east-1") + assert credential._endpoint == "us-east-1" + + +def test_sts_assume_role_credential_secretId(mocker): + credential = STSAssumeRoleCredential(None, None, None, None, 7200, "us-east-1") + _need_refresh = mocker.patch.object(credential, "_need_refresh") + credential.secretId + _need_refresh.assert_called_once() + + +def test_sts_assume_role_credential_secretKey(mocker): + credential = STSAssumeRoleCredential(None, None, None, None, 7200, "us-east-1") + _need_refresh = mocker.patch.object(credential, "_need_refresh") + credential.secretKey + _need_refresh.assert_called_once() + + +def test_sts_assume_role_credential_secret_id(mocker): + credential = STSAssumeRoleCredential(None, None, None, None, 7200, "us-east-1") + _need_refresh = mocker.patch.object(credential, "_need_refresh") + credential.secret_id + _need_refresh.assert_called_once() + + +def test_sts_assume_role_credential_secret_key(mocker): + credential = STSAssumeRoleCredential(None, None, None, None, 7200, "us-east-1") + _need_refresh = mocker.patch.object(credential, "_need_refresh") + credential.secret_key + _need_refresh.assert_called_once() + + +def test_sts_assume_role_credential_token(mocker): + credential = STSAssumeRoleCredential(None, None, None, None, 7200, "us-east-1") + _need_refresh = mocker.patch.object(credential, "_need_refresh") + credential.token + _need_refresh.assert_called_once() diff --git a/common/test_switch_state.py b/common/test_switch_state.py new file mode 100644 index 000000000..3e153fc2f --- /dev/null +++ b/common/test_switch_state.py @@ -0,0 +1,12 @@ +from tencentcloud.common.circuit_breaker import CircuitBreaker + + +def test_switch_state(mocker): + breaker_setting = mocker.MagicMock() + breaker_setting.window_interval.return_value = 10 + cb = CircuitBreaker(breaker_setting) + assert cb.switch_state(0, 0) is None + + to_new_generation = mocker.patch.object(cb, "to_new_generation") + cb.switch_state(1,0) + to_new_generation.assert_called_once() diff --git a/common/test_tencent_cloud_sdk_exception.py b/common/test_tencent_cloud_sdk_exception.py new file mode 100644 index 000000000..0a7f35d81 --- /dev/null +++ b/common/test_tencent_cloud_sdk_exception.py @@ -0,0 +1,10 @@ +from tencentcloud.common.exception import TencentCloudSDKException + + +def test_tencent_cloud_sdk_exception_get(): + exception = TencentCloudSDKException("code", "message", "requestId") + assert exception.get_code() == "code" + assert exception.get_message() == "message" + assert exception.get_request_id() == "requestId" + + assert exception.__str__() == "[TencentCloudSDKException] code:code message:message requestId:requestId" diff --git a/common/test_to_new_generation.py b/common/test_to_new_generation.py new file mode 100644 index 000000000..9b6a5fbce --- /dev/null +++ b/common/test_to_new_generation.py @@ -0,0 +1,22 @@ +from tencentcloud.common.circuit_breaker import CircuitBreaker + + +class BreakerSetting: + def __init__(self, window_interval, timeout): + self.window_interval = window_interval + self.timeout = timeout + + +def test_to_new_generation(mocker): + breaker_setting = BreakerSetting(10, 10) + cb = CircuitBreaker(breaker_setting) + cb.state = 0 + cb.to_new_generation(1) + assert cb.expiry == 11 + cb.state = 2 + cb.to_new_generation(1) + assert cb.expiry == 11 + cb.state = 1 + with mocker.patch('time.time', return_value=1234567): + cb.to_new_generation(1) + assert cb.expiry == 1234567 From 5b34e81d703be17944f21e0e55f27896c9b678e6 Mon Sep 17 00:00:00 2001 From: wenjiezzou Date: Sun, 29 Sep 2024 19:57:58 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E9=9C=80=E8=A6=81=E5=BC=95=E8=BF=9B?= =?UTF-8?q?=EF=BC=9Apip=20install=20pytest-mock?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 1hunyuan/test_chat_completions.py | 62 -------- 1hunyuan/test_hunyuan_get_embedding.py | 39 ----- 1hunyuan/test_hunyuan_get_token_count.py | 40 ----- 1hunyuan/test_submit_hunyuan_image_job.py | 39 ----- {1hunyuan => tests/unit/common}/__init__.py | 0 {common => tests/unit/common}/test.log | 0 .../unit/common}/test_build_req_inter.py | 0 ...test_build_req_with_old_signature_inter.py | 0 .../test_build_req_without_signature.py | 0 .../common}/test_call_with_region_breaker.py | 0 tests/unit/common/test_chat_completions.py | 150 ++++++++++++++++++ .../common}/test_cvm_role_credential_init.py | 0 .../test_default_credential_provider.py | 0 ...test_default_tke_oidc_role_arn_provider.py | 0 .../unit/common}/test_empty_handle.py | 0 .../test_environment_variable_credential.py | 0 .../unit/common}/test_get_role_name.py | 0 .../unit/common}/test_https_pre_conn_pool.py | 0 .../unit/common}/test_init_credential.py | 0 .../common}/test_need_refresh_has_None.py | 0 .../common}/test_oidc_role_arn_credential.py | 0 .../unit/common}/test_on_failure.py | 0 .../common}/test_on_success_or_failure.py | 0 .../test_params_is_dict_and_format_params.py | 0 .../unit/common}/test_pre_conn_adapter.py | 0 .../unit/common}/test_process_response.py | 0 .../unit/common}/test_process_response_sse.py | 0 .../test_profile_credential_get_credential.py | 0 .../common}/test_response_pretty_formatter.py | 0 .../unit/common}/test_set_file_logger.py | 0 .../unit/common}/test_set_stream_logger.py | 0 .../test_sts_assume_role_credential_init.py | 0 .../unit/common}/test_switch_state.py | 0 .../test_tencent_cloud_sdk_exception.py | 0 .../unit/common}/test_to_new_generation.py | 0 {common => tests/unit/hunyuan}/__init__.py | 0 .../hunyuan}/test_chat_completions_request.py | 0 .../test_chat_completions_response.py | 0 .../unit/hunyuan}/test_hunyuan_choice.py | 0 .../unit/hunyuan}/test_hunyuan_content.py | 0 .../unit/hunyuan}/test_hunyuan_delta.py | 0 .../hunyuan}/test_hunyuan_embedding_data.py | 0 .../hunyuan}/test_hunyuan_embedding_usage.py | 0 .../unit/hunyuan}/test_hunyuan_error_msg.py | 0 .../test_hunyuan_get_embedding_request.py | 0 .../test_hunyuan_get_embedding_response.py | 0 .../test_hunyuan_get_token_count_request.py | 0 .../test_hunyuan_get_token_count_response.py | 0 .../unit/hunyuan}/test_hunyuan_image_url.py | 0 .../unit/hunyuan}/test_hunyuan_message.py | 0 .../unit/hunyuan}/test_hunyuan_tool.py | 0 .../unit/hunyuan}/test_hunyuan_tool_call.py | 0 .../test_hunyuan_tool_call_function.py | 0 .../hunyuan}/test_hunyuan_tool_function.py | 0 .../unit/hunyuan}/test_hunyuan_usage.py | 0 .../test_query_hunyuan_image_job_request.py | 0 .../test_query_hunyuan_image_job_response.py | 0 .../test_submit_hunyuan_image_job_request.py | 0 .../test_submit_hunyuan_image_job_response.py | 0 59 files changed, 150 insertions(+), 180 deletions(-) delete mode 100644 1hunyuan/test_chat_completions.py delete mode 100644 1hunyuan/test_hunyuan_get_embedding.py delete mode 100644 1hunyuan/test_hunyuan_get_token_count.py delete mode 100644 1hunyuan/test_submit_hunyuan_image_job.py rename {1hunyuan => tests/unit/common}/__init__.py (100%) rename {common => tests/unit/common}/test.log (100%) rename {common => tests/unit/common}/test_build_req_inter.py (100%) rename {common => tests/unit/common}/test_build_req_with_old_signature_inter.py (100%) rename {common => tests/unit/common}/test_build_req_without_signature.py (100%) rename {common => tests/unit/common}/test_call_with_region_breaker.py (100%) create mode 100644 tests/unit/common/test_chat_completions.py rename {common => tests/unit/common}/test_cvm_role_credential_init.py (100%) rename {common => tests/unit/common}/test_default_credential_provider.py (100%) rename {common => tests/unit/common}/test_default_tke_oidc_role_arn_provider.py (100%) rename {common => tests/unit/common}/test_empty_handle.py (100%) rename {common => tests/unit/common}/test_environment_variable_credential.py (100%) rename {common => tests/unit/common}/test_get_role_name.py (100%) rename {common => tests/unit/common}/test_https_pre_conn_pool.py (100%) rename {common => tests/unit/common}/test_init_credential.py (100%) rename {common => tests/unit/common}/test_need_refresh_has_None.py (100%) rename {common => tests/unit/common}/test_oidc_role_arn_credential.py (100%) rename {common => tests/unit/common}/test_on_failure.py (100%) rename {common => tests/unit/common}/test_on_success_or_failure.py (100%) rename {common => tests/unit/common}/test_params_is_dict_and_format_params.py (100%) rename {common => tests/unit/common}/test_pre_conn_adapter.py (100%) rename {common => tests/unit/common}/test_process_response.py (100%) rename {common => tests/unit/common}/test_process_response_sse.py (100%) rename {common => tests/unit/common}/test_profile_credential_get_credential.py (100%) rename {common => tests/unit/common}/test_response_pretty_formatter.py (100%) rename {common => tests/unit/common}/test_set_file_logger.py (100%) rename {common => tests/unit/common}/test_set_stream_logger.py (100%) rename {common => tests/unit/common}/test_sts_assume_role_credential_init.py (100%) rename {common => tests/unit/common}/test_switch_state.py (100%) rename {common => tests/unit/common}/test_tencent_cloud_sdk_exception.py (100%) rename {common => tests/unit/common}/test_to_new_generation.py (100%) rename {common => tests/unit/hunyuan}/__init__.py (100%) rename {1hunyuan => tests/unit/hunyuan}/test_chat_completions_request.py (100%) rename {1hunyuan => tests/unit/hunyuan}/test_chat_completions_response.py (100%) rename {1hunyuan => tests/unit/hunyuan}/test_hunyuan_choice.py (100%) rename {1hunyuan => tests/unit/hunyuan}/test_hunyuan_content.py (100%) rename {1hunyuan => tests/unit/hunyuan}/test_hunyuan_delta.py (100%) rename {1hunyuan => tests/unit/hunyuan}/test_hunyuan_embedding_data.py (100%) rename {1hunyuan => tests/unit/hunyuan}/test_hunyuan_embedding_usage.py (100%) rename {1hunyuan => tests/unit/hunyuan}/test_hunyuan_error_msg.py (100%) rename {1hunyuan => tests/unit/hunyuan}/test_hunyuan_get_embedding_request.py (100%) rename {1hunyuan => tests/unit/hunyuan}/test_hunyuan_get_embedding_response.py (100%) rename {1hunyuan => tests/unit/hunyuan}/test_hunyuan_get_token_count_request.py (100%) rename {1hunyuan => tests/unit/hunyuan}/test_hunyuan_get_token_count_response.py (100%) rename {1hunyuan => tests/unit/hunyuan}/test_hunyuan_image_url.py (100%) rename {1hunyuan => tests/unit/hunyuan}/test_hunyuan_message.py (100%) rename {1hunyuan => tests/unit/hunyuan}/test_hunyuan_tool.py (100%) rename {1hunyuan => tests/unit/hunyuan}/test_hunyuan_tool_call.py (100%) rename {1hunyuan => tests/unit/hunyuan}/test_hunyuan_tool_call_function.py (100%) rename {1hunyuan => tests/unit/hunyuan}/test_hunyuan_tool_function.py (100%) rename {1hunyuan => tests/unit/hunyuan}/test_hunyuan_usage.py (100%) rename {1hunyuan => tests/unit/hunyuan}/test_query_hunyuan_image_job_request.py (100%) rename {1hunyuan => tests/unit/hunyuan}/test_query_hunyuan_image_job_response.py (100%) rename {1hunyuan => tests/unit/hunyuan}/test_submit_hunyuan_image_job_request.py (100%) rename {1hunyuan => tests/unit/hunyuan}/test_submit_hunyuan_image_job_response.py (100%) diff --git a/1hunyuan/test_chat_completions.py b/1hunyuan/test_chat_completions.py deleted file mode 100644 index d4a69c664..000000000 --- a/1hunyuan/test_chat_completions.py +++ /dev/null @@ -1,62 +0,0 @@ -import json -import os -import types - -import pytest - -from tencentcloud.common import credential -from tencentcloud.common.exception import TencentCloudSDKException -from tencentcloud.common.profile.client_profile import ClientProfile -from tencentcloud.common.profile.http_profile import HttpProfile -from tencentcloud.hunyuan.v20230901 import hunyuan_client, models - - -def test_chat_completions(): - cred = credential.Credential( - os.environ.get("TENCENTCLOUD_SECRET_ID"), - os.environ.get("TENCENTCLOUD_SECRET_KEY")) - httpProfile = HttpProfile() - httpProfile.endpoint = "hunyuan.tencentcloudapi.com" - - clientProfile = ClientProfile() - clientProfile.httpProfile = httpProfile - client = hunyuan_client.HunyuanClient(cred, "", clientProfile) - - req = models.ChatCompletionsRequest() - params = { - "Model": "hunyuan-pro", - "Messages": [ - { - "Role": "user", - "Content": "你好啊,早上好" - } - ] - } - req.from_json_string(json.dumps(params)) - - # 返回的resp是一个ChatCompletionsResponse的实例,与请求对象对应 - resp = client.ChatCompletions(req) - assert isinstance(resp, types.GeneratorType) is False - - req1 = models.ChatCompletionsRequest() - params = { - "Model": "hunyuan-pro", - "Messages": [ - { - "Role": "user", - "Content": "你好啊,早上好" - } - ], - "Stream": True - } - req1.from_json_string(json.dumps(params)) - - resp = client.ChatCompletions(req1) - assert isinstance(resp, types.GeneratorType) is True - - -def test_chat_completions_with_exception(): - with pytest.raises(TencentCloudSDKException): - client = hunyuan_client.HunyuanClient(None, "", None) - params = {} - client.ChatCompletions(params) diff --git a/1hunyuan/test_hunyuan_get_embedding.py b/1hunyuan/test_hunyuan_get_embedding.py deleted file mode 100644 index b3329c7ef..000000000 --- a/1hunyuan/test_hunyuan_get_embedding.py +++ /dev/null @@ -1,39 +0,0 @@ -import json -import os - -import pytest - -from tencentcloud.common import credential -from tencentcloud.common.exception import TencentCloudSDKException -from tencentcloud.common.profile.client_profile import ClientProfile -from tencentcloud.common.profile.http_profile import HttpProfile -from tencentcloud.hunyuan.v20230901 import hunyuan_client, models - - -def test_hunyuan_get_embedding(): - cred = credential.Credential( - os.environ.get("TENCENTCLOUD_SECRET_ID"), - os.environ.get("TENCENTCLOUD_SECRET_KEY")) - - httpProfile = HttpProfile() - httpProfile.endpoint = "hunyuan.tencentcloudapi.com" - - clientProfile = ClientProfile() - clientProfile.httpProfile = httpProfile - client = hunyuan_client.HunyuanClient(cred, "", clientProfile) - - req = models.GetEmbeddingRequest() - params = { - "Input": "你好" - } - req.from_json_string(json.dumps(params)) - - resp = client.GetEmbedding(req) - assert resp is not None - - -def test_hunyuan_get_embedding_with_exception(): - with pytest.raises(TencentCloudSDKException): - client = hunyuan_client.HunyuanClient(None, "", None) - params = {} - client.GetEmbedding(params) diff --git a/1hunyuan/test_hunyuan_get_token_count.py b/1hunyuan/test_hunyuan_get_token_count.py deleted file mode 100644 index ad993118d..000000000 --- a/1hunyuan/test_hunyuan_get_token_count.py +++ /dev/null @@ -1,40 +0,0 @@ -import json -import os - -import pytest - -from tencentcloud.common import credential -from tencentcloud.common.exception import TencentCloudSDKException -from tencentcloud.common.profile.client_profile import ClientProfile -from tencentcloud.common.profile.http_profile import HttpProfile -from tencentcloud.hunyuan.v20230901 import hunyuan_client, models - - -def test_hunyuan_get_token_count(): - cred = credential.Credential( - os.environ.get("TENCENTCLOUD_SECRET_ID"), - os.environ.get("TENCENTCLOUD_SECRET_KEY")) - httpProfile = HttpProfile() - httpProfile.endpoint = "hunyuan.tencentcloudapi.com" - - clientProfile = ClientProfile() - clientProfile.httpProfile = httpProfile - client = hunyuan_client.HunyuanClient(cred, "", clientProfile) - - req = models.GetTokenCountRequest() - params = { - "Prompt": "你好" - } - req.from_json_string(json.dumps(params)) - - resp = client.GetTokenCount(req) - assert resp.TokenCount == 1 - assert resp.CharacterCount == 2 - assert resp.Tokens == ["你好"] - - -def test_hunyuan_get_token_count_with_exception(): - with pytest.raises(TencentCloudSDKException): - client = hunyuan_client.HunyuanClient(None, "", None) - params = {} - client.GetTokenCount(params) diff --git a/1hunyuan/test_submit_hunyuan_image_job.py b/1hunyuan/test_submit_hunyuan_image_job.py deleted file mode 100644 index 5c5d15e13..000000000 --- a/1hunyuan/test_submit_hunyuan_image_job.py +++ /dev/null @@ -1,39 +0,0 @@ -import json -import os - -import pytest - -from tencentcloud.common import credential -from tencentcloud.common.exception import TencentCloudSDKException -from tencentcloud.common.profile.client_profile import ClientProfile -from tencentcloud.common.profile.http_profile import HttpProfile -from tencentcloud.hunyuan.v20230901 import hunyuan_client, models - - -def test_submit_hunyuan_image_job(): - cred = credential.Credential( - os.environ.get("TENCENTCLOUD_SECRET_ID"), - os.environ.get("TENCENTCLOUD_SECRET_KEY")) - - httpProfile = HttpProfile() - httpProfile.endpoint = "hunyuan.tencentcloudapi.com" - - clientProfile = ClientProfile() - clientProfile.httpProfile = httpProfile - client = hunyuan_client.HunyuanClient(cred, "ap-guangzhou", clientProfile) - - req = models.SubmitHunyuanImageJobRequest() - params = { - "Prompt": "火山" - } - req.from_json_string(json.dumps(params)) - - resp = client.SubmitHunyuanImageJob(req) - assert resp is not None - - -def test_submit_hunyuan_image_job_with_exception(): - with pytest.raises(TencentCloudSDKException): - client = hunyuan_client.HunyuanClient(None, "", None) - params = {} - client.SubmitHunyuanImageJob(params) diff --git a/1hunyuan/__init__.py b/tests/unit/common/__init__.py similarity index 100% rename from 1hunyuan/__init__.py rename to tests/unit/common/__init__.py diff --git a/common/test.log b/tests/unit/common/test.log similarity index 100% rename from common/test.log rename to tests/unit/common/test.log diff --git a/common/test_build_req_inter.py b/tests/unit/common/test_build_req_inter.py similarity index 100% rename from common/test_build_req_inter.py rename to tests/unit/common/test_build_req_inter.py diff --git a/common/test_build_req_with_old_signature_inter.py b/tests/unit/common/test_build_req_with_old_signature_inter.py similarity index 100% rename from common/test_build_req_with_old_signature_inter.py rename to tests/unit/common/test_build_req_with_old_signature_inter.py diff --git a/common/test_build_req_without_signature.py b/tests/unit/common/test_build_req_without_signature.py similarity index 100% rename from common/test_build_req_without_signature.py rename to tests/unit/common/test_build_req_without_signature.py diff --git a/common/test_call_with_region_breaker.py b/tests/unit/common/test_call_with_region_breaker.py similarity index 100% rename from common/test_call_with_region_breaker.py rename to tests/unit/common/test_call_with_region_breaker.py diff --git a/tests/unit/common/test_chat_completions.py b/tests/unit/common/test_chat_completions.py new file mode 100644 index 000000000..c942c2f58 --- /dev/null +++ b/tests/unit/common/test_chat_completions.py @@ -0,0 +1,150 @@ +import json +import os +import types + +import pytest + +from tencentcloud.common import credential +from tencentcloud.common.exception import TencentCloudSDKException +from tencentcloud.common.profile.client_profile import ClientProfile +from tencentcloud.common.profile.http_profile import HttpProfile +from tencentcloud.hunyuan.v20230901 import hunyuan_client, models + + +def test_chat_completions(): + cred = credential.Credential( + os.environ.get("TENCENTCLOUD_SECRET_ID"), + os.environ.get("TENCENTCLOUD_SECRET_KEY")) + httpProfile = HttpProfile() + httpProfile.endpoint = "hunyuan.tencentcloudapi.com" + + clientProfile = ClientProfile() + clientProfile.httpProfile = httpProfile + client = hunyuan_client.HunyuanClient(cred, "", clientProfile) + + req = models.ChatCompletionsRequest() + params = { + "Model": "hunyuan-pro", + "Messages": [ + { + "Role": "user", + "Content": "你好啊,早上好" + } + ] + } + req.from_json_string(json.dumps(params)) + + # 返回的resp是一个ChatCompletionsResponse的实例,与请求对象对应 + resp = client.ChatCompletions(req) + assert isinstance(resp, types.GeneratorType) is False + + req1 = models.ChatCompletionsRequest() + params = { + "Model": "hunyuan-pro", + "Messages": [ + { + "Role": "user", + "Content": "你好啊,早上好" + } + ], + "Stream": True + } + req1.from_json_string(json.dumps(params)) + + resp = client.ChatCompletions(req1) + assert isinstance(resp, types.GeneratorType) is True + + +def test_chat_completions_with_exception(): + with pytest.raises(TencentCloudSDKException): + client = hunyuan_client.HunyuanClient(None, "", None) + params = {} + client.ChatCompletions(params) + + +def test_hunyuan_get_embedding(): + cred = credential.Credential( + os.environ.get("TENCENTCLOUD_SECRET_ID"), + os.environ.get("TENCENTCLOUD_SECRET_KEY")) + + httpProfile = HttpProfile() + httpProfile.endpoint = "hunyuan.tencentcloudapi.com" + + clientProfile = ClientProfile() + clientProfile.httpProfile = httpProfile + client = hunyuan_client.HunyuanClient(cred, "", clientProfile) + + req = models.GetEmbeddingRequest() + params = { + "Input": "你好" + } + req.from_json_string(json.dumps(params)) + + resp = client.GetEmbedding(req) + assert resp is not None + + +def test_hunyuan_get_embedding_with_exception(): + with pytest.raises(TencentCloudSDKException): + client = hunyuan_client.HunyuanClient(None, "", None) + params = {} + client.GetEmbedding(params) + + +def test_hunyuan_get_token_count(): + cred = credential.Credential( + os.environ.get("TENCENTCLOUD_SECRET_ID"), + os.environ.get("TENCENTCLOUD_SECRET_KEY")) + httpProfile = HttpProfile() + httpProfile.endpoint = "hunyuan.tencentcloudapi.com" + + clientProfile = ClientProfile() + clientProfile.httpProfile = httpProfile + client = hunyuan_client.HunyuanClient(cred, "", clientProfile) + + req = models.GetTokenCountRequest() + params = { + "Prompt": "你好" + } + req.from_json_string(json.dumps(params)) + + resp = client.GetTokenCount(req) + assert resp.TokenCount == 1 + assert resp.CharacterCount == 2 + assert resp.Tokens == ["你好"] + + +def test_hunyuan_get_token_count_with_exception(): + with pytest.raises(TencentCloudSDKException): + client = hunyuan_client.HunyuanClient(None, "", None) + params = {} + client.GetTokenCount(params) + + +def test_submit_hunyuan_image_job(): + cred = credential.Credential( + os.environ.get("TENCENTCLOUD_SECRET_ID"), + os.environ.get("TENCENTCLOUD_SECRET_KEY")) + + httpProfile = HttpProfile() + httpProfile.endpoint = "hunyuan.tencentcloudapi.com" + + clientProfile = ClientProfile() + clientProfile.httpProfile = httpProfile + client = hunyuan_client.HunyuanClient(cred, "ap-guangzhou", clientProfile) + + req = models.SubmitHunyuanImageJobRequest() + params = { + "Prompt": "火山" + } + req.from_json_string(json.dumps(params)) + + resp = client.SubmitHunyuanImageJob(req) + assert resp is not None + + +def test_submit_hunyuan_image_job_with_exception(): + with pytest.raises(TencentCloudSDKException): + client = hunyuan_client.HunyuanClient(None, "", None) + params = {} + client.SubmitHunyuanImageJob(params) diff --git a/common/test_cvm_role_credential_init.py b/tests/unit/common/test_cvm_role_credential_init.py similarity index 100% rename from common/test_cvm_role_credential_init.py rename to tests/unit/common/test_cvm_role_credential_init.py diff --git a/common/test_default_credential_provider.py b/tests/unit/common/test_default_credential_provider.py similarity index 100% rename from common/test_default_credential_provider.py rename to tests/unit/common/test_default_credential_provider.py diff --git a/common/test_default_tke_oidc_role_arn_provider.py b/tests/unit/common/test_default_tke_oidc_role_arn_provider.py similarity index 100% rename from common/test_default_tke_oidc_role_arn_provider.py rename to tests/unit/common/test_default_tke_oidc_role_arn_provider.py diff --git a/common/test_empty_handle.py b/tests/unit/common/test_empty_handle.py similarity index 100% rename from common/test_empty_handle.py rename to tests/unit/common/test_empty_handle.py diff --git a/common/test_environment_variable_credential.py b/tests/unit/common/test_environment_variable_credential.py similarity index 100% rename from common/test_environment_variable_credential.py rename to tests/unit/common/test_environment_variable_credential.py diff --git a/common/test_get_role_name.py b/tests/unit/common/test_get_role_name.py similarity index 100% rename from common/test_get_role_name.py rename to tests/unit/common/test_get_role_name.py diff --git a/common/test_https_pre_conn_pool.py b/tests/unit/common/test_https_pre_conn_pool.py similarity index 100% rename from common/test_https_pre_conn_pool.py rename to tests/unit/common/test_https_pre_conn_pool.py diff --git a/common/test_init_credential.py b/tests/unit/common/test_init_credential.py similarity index 100% rename from common/test_init_credential.py rename to tests/unit/common/test_init_credential.py diff --git a/common/test_need_refresh_has_None.py b/tests/unit/common/test_need_refresh_has_None.py similarity index 100% rename from common/test_need_refresh_has_None.py rename to tests/unit/common/test_need_refresh_has_None.py diff --git a/common/test_oidc_role_arn_credential.py b/tests/unit/common/test_oidc_role_arn_credential.py similarity index 100% rename from common/test_oidc_role_arn_credential.py rename to tests/unit/common/test_oidc_role_arn_credential.py diff --git a/common/test_on_failure.py b/tests/unit/common/test_on_failure.py similarity index 100% rename from common/test_on_failure.py rename to tests/unit/common/test_on_failure.py diff --git a/common/test_on_success_or_failure.py b/tests/unit/common/test_on_success_or_failure.py similarity index 100% rename from common/test_on_success_or_failure.py rename to tests/unit/common/test_on_success_or_failure.py diff --git a/common/test_params_is_dict_and_format_params.py b/tests/unit/common/test_params_is_dict_and_format_params.py similarity index 100% rename from common/test_params_is_dict_and_format_params.py rename to tests/unit/common/test_params_is_dict_and_format_params.py diff --git a/common/test_pre_conn_adapter.py b/tests/unit/common/test_pre_conn_adapter.py similarity index 100% rename from common/test_pre_conn_adapter.py rename to tests/unit/common/test_pre_conn_adapter.py diff --git a/common/test_process_response.py b/tests/unit/common/test_process_response.py similarity index 100% rename from common/test_process_response.py rename to tests/unit/common/test_process_response.py diff --git a/common/test_process_response_sse.py b/tests/unit/common/test_process_response_sse.py similarity index 100% rename from common/test_process_response_sse.py rename to tests/unit/common/test_process_response_sse.py diff --git a/common/test_profile_credential_get_credential.py b/tests/unit/common/test_profile_credential_get_credential.py similarity index 100% rename from common/test_profile_credential_get_credential.py rename to tests/unit/common/test_profile_credential_get_credential.py diff --git a/common/test_response_pretty_formatter.py b/tests/unit/common/test_response_pretty_formatter.py similarity index 100% rename from common/test_response_pretty_formatter.py rename to tests/unit/common/test_response_pretty_formatter.py diff --git a/common/test_set_file_logger.py b/tests/unit/common/test_set_file_logger.py similarity index 100% rename from common/test_set_file_logger.py rename to tests/unit/common/test_set_file_logger.py diff --git a/common/test_set_stream_logger.py b/tests/unit/common/test_set_stream_logger.py similarity index 100% rename from common/test_set_stream_logger.py rename to tests/unit/common/test_set_stream_logger.py diff --git a/common/test_sts_assume_role_credential_init.py b/tests/unit/common/test_sts_assume_role_credential_init.py similarity index 100% rename from common/test_sts_assume_role_credential_init.py rename to tests/unit/common/test_sts_assume_role_credential_init.py diff --git a/common/test_switch_state.py b/tests/unit/common/test_switch_state.py similarity index 100% rename from common/test_switch_state.py rename to tests/unit/common/test_switch_state.py diff --git a/common/test_tencent_cloud_sdk_exception.py b/tests/unit/common/test_tencent_cloud_sdk_exception.py similarity index 100% rename from common/test_tencent_cloud_sdk_exception.py rename to tests/unit/common/test_tencent_cloud_sdk_exception.py diff --git a/common/test_to_new_generation.py b/tests/unit/common/test_to_new_generation.py similarity index 100% rename from common/test_to_new_generation.py rename to tests/unit/common/test_to_new_generation.py diff --git a/common/__init__.py b/tests/unit/hunyuan/__init__.py similarity index 100% rename from common/__init__.py rename to tests/unit/hunyuan/__init__.py diff --git a/1hunyuan/test_chat_completions_request.py b/tests/unit/hunyuan/test_chat_completions_request.py similarity index 100% rename from 1hunyuan/test_chat_completions_request.py rename to tests/unit/hunyuan/test_chat_completions_request.py diff --git a/1hunyuan/test_chat_completions_response.py b/tests/unit/hunyuan/test_chat_completions_response.py similarity index 100% rename from 1hunyuan/test_chat_completions_response.py rename to tests/unit/hunyuan/test_chat_completions_response.py diff --git a/1hunyuan/test_hunyuan_choice.py b/tests/unit/hunyuan/test_hunyuan_choice.py similarity index 100% rename from 1hunyuan/test_hunyuan_choice.py rename to tests/unit/hunyuan/test_hunyuan_choice.py diff --git a/1hunyuan/test_hunyuan_content.py b/tests/unit/hunyuan/test_hunyuan_content.py similarity index 100% rename from 1hunyuan/test_hunyuan_content.py rename to tests/unit/hunyuan/test_hunyuan_content.py diff --git a/1hunyuan/test_hunyuan_delta.py b/tests/unit/hunyuan/test_hunyuan_delta.py similarity index 100% rename from 1hunyuan/test_hunyuan_delta.py rename to tests/unit/hunyuan/test_hunyuan_delta.py diff --git a/1hunyuan/test_hunyuan_embedding_data.py b/tests/unit/hunyuan/test_hunyuan_embedding_data.py similarity index 100% rename from 1hunyuan/test_hunyuan_embedding_data.py rename to tests/unit/hunyuan/test_hunyuan_embedding_data.py diff --git a/1hunyuan/test_hunyuan_embedding_usage.py b/tests/unit/hunyuan/test_hunyuan_embedding_usage.py similarity index 100% rename from 1hunyuan/test_hunyuan_embedding_usage.py rename to tests/unit/hunyuan/test_hunyuan_embedding_usage.py diff --git a/1hunyuan/test_hunyuan_error_msg.py b/tests/unit/hunyuan/test_hunyuan_error_msg.py similarity index 100% rename from 1hunyuan/test_hunyuan_error_msg.py rename to tests/unit/hunyuan/test_hunyuan_error_msg.py diff --git a/1hunyuan/test_hunyuan_get_embedding_request.py b/tests/unit/hunyuan/test_hunyuan_get_embedding_request.py similarity index 100% rename from 1hunyuan/test_hunyuan_get_embedding_request.py rename to tests/unit/hunyuan/test_hunyuan_get_embedding_request.py diff --git a/1hunyuan/test_hunyuan_get_embedding_response.py b/tests/unit/hunyuan/test_hunyuan_get_embedding_response.py similarity index 100% rename from 1hunyuan/test_hunyuan_get_embedding_response.py rename to tests/unit/hunyuan/test_hunyuan_get_embedding_response.py diff --git a/1hunyuan/test_hunyuan_get_token_count_request.py b/tests/unit/hunyuan/test_hunyuan_get_token_count_request.py similarity index 100% rename from 1hunyuan/test_hunyuan_get_token_count_request.py rename to tests/unit/hunyuan/test_hunyuan_get_token_count_request.py diff --git a/1hunyuan/test_hunyuan_get_token_count_response.py b/tests/unit/hunyuan/test_hunyuan_get_token_count_response.py similarity index 100% rename from 1hunyuan/test_hunyuan_get_token_count_response.py rename to tests/unit/hunyuan/test_hunyuan_get_token_count_response.py diff --git a/1hunyuan/test_hunyuan_image_url.py b/tests/unit/hunyuan/test_hunyuan_image_url.py similarity index 100% rename from 1hunyuan/test_hunyuan_image_url.py rename to tests/unit/hunyuan/test_hunyuan_image_url.py diff --git a/1hunyuan/test_hunyuan_message.py b/tests/unit/hunyuan/test_hunyuan_message.py similarity index 100% rename from 1hunyuan/test_hunyuan_message.py rename to tests/unit/hunyuan/test_hunyuan_message.py diff --git a/1hunyuan/test_hunyuan_tool.py b/tests/unit/hunyuan/test_hunyuan_tool.py similarity index 100% rename from 1hunyuan/test_hunyuan_tool.py rename to tests/unit/hunyuan/test_hunyuan_tool.py diff --git a/1hunyuan/test_hunyuan_tool_call.py b/tests/unit/hunyuan/test_hunyuan_tool_call.py similarity index 100% rename from 1hunyuan/test_hunyuan_tool_call.py rename to tests/unit/hunyuan/test_hunyuan_tool_call.py diff --git a/1hunyuan/test_hunyuan_tool_call_function.py b/tests/unit/hunyuan/test_hunyuan_tool_call_function.py similarity index 100% rename from 1hunyuan/test_hunyuan_tool_call_function.py rename to tests/unit/hunyuan/test_hunyuan_tool_call_function.py diff --git a/1hunyuan/test_hunyuan_tool_function.py b/tests/unit/hunyuan/test_hunyuan_tool_function.py similarity index 100% rename from 1hunyuan/test_hunyuan_tool_function.py rename to tests/unit/hunyuan/test_hunyuan_tool_function.py diff --git a/1hunyuan/test_hunyuan_usage.py b/tests/unit/hunyuan/test_hunyuan_usage.py similarity index 100% rename from 1hunyuan/test_hunyuan_usage.py rename to tests/unit/hunyuan/test_hunyuan_usage.py diff --git a/1hunyuan/test_query_hunyuan_image_job_request.py b/tests/unit/hunyuan/test_query_hunyuan_image_job_request.py similarity index 100% rename from 1hunyuan/test_query_hunyuan_image_job_request.py rename to tests/unit/hunyuan/test_query_hunyuan_image_job_request.py diff --git a/1hunyuan/test_query_hunyuan_image_job_response.py b/tests/unit/hunyuan/test_query_hunyuan_image_job_response.py similarity index 100% rename from 1hunyuan/test_query_hunyuan_image_job_response.py rename to tests/unit/hunyuan/test_query_hunyuan_image_job_response.py diff --git a/1hunyuan/test_submit_hunyuan_image_job_request.py b/tests/unit/hunyuan/test_submit_hunyuan_image_job_request.py similarity index 100% rename from 1hunyuan/test_submit_hunyuan_image_job_request.py rename to tests/unit/hunyuan/test_submit_hunyuan_image_job_request.py diff --git a/1hunyuan/test_submit_hunyuan_image_job_response.py b/tests/unit/hunyuan/test_submit_hunyuan_image_job_response.py similarity index 100% rename from 1hunyuan/test_submit_hunyuan_image_job_response.py rename to tests/unit/hunyuan/test_submit_hunyuan_image_job_response.py From e8a18066f531393d61795447e3652c5ae7264c97 Mon Sep 17 00:00:00 2001 From: wenjiezzou Date: Wed, 27 Nov 2024 20:51:39 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E9=87=8D=E6=9E=84=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/unit/refactoring/__init__.py | 0 tests/unit/refactoring/test_specify_proxy.py | 27 +++++++++ .../test_sts_assume_role_credential.py | 24 ++++++++ tests/unit/refactoring/test_v1_signature.py | 28 +++++++++ tests/unit/refactoring/test_v3_signature.py | 58 +++++++++++++++++++ 5 files changed, 137 insertions(+) create mode 100644 tests/unit/refactoring/__init__.py create mode 100644 tests/unit/refactoring/test_specify_proxy.py create mode 100644 tests/unit/refactoring/test_sts_assume_role_credential.py create mode 100644 tests/unit/refactoring/test_v1_signature.py create mode 100644 tests/unit/refactoring/test_v3_signature.py diff --git a/tests/unit/refactoring/__init__.py b/tests/unit/refactoring/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/unit/refactoring/test_specify_proxy.py b/tests/unit/refactoring/test_specify_proxy.py new file mode 100644 index 000000000..def3a6d5e --- /dev/null +++ b/tests/unit/refactoring/test_specify_proxy.py @@ -0,0 +1,27 @@ +import requests +from mock.mock import patch + +from tencentcloud.common.http.request import ProxyConnection + + +class TestProxyConnection: + def test_default_proxy(self): + conn = ProxyConnection(host="example.com") + assert conn.request_host == "example.com" + assert conn.timeout == 60 + assert conn.proxy is None + assert conn.certification is not None + assert conn.request_length == 0 + assert isinstance(conn._session, requests.Session) + + @patch('tencentcloud.common.http.request._get_proxy_from_env') + def test_with_proxy(self, mock_proxy_from_env): + # 存在proxy时 + conn = ProxyConnection(host="example.com", proxy="http://127.0.0.1:8080") + assert conn.request_host == "example.com" + assert conn.proxy == {"http": "http://127.0.0.1:8080", "https": "http://127.0.0.1:8080"} + # 不存在proxy时 + mock_proxy_from_env.return_value = "http://127.0.0.1:8080" + conn = ProxyConnection(host="example.com") + assert conn.request_host == "example.com" + assert conn.proxy == {"http": "http://127.0.0.1:8080", "https": "http://127.0.0.1:8080"} \ No newline at end of file diff --git a/tests/unit/refactoring/test_sts_assume_role_credential.py b/tests/unit/refactoring/test_sts_assume_role_credential.py new file mode 100644 index 000000000..6018a7a94 --- /dev/null +++ b/tests/unit/refactoring/test_sts_assume_role_credential.py @@ -0,0 +1,24 @@ +from mock.mock import patch + +from tencentcloud.common.credential import STSAssumeRoleCredential + + +@patch('tencentcloud.common.credential.CommonClient') +def test_sts_assume_role_credential(mock_client): + credential = STSAssumeRoleCredential('secret_id', 'secret_key', 'role_name', 'role_session_name') + client = mock_client.return_value + client.call_json.return_value = { + "Response": { + "Credentials": { + "Token": "mocked_token", + "TmpSecretId": "mocked_tmp_secret_id", + "TmpSecretKey": "mocked_tmp_secret_key" + }, + "ExpiredTime": 1633072800 + } + } + credential.get_sts_tmp_role_arn() + assert credential._token == 'mocked_token' + assert credential._tmp_secret_id == 'mocked_tmp_secret_id' + assert credential._tmp_secret_key == 'mocked_tmp_secret_key' + assert credential._expired_time == 1633066320.0 diff --git a/tests/unit/refactoring/test_v1_signature.py b/tests/unit/refactoring/test_v1_signature.py new file mode 100644 index 000000000..a138097b9 --- /dev/null +++ b/tests/unit/refactoring/test_v1_signature.py @@ -0,0 +1,28 @@ +from mock.mock import patch, MagicMock + +from tencentcloud.common.http.request import RequestInternal + +from tencentcloud.common import abstract_client, credential + + +@patch("tencentcloud.common.abstract_client.Sign.sign") +@patch("tencentcloud.common.abstract_client.random.randint") +@patch("tencentcloud.common.abstract_client.time.time") +def test_build_req_with_old_signature_inter_correct(mock_time, mock_randint, mock_sign): + mock_sign.return_value = "mocked_sign" + mock_time.return_value = 1590000000 + mock_randint.return_value = 123456789 + cred = credential.Credential("secret_id", "secret_key") + client = abstract_client.AbstractClient(cred, "ap-shanghai", None) + req = RequestInternal(method="GET", header={"Content-Type": "application"}, data="") + client.request_client = 'test_client' + client._apiVersion = '2020-01-01' + client.region = 'ap-guangzhou' + client.profile = MagicMock() + client.profile.signMethod = 'HmacSHA256' + client.profile.language = 'zh-CN' + client._build_req_with_old_signature("DELETE", {}, req) + assert req.data == ("Action=DELETE&RequestClient=test_client&Nonce=123456789&Timestamp=1590000000&Version=2020-01" + "-01&Region=ap-guangzhou&SecretId=secret_id&SignatureMethod=HmacSHA256&Language=zh-CN" + "&Signature=mocked_sign") + assert req.header["Content-Type"] == "application/x-www-form-urlencoded" diff --git a/tests/unit/refactoring/test_v3_signature.py b/tests/unit/refactoring/test_v3_signature.py new file mode 100644 index 000000000..46a1aa1e2 --- /dev/null +++ b/tests/unit/refactoring/test_v3_signature.py @@ -0,0 +1,58 @@ +from mock.mock import MagicMock, patch +from tencentcloud.common.http.request import RequestInternal + +from tencentcloud.common import abstract_client, credential +from tencentcloud.common.exception import TencentCloudSDKException + + +@patch('tencentcloud.common.abstract_client.AbstractClient._get_tc3_signature') +@patch('tencentcloud.common.abstract_client.time.time') +def test_build_req_with_tc3_signature(mock_time, mock_get_tc3_signature): + mock_time.return_value = 1732608295 + mock_get_tc3_signature.return_value = 'mocked_signature' + cred = credential.Credential("secret_id", "secret_key") + client = abstract_client.AbstractClient(cred, "ap-shanghai", None) + # 测试异常情况 + header = { + "Content-Type": "application/json", + "host": "127.0.0.1", + "X-TC-Action": "DescribeInstances", + "X-TC-RequestClient": "tencentcloud-python", + "X-TC-Version": "2018-04-09", + "X-TC-Timestamp": "1527899580", + "Auth": None + } + req = RequestInternal(method="GET", header=header) + options = {"IsMultipart": True} + try: + client._build_req_with_tc3_signature("DescribeInstances", {}, req, options) + except TencentCloudSDKException as e: + assert e.message == "Invalid request method GET for multipart." + assert e.code == "ClientError" + + # 测试正常情况 + req = RequestInternal(method="GET", header={"Content-Type": "application"}) + client._build_req_with_tc3_signature("DescribeInstances", {}, req, None) + assert req.header['Content-Type'] == "application/x-www-form-urlencoded" + assert req.header['Host'] == ".tencentcloudapi.com" + assert req.header['X-TC-RequestClient'] == "SDK_PYTHON_3.0.1242" + assert req.header['X-TC-Version'] == "" + assert req.header['X-TC-Timestamp'] == "1732608295" + assert req.header['Authorization'] == ("TC3-HMAC-SHA256 Credential=secret_id/2024-11-26//tc3_request, " + "SignedHeaders=content-type;host, Signature=mocked_signature") + + +@patch('tencentcloud.common.abstract_client.Sign.sign_tc3') +def test_get_tc3_signature(mock_sign_tc3): + mock_sign_tc3.return_value = "mocked_signature" + cred = credential.Credential("secret_id", "secret_key") + client = abstract_client.AbstractClient(cred, "ap-shanghai", None) + header = { + "X-TC-Content-SHA256": "UNSIGNED-PAYLOAD", + "Content-Type": "application/json", + "Host": "cvm.tencentcloudapi.com", + "X-TC-Timestamp": "1732608295" + } + req = RequestInternal(method="GET", header=header, uri="/") + sign = client._get_tc3_signature({}, req, "2024-11-26", "cvm") + assert sign == "mocked_signature"