From d5c9f6a4c4efa4d6241a1d1a8168e63d6398dadf Mon Sep 17 00:00:00 2001 From: Evan Mattson Date: Thu, 11 Jul 2024 14:21:22 -0400 Subject: [PATCH 1/3] Increase unit test coverage --- .../sessions_python_plugin.py | 2 +- .../functions/kernel_function_from_method.py | 20 ++- .../openai_plugin/test_openai_plugin.py | 31 ++++ .../openapi/test_openapi_manager.py | 11 ++ .../test_sessions_python_plugin.py | 159 +++++++++++++++++- .../unit/functions/test_function_result.py | 128 ++++++++++++++ .../test_kernel_function_from_method.py | 2 + python/tests/unit/kernel/test_kernel.py | 12 ++ .../tests/unit/services/test_service_utils.py | 44 +++++ python/tests/unit/utils/test_chat.py | 21 +++ python/tests/unit/utils/test_logging.py | 14 ++ 11 files changed, 433 insertions(+), 11 deletions(-) create mode 100644 python/tests/unit/connectors/openai_plugin/test_openai_plugin.py create mode 100644 python/tests/unit/functions/test_function_result.py create mode 100644 python/tests/unit/utils/test_chat.py create mode 100644 python/tests/unit/utils/test_logging.py diff --git a/python/semantic_kernel/core_plugins/sessions_python_tool/sessions_python_plugin.py b/python/semantic_kernel/core_plugins/sessions_python_tool/sessions_python_plugin.py index fa792d499a20..63cf86a27c08 100644 --- a/python/semantic_kernel/core_plugins/sessions_python_tool/sessions_python_plugin.py +++ b/python/semantic_kernel/core_plugins/sessions_python_tool/sessions_python_plugin.py @@ -289,7 +289,7 @@ async def download_file( Returns: BufferedReader: The data of the downloaded file. """ - auth_token = await self.auth_callback() + auth_token = await self._ensure_auth_token() self.http_client.headers.update( { "Authorization": f"Bearer {auth_token}", diff --git a/python/semantic_kernel/functions/kernel_function_from_method.py b/python/semantic_kernel/functions/kernel_function_from_method.py index efae9ddcbd92..e97c84205d93 100644 --- a/python/semantic_kernel/functions/kernel_function_from_method.py +++ b/python/semantic_kernel/functions/kernel_function_from_method.py @@ -86,7 +86,9 @@ def __init__( "stream_method": ( stream_method if stream_method is not None - else method if isasyncgenfunction(method) or isgeneratorfunction(method) else None + else method + if isasyncgenfunction(method) or isgeneratorfunction(method) + else None ), } @@ -119,9 +121,7 @@ async def _invoke_internal_stream(self, context: FunctionInvocationContext) -> N function_arguments = self.gather_function_parameters(context) context.result = FunctionResult(function=self.metadata, value=self.stream_method(**function_arguments)) - def gather_function_parameters( - self, context: FunctionInvocationContext - ) -> dict[str, Any]: + def gather_function_parameters(self, context: FunctionInvocationContext) -> dict[str, Any]: """Gathers the function parameters from the arguments.""" function_arguments: dict[str, Any] = {} for param in self.parameters: @@ -141,8 +141,12 @@ def gather_function_parameters( continue if param.name in context.arguments: value: Any = context.arguments[param.name] - if (param.type_ and "," not in param.type_ and - param.type_object and param.type_object is not inspect._empty): + if ( + param.type_ + and "," not in param.type_ + and param.type_object + and param.type_object is not inspect._empty + ): if hasattr(param.type_object, "model_validate"): try: value = param.type_object.model_validate(value) @@ -167,7 +171,5 @@ def gather_function_parameters( raise FunctionExecutionException( f"Parameter {param.name} is required but not provided in the arguments." ) - logger.debug( - f"Parameter {param.name} is not provided, using default value {param.default_value}" - ) + logger.debug(f"Parameter {param.name} is not provided, using default value {param.default_value}") return function_arguments diff --git a/python/tests/unit/connectors/openai_plugin/test_openai_plugin.py b/python/tests/unit/connectors/openai_plugin/test_openai_plugin.py new file mode 100644 index 000000000000..000463070721 --- /dev/null +++ b/python/tests/unit/connectors/openai_plugin/test_openai_plugin.py @@ -0,0 +1,31 @@ +# Copyright (c) Microsoft. All rights reserved. + + +import pytest + +from semantic_kernel.connectors.openai_plugin.openai_utils import OpenAIUtils +from semantic_kernel.exceptions import PluginInitializationError + + +def test_parse_openai_manifest_for_openapi_spec_url_valid(): + plugin_json = {"api": {"type": "openapi", "url": "https://example.com/openapi.json"}} + result = OpenAIUtils.parse_openai_manifest_for_openapi_spec_url(plugin_json) + assert result == "https://example.com/openapi.json" + + +def test_parse_openai_manifest_for_openapi_spec_url_missing_api_type(): + plugin_json = {"api": {}} + with pytest.raises(PluginInitializationError, match="OpenAI manifest is missing the API type."): + OpenAIUtils.parse_openai_manifest_for_openapi_spec_url(plugin_json) + + +def test_parse_openai_manifest_for_openapi_spec_url_invalid_api_type(): + plugin_json = {"api": {"type": "other", "url": "https://example.com/openapi.json"}} + with pytest.raises(PluginInitializationError, match="OpenAI manifest is not of type OpenAPI."): + OpenAIUtils.parse_openai_manifest_for_openapi_spec_url(plugin_json) + + +def test_parse_openai_manifest_for_openapi_spec_url_missing_url(): + plugin_json = {"api": {"type": "openapi"}} + with pytest.raises(PluginInitializationError, match="OpenAI manifest is missing the OpenAPI Spec URL."): + OpenAIUtils.parse_openai_manifest_for_openapi_spec_url(plugin_json) diff --git a/python/tests/unit/connectors/openapi/test_openapi_manager.py b/python/tests/unit/connectors/openapi/test_openapi_manager.py index 63fef583c1ff..de5d834c1361 100644 --- a/python/tests/unit/connectors/openapi/test_openapi_manager.py +++ b/python/tests/unit/connectors/openapi/test_openapi_manager.py @@ -10,6 +10,7 @@ ) from semantic_kernel.connectors.openapi_plugin.openapi_manager import ( _create_function_from_operation, + create_functions_from_openapi, ) from semantic_kernel.exceptions import FunctionExecutionException from semantic_kernel.functions.kernel_function_decorator import kernel_function @@ -222,3 +223,13 @@ async def run_openapi_operation(kernel, **kwargs): assert str(result) == "Operation Result" run_operation_mock.assert_called_once() assert runner.run_operation.call_args[0][1]["param1"] == "value1" + + +@pytest.mark.asyncio +@patch("semantic_kernel.connectors.openapi_plugin.openapi_parser.OpenApiParser.parse", return_value=None) +async def test_create_functions_from_openapi_raises_exception(mock_parse): + """Test that an exception is raised when parsing fails.""" + with pytest.raises(FunctionExecutionException, match="Error parsing OpenAPI document: test_openapi_document_path"): + create_functions_from_openapi(plugin_name="test_plugin", openapi_document_path="test_openapi_document_path") + + mock_parse.assert_called_once_with("test_openapi_document_path") diff --git a/python/tests/unit/core_plugins/test_sessions_python_plugin.py b/python/tests/unit/core_plugins/test_sessions_python_plugin.py index 54efad3d1247..e37ddcc65426 100644 --- a/python/tests/unit/core_plugins/test_sessions_python_plugin.py +++ b/python/tests/unit/core_plugins/test_sessions_python_plugin.py @@ -4,8 +4,13 @@ import httpx import pytest +from httpx import HTTPStatusError -from semantic_kernel.core_plugins.sessions_python_tool.sessions_python_plugin import SessionsPythonTool +from semantic_kernel.core_plugins.sessions_python_tool.sessions_python_plugin import ( + SESSIONS_API_VERSION, + SessionsPythonTool, +) +from semantic_kernel.core_plugins.sessions_python_tool.sessions_remote_file_metadata import SessionsRemoteFileMetadata from semantic_kernel.exceptions.function_exceptions import FunctionExecutionException, FunctionInitializationError from semantic_kernel.kernel import Kernel @@ -25,6 +30,53 @@ def test_validate_endpoint(aca_python_sessions_unit_test_env): assert str(plugin.pool_management_endpoint) == aca_python_sessions_unit_test_env["ACA_POOL_MANAGEMENT_ENDPOINT"] +@pytest.mark.parametrize( + "base_url, endpoint, params, expected_url", + [ + ( + "http://example.com", + "api/resource", + {"param1": "value1", "param2": "value2"}, + f"http://example.com/api/resource?param1=value1¶m2=value2&api-version={SESSIONS_API_VERSION}", + ), + ( + "http://example.com/", + "api/resource", + {"param1": "value1"}, + f"http://example.com/api/resource?param1=value1&api-version={SESSIONS_API_VERSION}", + ), + ( + "http://example.com", + "api/resource/", + {"param1": "value1", "param2": "value2"}, + f"http://example.com/api/resource?param1=value1¶m2=value2&api-version={SESSIONS_API_VERSION}", + ), + ( + "http://example.com/", + "api/resource/", + {"param1": "value1"}, + f"http://example.com/api/resource?param1=value1&api-version={SESSIONS_API_VERSION}", + ), + ( + "http://example.com", + "api/resource", + {}, + f"http://example.com/api/resource?api-version={SESSIONS_API_VERSION}", + ), + ( + "http://example.com/", + "api/resource", + {}, + f"http://example.com/api/resource?api-version={SESSIONS_API_VERSION}", + ), + ], +) +def test_build_url_with_version(base_url, endpoint, params, expected_url): + plugin = SessionsPythonTool(auth_callback=auth_callback_test) + result = plugin._build_url_with_version(base_url, endpoint, params) + assert result == expected_url + + @pytest.mark.parametrize( "override_env_param_dict", [ @@ -229,6 +281,37 @@ async def async_return(result): mock_post.assert_awaited_once() +@pytest.mark.asyncio +@patch("httpx.AsyncClient.post") +async def test_upload_file_throws_exception(mock_post): + """Test throwing exception during file upload.""" + + async def async_raise_http_error(*args, **kwargs): + mock_request = httpx.Request(method="POST", url="https://example.com/files/upload") + mock_response = httpx.Response(status_code=500, request=mock_request) + raise HTTPStatusError("Server Error", request=mock_request, response=mock_response) + + with ( + patch( + "semantic_kernel.core_plugins.sessions_python_tool.sessions_python_plugin.SessionsPythonTool._ensure_auth_token", + return_value="test_token", + ), + patch("builtins.open", mock_open(read_data=b"file data")), + ): + mock_post.side_effect = async_raise_http_error + + plugin = SessionsPythonTool( + auth_callback=lambda: "sample_token", + env_file_path="test.env", + ) + + with pytest.raises( + FunctionExecutionException, match="Upload failed with status code 500 and error: Internal Server Error" + ): + await plugin.upload_file(local_file_path="hello.py") + mock_post.assert_awaited_once() + + @pytest.mark.parametrize( "local_file_path, input_remote_file_path, expected_remote_file_path", [ @@ -349,6 +432,36 @@ async def async_return(result): mock_get.assert_awaited_once() +@pytest.mark.asyncio +@patch("httpx.AsyncClient.get") +async def test_list_files_throws_exception(mock_get): + """Test throwing exception during list files.""" + + async def async_raise_http_error(*args, **kwargs): + mock_request = httpx.Request(method="GET", url="https://example.com/files?identifier=None") + mock_response = httpx.Response(status_code=500, request=mock_request) + raise HTTPStatusError("Server Error", request=mock_request, response=mock_response) + + with ( + patch( + "semantic_kernel.core_plugins.sessions_python_tool.sessions_python_plugin.SessionsPythonTool._ensure_auth_token", + return_value="test_token", + ), + ): + mock_get.side_effect = async_raise_http_error + + plugin = SessionsPythonTool( + auth_callback=lambda: "sample_token", + env_file_path="test.env", + ) + + with pytest.raises( + FunctionExecutionException, match="List files failed with status code 500 and error: Internal Server Error" + ): + await plugin.list_files() + mock_get.assert_awaited_once() + + @pytest.mark.asyncio @patch("httpx.AsyncClient.get") async def test_download_file_to_local(mock_get, aca_python_sessions_unit_test_env): @@ -417,6 +530,38 @@ async def mock_auth_callback(): mock_get.assert_awaited_once() +@pytest.mark.asyncio +@patch("httpx.AsyncClient.get") +async def test_download_file_throws_exception(mock_get): + """Test throwing exception during download file.""" + + async def async_raise_http_error(*args, **kwargs): + mock_request = httpx.Request( + method="GET", url="https://example.com/files/content/remote_test.txt?identifier=None" + ) + mock_response = httpx.Response(status_code=500, request=mock_request) + raise HTTPStatusError("Server Error", request=mock_request, response=mock_response) + + with ( + patch( + "semantic_kernel.core_plugins.sessions_python_tool.sessions_python_plugin.SessionsPythonTool._ensure_auth_token", + return_value="test_token", + ), + ): + mock_get.side_effect = async_raise_http_error + + plugin = SessionsPythonTool( + auth_callback=lambda: "sample_token", + env_file_path="test.env", + ) + + with pytest.raises( + FunctionExecutionException, match="Download failed with status code 500 and error: Internal Server Error" + ): + await plugin.download_file(remote_file_name="remote_test.txt") + mock_get.assert_awaited_once() + + @pytest.mark.parametrize( "input_code, expected_output", [ @@ -466,3 +611,15 @@ async def token_cb(): FunctionExecutionException, match="Failed to retrieve the client auth token with messages: Could not get token." ): await plugin._ensure_auth_token() + + +@pytest.mark.parametrize( + "filename, expected_full_path", + [ + ("/mnt/data/testfile.txt", "/mnt/data/testfile.txt"), + ("testfile.txt", "/mnt/data/testfile.txt"), + ], +) +def test_full_path(filename, expected_full_path): + metadata = SessionsRemoteFileMetadata(filename=filename, size_in_bytes=123) + assert metadata.full_path == expected_full_path diff --git a/python/tests/unit/functions/test_function_result.py b/python/tests/unit/functions/test_function_result.py new file mode 100644 index 000000000000..a8f686e9648b --- /dev/null +++ b/python/tests/unit/functions/test_function_result.py @@ -0,0 +1,128 @@ +# Copyright (c) Microsoft. All rights reserved. + +from typing import Any + +import pytest + +from semantic_kernel.contents.kernel_content import KernelContent +from semantic_kernel.exceptions.function_exceptions import FunctionResultError +from semantic_kernel.functions.function_result import FunctionResult +from semantic_kernel.functions.kernel_function_metadata import KernelFunctionMetadata + + +def test_function_result_str_with_value(): + result = FunctionResult( + function=KernelFunctionMetadata(name="test_function", is_prompt=False, is_asynchronous=False), + value="test_value", + ) + assert str(result) == "test_value" + + +def test_function_result_str_with_list_value(): + result = FunctionResult( + function=KernelFunctionMetadata(name="test_function", is_prompt=False, is_asynchronous=False), + value=["test_value1", "test_value2"], + ) + assert str(result) == "test_value1,test_value2" + + +def test_function_result_str_with_kernel_content_list(): + class MockKernelContent(KernelContent): + def __str__(self) -> str: + return "mock_content" + + def to_element(self) -> Any: + pass + + @classmethod + def from_element(cls: type["KernelContent"], element: Any) -> "KernelContent": + pass + + def to_dict(self) -> dict[str, Any]: + pass + + content = MockKernelContent(inner_content="inner_content") + result = FunctionResult( + function=KernelFunctionMetadata(name="test_function", is_prompt=False, is_asynchronous=False), value=[content] + ) + assert str(result) == "mock_content" + + +def test_function_result_str_with_dict_value(): + result = FunctionResult( + function=KernelFunctionMetadata(name="test_function", is_prompt=False, is_asynchronous=False), + value={"key1": "value1", "key2": "value2"}, + ) + assert str(result) == "value2" + + +def test_function_result_str_empty_value(): + result = FunctionResult( + function=KernelFunctionMetadata(name="test_function", is_prompt=False, is_asynchronous=False), value=None + ) + assert str(result) == "" + + +def test_function_result_str_with_conversion_error(): + class Unconvertible: + def __str__(self): + raise ValueError("Cannot convert to string") + + result = FunctionResult( + function=KernelFunctionMetadata(name="test_function", is_prompt=False, is_asynchronous=False), + value=Unconvertible(), + ) + with pytest.raises(FunctionResultError, match="Failed to convert value to string"): + str(result) + + +def test_function_result_get_inner_content_with_list(): + class MockKernelContent(KernelContent): + def __str__(self) -> str: + return "mock_content" + + def to_element(self) -> Any: + pass + + @classmethod + def from_element(cls: type["KernelContent"], element: Any) -> "KernelContent": + pass + + def to_dict(self) -> dict[str, Any]: + pass + + content = MockKernelContent(inner_content="inner_content") + result = FunctionResult( + function=KernelFunctionMetadata(name="test_function", is_prompt=False, is_asynchronous=False), value=[content] + ) + assert result.get_inner_content() == "inner_content" + + +def test_function_result_get_inner_content_with_kernel_content(): + class MockKernelContent(KernelContent): + def __str__(self) -> str: + return "mock_content" + + def to_element(self) -> Any: + pass + + @classmethod + def from_element(cls: type["KernelContent"], element: Any) -> "KernelContent": + pass + + def to_dict(self) -> dict[str, Any]: + pass + + content = MockKernelContent(inner_content="inner_content") + result = FunctionResult( + function=KernelFunctionMetadata(name="test_function", is_prompt=False, is_asynchronous=False), value=content + ) + assert result.get_inner_content() == "inner_content" + + +def test_function_result_get_inner_content_no_inner_content(): + result = FunctionResult( + function=KernelFunctionMetadata(name="test_function", is_prompt=False, is_asynchronous=False), + value="test_value", + ) + assert result.get_inner_content() is None diff --git a/python/tests/unit/functions/test_kernel_function_from_method.py b/python/tests/unit/functions/test_kernel_function_from_method.py index 9afbf4380c95..9944d19d6890 100644 --- a/python/tests/unit/functions/test_kernel_function_from_method.py +++ b/python/tests/unit/functions/test_kernel_function_from_method.py @@ -11,6 +11,7 @@ from semantic_kernel.functions.kernel_function import KernelFunction from semantic_kernel.functions.kernel_function_decorator import kernel_function from semantic_kernel.functions.kernel_function_from_method import KernelFunctionFromMethod +from semantic_kernel.functions.kernel_parameter_metadata import KernelParameterMetadata from semantic_kernel.kernel import Kernel from semantic_kernel.kernel_pydantic import KernelBaseModel @@ -86,6 +87,7 @@ def decorated_function(input: Annotated[str | None, "Test input description"] = assert native_function.parameters[0].default_value == "test_default_value" assert native_function.parameters[0].type_ == "str" assert native_function.parameters[0].is_required is False + assert type(native_function.return_parameter) is KernelParameterMetadata def test_init_native_function_from_kernel_function_decorator_defaults(): diff --git a/python/tests/unit/kernel/test_kernel.py b/python/tests/unit/kernel/test_kernel.py index 13756b7d1ebb..f4e03aff3914 100644 --- a/python/tests/unit/kernel/test_kernel.py +++ b/python/tests/unit/kernel/test_kernel.py @@ -79,6 +79,18 @@ def test_kernel_init_with_plugins(): assert kernel.plugins is not None +def test_kernel_init_with_kernel_plugin_instance(): + plugin = KernelPlugin(name="plugin") + kernel = Kernel(plugins=plugin) + assert kernel.plugins is not None + + +def test_kernel_init_with_kernel_plugin_list(): + plugin = [KernelPlugin(name="plugin")] + kernel = Kernel(plugins=plugin) + assert kernel.plugins is not None + + # endregion # region Invoke Functions diff --git a/python/tests/unit/services/test_service_utils.py b/python/tests/unit/services/test_service_utils.py index 7f1fc669bf1a..8cbb90dc7895 100644 --- a/python/tests/unit/services/test_service_utils.py +++ b/python/tests/unit/services/test_service_utils.py @@ -121,6 +121,24 @@ def test_bool_schema(setup_kernel): assert boolean_schema == expected_schema +def test_bool_schema_no_plugins(setup_kernel): + kernel = setup_kernel + kernel.plugins = None + + boolean_func_metadata = kernel.get_list_of_function_metadata_bool() + + assert boolean_func_metadata == [] + + +def test_bool_schema_with_plugins(setup_kernel): + kernel = setup_kernel + + boolean_func_metadata = kernel.get_list_of_function_metadata_bool() + + assert boolean_func_metadata is not None + assert len(boolean_func_metadata) > 0 + + def test_string_schema(setup_kernel): kernel = setup_kernel @@ -149,6 +167,32 @@ def test_string_schema(setup_kernel): assert string_schema == expected_schema +def test_string_schema_filter_functions(setup_kernel): + kernel = setup_kernel + + string_func_metadata = kernel.get_list_of_function_metadata_filters(filters={"included_functions": ["random"]}) + + assert string_func_metadata == [] + + +def test_string_schema_throws_included_and_excluded_plugins(setup_kernel): + kernel = setup_kernel + + with pytest.raises(ValueError): + _ = kernel.get_list_of_function_metadata_filters( + filters={"included_plugins": ["StringPlugin"], "excluded_plugins": ["BooleanPlugin"]} + ) + + +def test_string_schema_throws_included_and_excluded_functions(setup_kernel): + kernel = setup_kernel + + with pytest.raises(ValueError): + _ = kernel.get_list_of_function_metadata_filters( + filters={"included_functions": ["function1"], "excluded_functions": ["function2"]} + ) + + def test_complex_schema(setup_kernel): kernel = setup_kernel diff --git a/python/tests/unit/utils/test_chat.py b/python/tests/unit/utils/test_chat.py new file mode 100644 index 000000000000..617441af3ac7 --- /dev/null +++ b/python/tests/unit/utils/test_chat.py @@ -0,0 +1,21 @@ +# Copyright (c) Microsoft. All rights reserved. + +from unittest.mock import Mock + +from semantic_kernel.utils.chat import store_results + + +def test_store_results(): + chat_history_mock = Mock() + chat_history_mock.add_message = Mock() + + chat_message_content_mock = Mock() + results = [chat_message_content_mock, chat_message_content_mock] + + updated_chat_history = store_results(chat_history_mock, results) + + assert chat_history_mock.add_message.call_count == len(results) + for message in results: + chat_history_mock.add_message.assert_any_call(message=message) + + assert updated_chat_history == chat_history_mock diff --git a/python/tests/unit/utils/test_logging.py b/python/tests/unit/utils/test_logging.py new file mode 100644 index 000000000000..f178c3fdaedb --- /dev/null +++ b/python/tests/unit/utils/test_logging.py @@ -0,0 +1,14 @@ +# Copyright (c) Microsoft. All rights reserved. + +import logging + +from semantic_kernel.utils.logging import setup_logging + + +def test_setup_logging(): + """Test that the logging is setup correctly.""" + setup_logging() + + root_logger = logging.getLogger() + assert root_logger.handlers + assert any(isinstance(handler, logging.StreamHandler) for handler in root_logger.handlers) From 6887459752fe4cf158cd862e3e236a158b3c7705 Mon Sep 17 00:00:00 2001 From: Evan Mattson Date: Thu, 11 Jul 2024 14:24:17 -0400 Subject: [PATCH 2/3] Fix ruff errors --- .../getting_started/10-multiple-results-per-prompt.ipynb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/samples/getting_started/10-multiple-results-per-prompt.ipynb b/python/samples/getting_started/10-multiple-results-per-prompt.ipynb index fca51b462471..803d35023ce9 100644 --- a/python/samples/getting_started/10-multiple-results-per-prompt.ipynb +++ b/python/samples/getting_started/10-multiple-results-per-prompt.ipynb @@ -251,7 +251,7 @@ " results = await oai_text_service.get_text_contents(prompt=prompt, settings=oai_text_prompt_execution_settings)\n", "\n", " for i, result in enumerate(results):\n", - " print(f\"Result {i+1}: {result}\")" + " print(f\"Result {i + 1}: {result}\")" ] }, { @@ -276,7 +276,7 @@ " results = await aoai_text_service.get_text_contents(prompt=prompt, settings=oai_text_prompt_execution_settings)\n", "\n", " for i, result in enumerate(results):\n", - " print(f\"Result {i+1}: {result}\")" + " print(f\"Result {i + 1}: {result}\")" ] }, { From 9a27107b053f428bf3108a258096dde38b8d980e Mon Sep 17 00:00:00 2001 From: Evan Mattson Date: Thu, 11 Jul 2024 15:58:25 -0400 Subject: [PATCH 3/3] Add missing test env vars --- .../unit/core_plugins/test_sessions_python_plugin.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/python/tests/unit/core_plugins/test_sessions_python_plugin.py b/python/tests/unit/core_plugins/test_sessions_python_plugin.py index e37ddcc65426..ee7beeec4799 100644 --- a/python/tests/unit/core_plugins/test_sessions_python_plugin.py +++ b/python/tests/unit/core_plugins/test_sessions_python_plugin.py @@ -71,7 +71,7 @@ def test_validate_endpoint(aca_python_sessions_unit_test_env): ), ], ) -def test_build_url_with_version(base_url, endpoint, params, expected_url): +def test_build_url_with_version(base_url, endpoint, params, expected_url, aca_python_sessions_unit_test_env): plugin = SessionsPythonTool(auth_callback=auth_callback_test) result = plugin._build_url_with_version(base_url, endpoint, params) assert result == expected_url @@ -283,7 +283,7 @@ async def async_return(result): @pytest.mark.asyncio @patch("httpx.AsyncClient.post") -async def test_upload_file_throws_exception(mock_post): +async def test_upload_file_throws_exception(mock_post, aca_python_sessions_unit_test_env): """Test throwing exception during file upload.""" async def async_raise_http_error(*args, **kwargs): @@ -434,7 +434,7 @@ async def async_return(result): @pytest.mark.asyncio @patch("httpx.AsyncClient.get") -async def test_list_files_throws_exception(mock_get): +async def test_list_files_throws_exception(mock_get, aca_python_sessions_unit_test_env): """Test throwing exception during list files.""" async def async_raise_http_error(*args, **kwargs): @@ -532,7 +532,7 @@ async def mock_auth_callback(): @pytest.mark.asyncio @patch("httpx.AsyncClient.get") -async def test_download_file_throws_exception(mock_get): +async def test_download_file_throws_exception(mock_get, aca_python_sessions_unit_test_env): """Test throwing exception during download file.""" async def async_raise_http_error(*args, **kwargs):