From 0bcf4c2a4656c8937269b258f58da7cf32d2ba35 Mon Sep 17 00:00:00 2001 From: Hu Yueh-Wei Date: Sun, 10 Nov 2024 23:14:04 +0800 Subject: [PATCH 1/2] feat: add each_ok_and_error return policy --- .../python/multiple_results_python_1/BUILD.gn | 50 +++++++ .../multiple_results_python_1/__init__.py | 0 .../manifest.json | 19 +++ .../property.json | 66 +++++++++ .../default_extension_python/extension.py | 60 ++++++++ .../multiple_results_python_1/test_case.py | 134 ++++++++++++++++++ .../python/multiple_results_python_2/BUILD.gn | 50 +++++++ .../multiple_results_python_2/__init__.py | 0 .../manifest.json | 19 +++ .../property.json | 76 ++++++++++ .../default_extension_python/extension.py | 57 ++++++++ .../multiple_results_python_2/test_case.py | 134 ++++++++++++++++++ .../python/multiple_results_python_3/BUILD.gn | 50 +++++++ .../multiple_results_python_3/__init__.py | 0 .../manifest.json | 19 +++ .../property.json | 77 ++++++++++ .../default_extension_python/extension.py | 60 ++++++++ .../multiple_results_python_3/test_case.py | 134 ++++++++++++++++++ 18 files changed, 1005 insertions(+) create mode 100644 tests/ten_runtime/integration/python/multiple_results_python_1/BUILD.gn create mode 100644 tests/ten_runtime/integration/python/multiple_results_python_1/__init__.py create mode 100644 tests/ten_runtime/integration/python/multiple_results_python_1/multiple_results_python_1_app/manifest.json create mode 100644 tests/ten_runtime/integration/python/multiple_results_python_1/multiple_results_python_1_app/property.json create mode 100644 tests/ten_runtime/integration/python/multiple_results_python_1/multiple_results_python_1_app/ten_packages/extension/default_extension_python/extension.py create mode 100644 tests/ten_runtime/integration/python/multiple_results_python_1/test_case.py create mode 100644 tests/ten_runtime/integration/python/multiple_results_python_2/BUILD.gn create mode 100644 tests/ten_runtime/integration/python/multiple_results_python_2/__init__.py create mode 100644 tests/ten_runtime/integration/python/multiple_results_python_2/multiple_results_python_2_app/manifest.json create mode 100644 tests/ten_runtime/integration/python/multiple_results_python_2/multiple_results_python_2_app/property.json create mode 100644 tests/ten_runtime/integration/python/multiple_results_python_2/multiple_results_python_2_app/ten_packages/extension/default_extension_python/extension.py create mode 100644 tests/ten_runtime/integration/python/multiple_results_python_2/test_case.py create mode 100644 tests/ten_runtime/integration/python/multiple_results_python_3/BUILD.gn create mode 100644 tests/ten_runtime/integration/python/multiple_results_python_3/__init__.py create mode 100644 tests/ten_runtime/integration/python/multiple_results_python_3/multiple_results_python_3_app/manifest.json create mode 100644 tests/ten_runtime/integration/python/multiple_results_python_3/multiple_results_python_3_app/property.json create mode 100644 tests/ten_runtime/integration/python/multiple_results_python_3/multiple_results_python_3_app/ten_packages/extension/default_extension_python/extension.py create mode 100644 tests/ten_runtime/integration/python/multiple_results_python_3/test_case.py diff --git a/tests/ten_runtime/integration/python/multiple_results_python_1/BUILD.gn b/tests/ten_runtime/integration/python/multiple_results_python_1/BUILD.gn new file mode 100644 index 0000000000..4837a4d0ef --- /dev/null +++ b/tests/ten_runtime/integration/python/multiple_results_python_1/BUILD.gn @@ -0,0 +1,50 @@ +# +# Copyright © 2024 Agora +# This file is part of TEN Framework, an open source project. +# Licensed under the Apache License, Version 2.0, with certain conditions. +# Refer to the "LICENSE" file in the root directory for more information. +# +import("//build/ten_runtime/feature/test.gni") +import("//build/ten_runtime/ten.gni") + +ten_package_test_prepare_app("multiple_results_python_1_app") { + src_app = "default_app_python" + src_app_language = "python" + generated_app_src_root_dir_name = "multiple_results_python_1_app" + + replace_files_after_install_app = [ + "multiple_results_python_1_app/manifest.json", + "multiple_results_python_1_app/property.json", + ] + + replace_files_after_install_all = [ "multiple_results_python_1_app/ten_packages/extension/default_extension_python/extension.py" ] + + if (ten_enable_package_manager) { + deps = [ + "//core/src/ten_manager", + "//packages/core_apps/default_app_python:upload_default_app_python_to_server", + "//packages/core_extensions/default_extension_python:upload_default_extension_python_to_server", + "//packages/example_extensions/simple_echo_cpp:upload_simple_echo_cpp_to_server", + "//packages/example_extensions/simple_http_server_cpp:upload_simple_http_server_cpp_to_server", + ] + } +} + +ten_package_test_prepare_auxiliary_resources( + "multiple_results_python_1_test_files") { + resources = [ + "//tests/ten_runtime/integration/common=>common", + "__init__.py", + "test_case.py", + ] + if (enable_sanitizer) { + resources += [ "//tests/ten_runtime/integration/tools/use_asan_lib_marker=>use_asan_lib_marker" ] + } +} + +group("multiple_results_python_1") { + deps = [ + ":multiple_results_python_1_app", + ":multiple_results_python_1_test_files", + ] +} diff --git a/tests/ten_runtime/integration/python/multiple_results_python_1/__init__.py b/tests/ten_runtime/integration/python/multiple_results_python_1/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/ten_runtime/integration/python/multiple_results_python_1/multiple_results_python_1_app/manifest.json b/tests/ten_runtime/integration/python/multiple_results_python_1/multiple_results_python_1_app/manifest.json new file mode 100644 index 0000000000..1cfe6ef552 --- /dev/null +++ b/tests/ten_runtime/integration/python/multiple_results_python_1/multiple_results_python_1_app/manifest.json @@ -0,0 +1,19 @@ +{ + "dependencies": [ + { + "type": "system", + "name": "ten_runtime", + "version": "0.3.0" + }, + { + "type": "extension", + "name": "simple_http_server_cpp", + "version": "0.1.0" + }, + { + "type": "extension", + "name": "default_extension_python", + "version": "0.3.0" + } + ] +} \ No newline at end of file diff --git a/tests/ten_runtime/integration/python/multiple_results_python_1/multiple_results_python_1_app/property.json b/tests/ten_runtime/integration/python/multiple_results_python_1/multiple_results_python_1_app/property.json new file mode 100644 index 0000000000..a0dc31ad96 --- /dev/null +++ b/tests/ten_runtime/integration/python/multiple_results_python_1/multiple_results_python_1_app/property.json @@ -0,0 +1,66 @@ +{ + "_ten": { + "log_level": 2, + "predefined_graphs": [ + { + "name": "default", + "auto_start": true, + "nodes": [ + { + "type": "extension", + "name": "simple_http_server_cpp", + "addon": "simple_http_server_cpp", + "extension_group": "default_extension_group", + "property": { + "server_port": 8002 + } + }, + { + "type": "extension", + "name": "default_extension_python_1", + "addon": "default_extension_python", + "extension_group": "test1" + }, + { + "type": "extension", + "name": "default_extension_python_2", + "addon": "default_extension_python", + "extension_group": "test2" + } + ], + "connections": [ + { + "extension_group": "default_extension_group", + "extension": "simple_http_server_cpp", + "cmd": [ + { + "name": "test", + "dest": [ + { + "extension_group": "test1", + "extension": "default_extension_python_1" + } + ] + } + ] + }, + { + "extension_group": "test1", + "extension": "default_extension_python_1", + "cmd": [ + { + "name": "hello", + "dest": [ + { + "extension_group": "test2", + "extension": "default_extension_python_2" + } + ] + } + ] + } + ] + } + ] + } +} \ No newline at end of file diff --git a/tests/ten_runtime/integration/python/multiple_results_python_1/multiple_results_python_1_app/ten_packages/extension/default_extension_python/extension.py b/tests/ten_runtime/integration/python/multiple_results_python_1/multiple_results_python_1_app/ten_packages/extension/default_extension_python/extension.py new file mode 100644 index 0000000000..f7bc88fd2b --- /dev/null +++ b/tests/ten_runtime/integration/python/multiple_results_python_1/multiple_results_python_1_app/ten_packages/extension/default_extension_python/extension.py @@ -0,0 +1,60 @@ +# +# Copyright © 2024 Agora +# This file is part of TEN Framework, an open source project. +# Licensed under the Apache License, Version 2.0, with certain conditions. +# Refer to the "LICENSE" file in the root directory for more information. +# +from ten import ( + Extension, + TenEnv, + Cmd, + StatusCode, + CmdResult, +) + + +class DefaultExtension(Extension): + def __init__(self, name: str) -> None: + super().__init__(name) + self.name = name + + self.__counter = 0 + + def on_init(self, ten_env: TenEnv) -> None: + ten_env.log_debug("on_init") + ten_env.on_init_done() + + def check_hello(self, ten_env: TenEnv, result: CmdResult, receivedCmd: Cmd): + self.__counter += 1 + + if self.__counter == 1: + assert result.is_final() is False + ten_env.log_info("receive 1 cmd result") + elif self.__counter == 2: + assert result.is_final() is True + ten_env.log_info("receive 2 cmd result") + + respCmd = CmdResult.create(StatusCode.OK) + respCmd.set_property_string("detail", "nbnb") + ten_env.return_result(respCmd, receivedCmd) + + def on_cmd(self, ten_env: TenEnv, cmd: Cmd) -> None: + cmd_json = cmd.to_json() + ten_env.log_debug(f"on_cmd json: {cmd_json}") + + if self.name == "default_extension_python_1": + new_cmd = Cmd.create("hello") + ten_env.send_cmd( + new_cmd, + lambda ten_env, result: self.check_hello(ten_env, result, cmd), + ) + elif self.name == "default_extension_python_2": + ten_env.log_info("create respCmd 1") + respCmd = CmdResult.create(StatusCode.OK) + # The following line is the key. + respCmd.set_final(False) + ten_env.return_result(respCmd, cmd) + + ten_env.log_info("create respCmd 2") + respCmd = CmdResult.create(StatusCode.OK) + ten_env.return_result(respCmd, cmd) diff --git a/tests/ten_runtime/integration/python/multiple_results_python_1/test_case.py b/tests/ten_runtime/integration/python/multiple_results_python_1/test_case.py new file mode 100644 index 0000000000..f545decdff --- /dev/null +++ b/tests/ten_runtime/integration/python/multiple_results_python_1/test_case.py @@ -0,0 +1,134 @@ +""" +Test multiple_results_python_1. +""" + +import subprocess +import os +import sys +from sys import stdout +from .common import http + + +def http_request(): + return http.post( + "http://127.0.0.1:8002/", + { + "_ten": { + "name": "test", + }, + }, + ) + + +def test_multiple_results_python_1(): + """Test client and app server.""" + base_path = os.path.dirname(os.path.abspath(__file__)) + root_dir = os.path.join(base_path, "../../../../../") + + # Create virtual environment. + venv_dir = os.path.join(base_path, "venv") + subprocess.run([sys.executable, "-m", "venv", venv_dir]) + + my_env = os.environ.copy() + + # Set the required environment variables for the test. + my_env["PYTHONMALLOC"] = "malloc" + my_env["PYTHONDEVMODE"] = "1" + + # Launch virtual environment. + my_env["VIRTUAL_ENV"] = venv_dir + my_env["PATH"] = os.path.join(venv_dir, "bin") + os.pathsep + my_env["PATH"] + + if sys.platform == "win32": + print("test_multiple_results_python_1 doesn't support win32") + assert False + elif sys.platform == "darwin": + # client depends on some libraries in the TEN app. + my_env["DYLD_LIBRARY_PATH"] = os.path.join( + base_path, "multiple_results_python_1_app/lib" + ) + else: + # client depends on some libraries in the TEN app. + my_env["LD_LIBRARY_PATH"] = os.path.join( + base_path, "multiple_results_python_1_app/lib" + ) + + app_root_path = os.path.join(base_path, "multiple_results_python_1_app") + + tman_install_cmd = [ + os.path.join(root_dir, "ten_manager/bin/tman"), + "--config-file", + os.path.join(root_dir, "tests/local_registry/config.json"), + "install", + ] + + tman_install_process = subprocess.Popen( + tman_install_cmd, + stdout=stdout, + stderr=subprocess.STDOUT, + env=my_env, + cwd=app_root_path, + ) + tman_install_process.wait() + + bootstrap_cmd = os.path.join( + base_path, "multiple_results_python_1_app/bin/bootstrap" + ) + + bootstrap_process = subprocess.Popen( + bootstrap_cmd, stdout=stdout, stderr=subprocess.STDOUT, env=my_env + ) + bootstrap_process.wait() + + if sys.platform == "linux": + if os.path.exists(os.path.join(base_path, "use_asan_lib_marker")): + libasan_path = os.path.join( + base_path, + "multiple_results_python_1_app/ten_packages/system/ten_runtime/lib/libasan.so", + ) + + if os.path.exists(libasan_path): + my_env["LD_PRELOAD"] = libasan_path + + server_cmd = os.path.join( + base_path, "multiple_results_python_1_app/bin/start" + ) + + server = subprocess.Popen( + server_cmd, + stdout=stdout, + stderr=subprocess.STDOUT, + env=my_env, + cwd=app_root_path, + ) + + is_started = http.is_app_started("127.0.0.1", 8002, 30) + if not is_started: + print("The multiple_results_python_1 is not started after 30 seconds.") + + server.kill() + exit_code = server.wait() + print("The exit code of multiple_results_python_1: ", exit_code) + + assert exit_code == 0 + assert 0 + + return + + try: + resp = http_request() + assert resp != 500 + print(resp) + + finally: + is_stopped = http.stop_app("127.0.0.1", 8002, 30) + if not is_stopped: + print( + "The multiple_results_python_1 can not stop after 30 seconds." + ) + server.kill() + + exit_code = server.wait() + print("The exit code of multiple_results_python_1: ", exit_code) + + assert exit_code == 0 diff --git a/tests/ten_runtime/integration/python/multiple_results_python_2/BUILD.gn b/tests/ten_runtime/integration/python/multiple_results_python_2/BUILD.gn new file mode 100644 index 0000000000..3dce110940 --- /dev/null +++ b/tests/ten_runtime/integration/python/multiple_results_python_2/BUILD.gn @@ -0,0 +1,50 @@ +# +# Copyright © 2024 Agora +# This file is part of TEN Framework, an open source project. +# Licensed under the Apache License, Version 2.0, with certain conditions. +# Refer to the "LICENSE" file in the root directory for more information. +# +import("//build/ten_runtime/feature/test.gni") +import("//build/ten_runtime/ten.gni") + +ten_package_test_prepare_app("multiple_results_python_2_app") { + src_app = "default_app_python" + src_app_language = "python" + generated_app_src_root_dir_name = "multiple_results_python_2_app" + + replace_files_after_install_app = [ + "multiple_results_python_2_app/manifest.json", + "multiple_results_python_2_app/property.json", + ] + + replace_files_after_install_all = [ "multiple_results_python_2_app/ten_packages/extension/default_extension_python/extension.py" ] + + if (ten_enable_package_manager) { + deps = [ + "//core/src/ten_manager", + "//packages/core_apps/default_app_python:upload_default_app_python_to_server", + "//packages/core_extensions/default_extension_python:upload_default_extension_python_to_server", + "//packages/example_extensions/simple_echo_cpp:upload_simple_echo_cpp_to_server", + "//packages/example_extensions/simple_http_server_cpp:upload_simple_http_server_cpp_to_server", + ] + } +} + +ten_package_test_prepare_auxiliary_resources( + "multiple_results_python_2_test_files") { + resources = [ + "//tests/ten_runtime/integration/common=>common", + "__init__.py", + "test_case.py", + ] + if (enable_sanitizer) { + resources += [ "//tests/ten_runtime/integration/tools/use_asan_lib_marker=>use_asan_lib_marker" ] + } +} + +group("multiple_results_python_2") { + deps = [ + ":multiple_results_python_2_app", + ":multiple_results_python_2_test_files", + ] +} diff --git a/tests/ten_runtime/integration/python/multiple_results_python_2/__init__.py b/tests/ten_runtime/integration/python/multiple_results_python_2/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/ten_runtime/integration/python/multiple_results_python_2/multiple_results_python_2_app/manifest.json b/tests/ten_runtime/integration/python/multiple_results_python_2/multiple_results_python_2_app/manifest.json new file mode 100644 index 0000000000..1cfe6ef552 --- /dev/null +++ b/tests/ten_runtime/integration/python/multiple_results_python_2/multiple_results_python_2_app/manifest.json @@ -0,0 +1,19 @@ +{ + "dependencies": [ + { + "type": "system", + "name": "ten_runtime", + "version": "0.3.0" + }, + { + "type": "extension", + "name": "simple_http_server_cpp", + "version": "0.1.0" + }, + { + "type": "extension", + "name": "default_extension_python", + "version": "0.3.0" + } + ] +} \ No newline at end of file diff --git a/tests/ten_runtime/integration/python/multiple_results_python_2/multiple_results_python_2_app/property.json b/tests/ten_runtime/integration/python/multiple_results_python_2/multiple_results_python_2_app/property.json new file mode 100644 index 0000000000..a0dd94adf7 --- /dev/null +++ b/tests/ten_runtime/integration/python/multiple_results_python_2/multiple_results_python_2_app/property.json @@ -0,0 +1,76 @@ +{ + "_ten": { + "log_level": 2, + "predefined_graphs": [ + { + "name": "default", + "auto_start": true, + "nodes": [ + { + "type": "extension", + "name": "simple_http_server_cpp", + "addon": "simple_http_server_cpp", + "extension_group": "default_extension_group", + "property": { + "server_port": 8002 + } + }, + { + "type": "extension", + "name": "default_extension_python_1", + "addon": "default_extension_python", + "extension_group": "test1" + }, + { + "type": "extension", + "name": "default_extension_python_2", + "addon": "default_extension_python", + "extension_group": "test2" + }, + { + "type": "extension", + "name": "default_extension_python_3", + "addon": "default_extension_python", + "extension_group": "test2" + } + ], + "connections": [ + { + "extension_group": "default_extension_group", + "extension": "simple_http_server_cpp", + "cmd": [ + { + "name": "test", + "dest": [ + { + "extension_group": "test1", + "extension": "default_extension_python_1" + } + ] + } + ] + }, + { + "extension_group": "test1", + "extension": "default_extension_python_1", + "cmd": [ + { + "name": "hello", + "dest": [ + { + "extension_group": "test2", + "extension": "default_extension_python_2" + }, + { + "extension_group": "test2", + "extension": "default_extension_python_3" + } + ] + } + ] + } + ] + } + ] + } +} \ No newline at end of file diff --git a/tests/ten_runtime/integration/python/multiple_results_python_2/multiple_results_python_2_app/ten_packages/extension/default_extension_python/extension.py b/tests/ten_runtime/integration/python/multiple_results_python_2/multiple_results_python_2_app/ten_packages/extension/default_extension_python/extension.py new file mode 100644 index 0000000000..65506b3828 --- /dev/null +++ b/tests/ten_runtime/integration/python/multiple_results_python_2/multiple_results_python_2_app/ten_packages/extension/default_extension_python/extension.py @@ -0,0 +1,57 @@ +# +# Copyright © 2024 Agora +# This file is part of TEN Framework, an open source project. +# Licensed under the Apache License, Version 2.0, with certain conditions. +# Refer to the "LICENSE" file in the root directory for more information. +# +from ten import ( + Extension, + TenEnv, + Cmd, + StatusCode, + CmdResult, +) + + +class DefaultExtension(Extension): + def __init__(self, name: str) -> None: + super().__init__(name) + self.name = name + + self.__counter = 0 + + def on_init(self, ten_env: TenEnv) -> None: + ten_env.log_debug("on_init") + ten_env.on_init_done() + + def check_hello(self, ten_env: TenEnv, result: CmdResult, receivedCmd: Cmd): + self.__counter += 1 + + if self.__counter == 1: + assert result.is_completed() is True + ten_env.log_info("receive 1 cmd result") + + respCmd = CmdResult.create(StatusCode.OK) + respCmd.set_property_string("detail", "nbnb") + ten_env.return_result(respCmd, receivedCmd) + else: + assert 0 + + def on_cmd(self, ten_env: TenEnv, cmd: Cmd) -> None: + cmd_json = cmd.to_json() + ten_env.log_debug(f"on_cmd json: {cmd_json}") + + if self.name == "default_extension_python_1": + new_cmd = Cmd.create("hello") + ten_env.send_cmd( + new_cmd, + lambda ten_env, result: self.check_hello(ten_env, result, cmd), + ) + elif self.name == "default_extension_python_2": + ten_env.log_info("create respCmd") + respCmd = CmdResult.create(StatusCode.OK) + ten_env.return_result(respCmd, cmd) + elif self.name == "default_extension_python_3": + ten_env.log_info("create respCmd") + respCmd = CmdResult.create(StatusCode.OK) + ten_env.return_result(respCmd, cmd) diff --git a/tests/ten_runtime/integration/python/multiple_results_python_2/test_case.py b/tests/ten_runtime/integration/python/multiple_results_python_2/test_case.py new file mode 100644 index 0000000000..a9e8720938 --- /dev/null +++ b/tests/ten_runtime/integration/python/multiple_results_python_2/test_case.py @@ -0,0 +1,134 @@ +""" +Test multiple_results_python_2. +""" + +import subprocess +import os +import sys +from sys import stdout +from .common import http + + +def http_request(): + return http.post( + "http://127.0.0.1:8002/", + { + "_ten": { + "name": "test", + }, + }, + ) + + +def test_multiple_results_python_2(): + """Test client and app server.""" + base_path = os.path.dirname(os.path.abspath(__file__)) + root_dir = os.path.join(base_path, "../../../../../") + + # Create virtual environment. + venv_dir = os.path.join(base_path, "venv") + subprocess.run([sys.executable, "-m", "venv", venv_dir]) + + my_env = os.environ.copy() + + # Set the required environment variables for the test. + my_env["PYTHONMALLOC"] = "malloc" + my_env["PYTHONDEVMODE"] = "1" + + # Launch virtual environment. + my_env["VIRTUAL_ENV"] = venv_dir + my_env["PATH"] = os.path.join(venv_dir, "bin") + os.pathsep + my_env["PATH"] + + if sys.platform == "win32": + print("test_multiple_results_python_2 doesn't support win32") + assert False + elif sys.platform == "darwin": + # client depends on some libraries in the TEN app. + my_env["DYLD_LIBRARY_PATH"] = os.path.join( + base_path, "multiple_results_python_2_app/lib" + ) + else: + # client depends on some libraries in the TEN app. + my_env["LD_LIBRARY_PATH"] = os.path.join( + base_path, "multiple_results_python_2_app/lib" + ) + + app_root_path = os.path.join(base_path, "multiple_results_python_2_app") + + tman_install_cmd = [ + os.path.join(root_dir, "ten_manager/bin/tman"), + "--config-file", + os.path.join(root_dir, "tests/local_registry/config.json"), + "install", + ] + + tman_install_process = subprocess.Popen( + tman_install_cmd, + stdout=stdout, + stderr=subprocess.STDOUT, + env=my_env, + cwd=app_root_path, + ) + tman_install_process.wait() + + bootstrap_cmd = os.path.join( + base_path, "multiple_results_python_2_app/bin/bootstrap" + ) + + bootstrap_process = subprocess.Popen( + bootstrap_cmd, stdout=stdout, stderr=subprocess.STDOUT, env=my_env + ) + bootstrap_process.wait() + + if sys.platform == "linux": + if os.path.exists(os.path.join(base_path, "use_asan_lib_marker")): + libasan_path = os.path.join( + base_path, + "multiple_results_python_2_app/ten_packages/system/ten_runtime/lib/libasan.so", + ) + + if os.path.exists(libasan_path): + my_env["LD_PRELOAD"] = libasan_path + + server_cmd = os.path.join( + base_path, "multiple_results_python_2_app/bin/start" + ) + + server = subprocess.Popen( + server_cmd, + stdout=stdout, + stderr=subprocess.STDOUT, + env=my_env, + cwd=app_root_path, + ) + + is_started = http.is_app_started("127.0.0.1", 8002, 30) + if not is_started: + print("The multiple_results_python_2 is not started after 30 seconds.") + + server.kill() + exit_code = server.wait() + print("The exit code of multiple_results_python_2: ", exit_code) + + assert exit_code == 0 + assert 0 + + return + + try: + resp = http_request() + assert resp != 500 + print(resp) + + finally: + is_stopped = http.stop_app("127.0.0.1", 8002, 30) + if not is_stopped: + print( + "The multiple_results_python_2 can not stop after 30 seconds." + ) + server.kill() + + exit_code = server.wait() + print("The exit code of multiple_results_python_2: ", exit_code) + + assert exit_code == 0 diff --git a/tests/ten_runtime/integration/python/multiple_results_python_3/BUILD.gn b/tests/ten_runtime/integration/python/multiple_results_python_3/BUILD.gn new file mode 100644 index 0000000000..aab3f7d7a1 --- /dev/null +++ b/tests/ten_runtime/integration/python/multiple_results_python_3/BUILD.gn @@ -0,0 +1,50 @@ +# +# Copyright © 2024 Agora +# This file is part of TEN Framework, an open source project. +# Licensed under the Apache License, Version 2.0, with certain conditions. +# Refer to the "LICENSE" file in the root directory for more information. +# +import("//build/ten_runtime/feature/test.gni") +import("//build/ten_runtime/ten.gni") + +ten_package_test_prepare_app("multiple_results_python_3_app") { + src_app = "default_app_python" + src_app_language = "python" + generated_app_src_root_dir_name = "multiple_results_python_3_app" + + replace_files_after_install_app = [ + "multiple_results_python_3_app/manifest.json", + "multiple_results_python_3_app/property.json", + ] + + replace_files_after_install_all = [ "multiple_results_python_3_app/ten_packages/extension/default_extension_python/extension.py" ] + + if (ten_enable_package_manager) { + deps = [ + "//core/src/ten_manager", + "//packages/core_apps/default_app_python:upload_default_app_python_to_server", + "//packages/core_extensions/default_extension_python:upload_default_extension_python_to_server", + "//packages/example_extensions/simple_echo_cpp:upload_simple_echo_cpp_to_server", + "//packages/example_extensions/simple_http_server_cpp:upload_simple_http_server_cpp_to_server", + ] + } +} + +ten_package_test_prepare_auxiliary_resources( + "multiple_results_python_3_test_files") { + resources = [ + "//tests/ten_runtime/integration/common=>common", + "__init__.py", + "test_case.py", + ] + if (enable_sanitizer) { + resources += [ "//tests/ten_runtime/integration/tools/use_asan_lib_marker=>use_asan_lib_marker" ] + } +} + +group("multiple_results_python_3") { + deps = [ + ":multiple_results_python_3_app", + ":multiple_results_python_3_test_files", + ] +} diff --git a/tests/ten_runtime/integration/python/multiple_results_python_3/__init__.py b/tests/ten_runtime/integration/python/multiple_results_python_3/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/ten_runtime/integration/python/multiple_results_python_3/multiple_results_python_3_app/manifest.json b/tests/ten_runtime/integration/python/multiple_results_python_3/multiple_results_python_3_app/manifest.json new file mode 100644 index 0000000000..1cfe6ef552 --- /dev/null +++ b/tests/ten_runtime/integration/python/multiple_results_python_3/multiple_results_python_3_app/manifest.json @@ -0,0 +1,19 @@ +{ + "dependencies": [ + { + "type": "system", + "name": "ten_runtime", + "version": "0.3.0" + }, + { + "type": "extension", + "name": "simple_http_server_cpp", + "version": "0.1.0" + }, + { + "type": "extension", + "name": "default_extension_python", + "version": "0.3.0" + } + ] +} \ No newline at end of file diff --git a/tests/ten_runtime/integration/python/multiple_results_python_3/multiple_results_python_3_app/property.json b/tests/ten_runtime/integration/python/multiple_results_python_3/multiple_results_python_3_app/property.json new file mode 100644 index 0000000000..81e4fe29dc --- /dev/null +++ b/tests/ten_runtime/integration/python/multiple_results_python_3/multiple_results_python_3_app/property.json @@ -0,0 +1,77 @@ +{ + "_ten": { + "log_level": 2, + "predefined_graphs": [ + { + "name": "default", + "auto_start": true, + "nodes": [ + { + "type": "extension", + "name": "simple_http_server_cpp", + "addon": "simple_http_server_cpp", + "extension_group": "default_extension_group", + "property": { + "server_port": 8002 + } + }, + { + "type": "extension", + "name": "default_extension_python_1", + "addon": "default_extension_python", + "extension_group": "test1" + }, + { + "type": "extension", + "name": "default_extension_python_2", + "addon": "default_extension_python", + "extension_group": "test2" + }, + { + "type": "extension", + "name": "default_extension_python_3", + "addon": "default_extension_python", + "extension_group": "test2" + } + ], + "connections": [ + { + "extension_group": "default_extension_group", + "extension": "simple_http_server_cpp", + "cmd": [ + { + "name": "test", + "dest": [ + { + "extension_group": "test1", + "extension": "default_extension_python_1" + } + ] + } + ] + }, + { + "extension_group": "test1", + "extension": "default_extension_python_1", + "cmd": [ + { + "name": "hello", + "result_return_policy": "each_ok_and_error", + "dest": [ + { + "extension_group": "test2", + "extension": "default_extension_python_2" + }, + { + "extension_group": "test2", + "extension": "default_extension_python_3" + } + ] + } + ] + } + ] + } + ] + } +} \ No newline at end of file diff --git a/tests/ten_runtime/integration/python/multiple_results_python_3/multiple_results_python_3_app/ten_packages/extension/default_extension_python/extension.py b/tests/ten_runtime/integration/python/multiple_results_python_3/multiple_results_python_3_app/ten_packages/extension/default_extension_python/extension.py new file mode 100644 index 0000000000..b66ab3ada8 --- /dev/null +++ b/tests/ten_runtime/integration/python/multiple_results_python_3/multiple_results_python_3_app/ten_packages/extension/default_extension_python/extension.py @@ -0,0 +1,60 @@ +# +# Copyright © 2024 Agora +# This file is part of TEN Framework, an open source project. +# Licensed under the Apache License, Version 2.0, with certain conditions. +# Refer to the "LICENSE" file in the root directory for more information. +# +from ten import ( + Extension, + TenEnv, + Cmd, + StatusCode, + CmdResult, +) + + +class DefaultExtension(Extension): + def __init__(self, name: str) -> None: + super().__init__(name) + self.name = name + + self.__counter = 0 + + def on_init(self, ten_env: TenEnv) -> None: + ten_env.log_debug("on_init") + ten_env.on_init_done() + + def check_hello(self, ten_env: TenEnv, result: CmdResult, receivedCmd: Cmd): + self.__counter += 1 + + if self.__counter == 1: + assert result.is_completed() is False + ten_env.log_info("receive 1 cmd result") + elif self.__counter == 2: + assert result.is_completed() is True + ten_env.log_info("receive 2 cmd result") + + respCmd = CmdResult.create(StatusCode.OK) + respCmd.set_property_string("detail", "nbnb") + ten_env.return_result(respCmd, receivedCmd) + else: + assert 0 + + def on_cmd(self, ten_env: TenEnv, cmd: Cmd) -> None: + cmd_json = cmd.to_json() + ten_env.log_debug(f"on_cmd json: {cmd_json}") + + if self.name == "default_extension_python_1": + new_cmd = Cmd.create("hello") + ten_env.send_cmd( + new_cmd, + lambda ten_env, result: self.check_hello(ten_env, result, cmd), + ) + elif self.name == "default_extension_python_2": + ten_env.log_info("create respCmd") + respCmd = CmdResult.create(StatusCode.OK) + ten_env.return_result(respCmd, cmd) + elif self.name == "default_extension_python_3": + ten_env.log_info("create respCmd") + respCmd = CmdResult.create(StatusCode.OK) + ten_env.return_result(respCmd, cmd) diff --git a/tests/ten_runtime/integration/python/multiple_results_python_3/test_case.py b/tests/ten_runtime/integration/python/multiple_results_python_3/test_case.py new file mode 100644 index 0000000000..179ff5fd7e --- /dev/null +++ b/tests/ten_runtime/integration/python/multiple_results_python_3/test_case.py @@ -0,0 +1,134 @@ +""" +Test multiple_results_python_3. +""" + +import subprocess +import os +import sys +from sys import stdout +from .common import http + + +def http_request(): + return http.post( + "http://127.0.0.1:8002/", + { + "_ten": { + "name": "test", + }, + }, + ) + + +def test_multiple_results_python_3(): + """Test client and app server.""" + base_path = os.path.dirname(os.path.abspath(__file__)) + root_dir = os.path.join(base_path, "../../../../../") + + # Create virtual environment. + venv_dir = os.path.join(base_path, "venv") + subprocess.run([sys.executable, "-m", "venv", venv_dir]) + + my_env = os.environ.copy() + + # Set the required environment variables for the test. + my_env["PYTHONMALLOC"] = "malloc" + my_env["PYTHONDEVMODE"] = "1" + + # Launch virtual environment. + my_env["VIRTUAL_ENV"] = venv_dir + my_env["PATH"] = os.path.join(venv_dir, "bin") + os.pathsep + my_env["PATH"] + + if sys.platform == "win32": + print("test_multiple_results_python_3 doesn't support win32") + assert False + elif sys.platform == "darwin": + # client depends on some libraries in the TEN app. + my_env["DYLD_LIBRARY_PATH"] = os.path.join( + base_path, "multiple_results_python_3_app/lib" + ) + else: + # client depends on some libraries in the TEN app. + my_env["LD_LIBRARY_PATH"] = os.path.join( + base_path, "multiple_results_python_3_app/lib" + ) + + app_root_path = os.path.join(base_path, "multiple_results_python_3_app") + + tman_install_cmd = [ + os.path.join(root_dir, "ten_manager/bin/tman"), + "--config-file", + os.path.join(root_dir, "tests/local_registry/config.json"), + "install", + ] + + tman_install_process = subprocess.Popen( + tman_install_cmd, + stdout=stdout, + stderr=subprocess.STDOUT, + env=my_env, + cwd=app_root_path, + ) + tman_install_process.wait() + + bootstrap_cmd = os.path.join( + base_path, "multiple_results_python_3_app/bin/bootstrap" + ) + + bootstrap_process = subprocess.Popen( + bootstrap_cmd, stdout=stdout, stderr=subprocess.STDOUT, env=my_env + ) + bootstrap_process.wait() + + if sys.platform == "linux": + if os.path.exists(os.path.join(base_path, "use_asan_lib_marker")): + libasan_path = os.path.join( + base_path, + "multiple_results_python_3_app/ten_packages/system/ten_runtime/lib/libasan.so", + ) + + if os.path.exists(libasan_path): + my_env["LD_PRELOAD"] = libasan_path + + server_cmd = os.path.join( + base_path, "multiple_results_python_3_app/bin/start" + ) + + server = subprocess.Popen( + server_cmd, + stdout=stdout, + stderr=subprocess.STDOUT, + env=my_env, + cwd=app_root_path, + ) + + is_started = http.is_app_started("127.0.0.1", 8002, 30) + if not is_started: + print("The multiple_results_python_3 is not started after 30 seconds.") + + server.kill() + exit_code = server.wait() + print("The exit code of multiple_results_python_3: ", exit_code) + + assert exit_code == 0 + assert 0 + + return + + try: + resp = http_request() + assert resp != 500 + print(resp) + + finally: + is_stopped = http.stop_app("127.0.0.1", 8002, 30) + if not is_stopped: + print( + "The multiple_results_python_3 can not stop after 30 seconds." + ) + server.kill() + + exit_code = server.wait() + print("The exit code of multiple_results_python_3: ", exit_code) + + assert exit_code == 0 From 51f7b9b3f7aaccd48057fc0d19a41a1fea0060c1 Mon Sep 17 00:00:00 2001 From: Hu Yueh-Wei Date: Sun, 10 Nov 2024 23:14:08 +0800 Subject: [PATCH 2/2] feat: add each_ok_and_error return policy --- .../ten_runtime/common/constant_str.h | 2 +- .../ten_runtime/path/result_return_policy.h | 4 +- .../python/native/ten_env/ten_env_send_cmd.c | 4 +- core/src/ten_runtime/path/path_group.c | 2 +- core/src/ten_runtime/path/path_table.c | 2 +- .../ten_runtime/path/result_return_policy.c | 8 +- .../src/json_schema/data/property.schema.json | 14 ++ tests/ten_runtime/integration/pytest.ini | 4 +- tests/ten_runtime/integration/python/BUILD.gn | 4 +- .../python/multiple_results_python/BUILD.gn | 50 ------- .../multiple_results_python/__init__.py | 0 .../multiple_results_python_app/manifest.json | 19 --- .../multiple_results_python_app/property.json | 66 --------- .../default_extension_python/extension.py | 60 -------- .../multiple_results_python/test_case.py | 132 ------------------ .../cmd_result_test/multiple_result_3.cc | 2 +- 16 files changed, 32 insertions(+), 341 deletions(-) delete mode 100644 tests/ten_runtime/integration/python/multiple_results_python/BUILD.gn delete mode 100644 tests/ten_runtime/integration/python/multiple_results_python/__init__.py delete mode 100644 tests/ten_runtime/integration/python/multiple_results_python/multiple_results_python_app/manifest.json delete mode 100644 tests/ten_runtime/integration/python/multiple_results_python/multiple_results_python_app/property.json delete mode 100644 tests/ten_runtime/integration/python/multiple_results_python/multiple_results_python_app/ten_packages/extension/default_extension_python/extension.py delete mode 100644 tests/ten_runtime/integration/python/multiple_results_python/test_case.py diff --git a/core/include_internal/ten_runtime/common/constant_str.h b/core/include_internal/ten_runtime/common/constant_str.h index 6d61ffe05f..f82cf237e9 100644 --- a/core/include_internal/ten_runtime/common/constant_str.h +++ b/core/include_internal/ten_runtime/common/constant_str.h @@ -166,4 +166,4 @@ #define TEN_STR_RESULT_RETURN_POLICY "result_return_policy" #define TEN_STR_FIRST_ERROR_OR_FIRST_OK "first_error_or_first_ok" #define TEN_STR_FIRST_ERROR_OR_LAST_OK "first_error_or_last_ok" -#define TEN_STR_EACH_IMMEDIATELY "each_immediately" +#define TEN_STR_EACH_OK_AND_ERROR "each_ok_and_error" diff --git a/core/include_internal/ten_runtime/path/result_return_policy.h b/core/include_internal/ten_runtime/path/result_return_policy.h index 728aeebd03..b93f60f071 100644 --- a/core/include_internal/ten_runtime/path/result_return_policy.h +++ b/core/include_internal/ten_runtime/path/result_return_policy.h @@ -22,8 +22,8 @@ typedef enum TEN_RESULT_RETURN_POLICY { // Similar to the above, except return the last received one. TEN_RESULT_RETURN_POLICY_FIRST_ERROR_OR_LAST_OK, - // Return each result immediately as it is received. - TEN_RESULT_RETURN_POLICY_EACH_IMMEDIATELY, + // Return each result as it is received, regardless of its status. + TEN_RESULT_RETURN_POLICY_EACH_OK_AND_ERROR, // More modes is allowed, and could be added here in case needed. } TEN_RESULT_RETURN_POLICY; diff --git a/core/src/ten_runtime/binding/python/native/ten_env/ten_env_send_cmd.c b/core/src/ten_runtime/binding/python/native/ten_env/ten_env_send_cmd.c index 063ff309f5..1be2a69331 100644 --- a/core/src/ten_runtime/binding/python/native/ten_env/ten_env_send_cmd.c +++ b/core/src/ten_runtime/binding/python/native/ten_env/ten_env_send_cmd.c @@ -74,8 +74,8 @@ static void proxy_send_xxx_callback(ten_extension_t *extension, Py_XDECREF(arglist); - bool is_final = ten_cmd_result_is_final(cmd_result, NULL); - if (is_final) { + bool is_completed = ten_cmd_result_is_completed(cmd_result, NULL); + if (is_completed) { Py_XDECREF(cb_func); } diff --git a/core/src/ten_runtime/path/path_group.c b/core/src/ten_runtime/path/path_group.c index 24486f2ab9..f35bb5e2fe 100644 --- a/core/src/ten_runtime/path/path_group.c +++ b/core/src/ten_runtime/path/path_group.c @@ -217,7 +217,7 @@ ten_path_t *ten_path_group_resolve(ten_path_t *path, TEN_PATH_TYPE type) { case TEN_RESULT_RETURN_POLICY_FIRST_ERROR_OR_LAST_OK: return ten_path_group_resolve_in_one_fail_and_all_ok_return(members, type, true); - case TEN_RESULT_RETURN_POLICY_EACH_IMMEDIATELY: + case TEN_RESULT_RETURN_POLICY_EACH_OK_AND_ERROR: // In this policy, we return the current path immediately. return path; default: diff --git a/core/src/ten_runtime/path/path_table.c b/core/src/ten_runtime/path/path_table.c index 30ffd65ae7..dd671cb83d 100644 --- a/core/src/ten_runtime/path/path_table.c +++ b/core/src/ten_runtime/path/path_table.c @@ -526,7 +526,7 @@ ten_shared_ptr_t *ten_path_table_determine_actual_cmd_result( ten_path_group_t *path_group = ten_path_get_group(path); switch (path_group->policy) { - case TEN_RESULT_RETURN_POLICY_EACH_IMMEDIATELY: { + case TEN_RESULT_RETURN_POLICY_EACH_OK_AND_ERROR: { bool last_one = ten_path_table_remove_path_from_group(self, path_type, path); diff --git a/core/src/ten_runtime/path/result_return_policy.c b/core/src/ten_runtime/path/result_return_policy.c index 1b5901f158..448d3802f8 100644 --- a/core/src/ten_runtime/path/result_return_policy.c +++ b/core/src/ten_runtime/path/result_return_policy.c @@ -19,8 +19,8 @@ TEN_RESULT_RETURN_POLICY ten_result_return_policy_from_string( } else if (ten_c_string_is_equal(policy_str, TEN_STR_FIRST_ERROR_OR_LAST_OK)) { return TEN_RESULT_RETURN_POLICY_FIRST_ERROR_OR_LAST_OK; - } else if (ten_c_string_is_equal(policy_str, TEN_STR_EACH_IMMEDIATELY)) { - return TEN_RESULT_RETURN_POLICY_EACH_IMMEDIATELY; + } else if (ten_c_string_is_equal(policy_str, TEN_STR_EACH_OK_AND_ERROR)) { + return TEN_RESULT_RETURN_POLICY_EACH_OK_AND_ERROR; } else { return TEN_RESULT_RETURN_POLICY_INVALID; } @@ -33,8 +33,8 @@ const char *ten_result_return_policy_to_string( return TEN_STR_FIRST_ERROR_OR_FIRST_OK; case TEN_RESULT_RETURN_POLICY_FIRST_ERROR_OR_LAST_OK: return TEN_STR_FIRST_ERROR_OR_LAST_OK; - case TEN_RESULT_RETURN_POLICY_EACH_IMMEDIATELY: - return TEN_STR_EACH_IMMEDIATELY; + case TEN_RESULT_RETURN_POLICY_EACH_OK_AND_ERROR: + return TEN_STR_EACH_OK_AND_ERROR; default: return NULL; } diff --git a/core/src/ten_rust/src/json_schema/data/property.schema.json b/core/src/ten_rust/src/json_schema/data/property.schema.json index 4bd035b492..206a432f46 100644 --- a/core/src/ten_rust/src/json_schema/data/property.schema.json +++ b/core/src/ten_rust/src/json_schema/data/property.schema.json @@ -29,6 +29,14 @@ "minLength": 1, "pattern": "^[A-Za-z_][A-Za-z0-9_]*$" }, + "result_return_policy": { + "type": "string", + "enum": [ + "each_ok_and_error", + "first_error_or_first_ok", + "first_error_or_last_ok" + ] + }, "valueType": { "type": "string", "enum": [ @@ -310,6 +318,9 @@ "name": { // The api name should be alphanumericCharacters. "$ref": "#/$defs/alphanumericCharacters" }, + "result_return_policy": { + "$ref": "#/$defs/result_return_policy" + }, "dest": { "$ref": "#/$defs/dataDests" } @@ -329,6 +340,9 @@ "name": { // The api name should be alphanumericCharacters. "$ref": "#/$defs/alphanumericCharacters" }, + "result_return_policy": { + "$ref": "#/$defs/result_return_policy" + }, "dest": { "$ref": "#/$defs/cmdDests" } diff --git a/tests/ten_runtime/integration/pytest.ini b/tests/ten_runtime/integration/pytest.ini index 9135415f10..745d473094 100644 --- a/tests/ten_runtime/integration/pytest.ini +++ b/tests/ten_runtime/integration/pytest.ini @@ -17,7 +17,9 @@ addopts = --ignore=tests/ten_runtime/integration/python/go_app_async_extension_python/go_app_async_extension_python_app/ten_packages/extension/default_extension_python/tests/ --ignore=tests/ten_runtime/integration/python/large_json_python/large_json_python_app/ten_packages/extension/default_extension_python/tests/ --ignore=tests/ten_runtime/integration/python/multi_process_python/multi_process_python_app/ten_packages/extension/default_extension_python/tests/ - --ignore=tests/ten_runtime/integration/python/multiple_results_python/multiple_results_python_app/ten_packages/extension/default_extension_python/tests/ + --ignore=tests/ten_runtime/integration/python/multiple_results_python_1/multiple_results_python_1_app/ten_packages/extension/default_extension_python/tests/ + --ignore=tests/ten_runtime/integration/python/multiple_results_python_2/multiple_results_python_2_app/ten_packages/extension/default_extension_python/tests/ + --ignore=tests/ten_runtime/integration/python/multiple_results_python_3/multiple_results_python_3_app/ten_packages/extension/default_extension_python/tests/ --ignore=tests/ten_runtime/integration/python/resp_handler_yield_python/resp_handler_yield_python_app/ten_packages/extension/default_extension_python/tests/ --ignore=tests/ten_runtime/integration/python/send_cmd_discard_result_python/send_cmd_discard_result_python_app/ten_packages/extension/default_extension_python/tests/ --ignore=tests/ten_runtime/integration/python/send_cmd_python/send_cmd_python_app/ten_packages/extension/default_extension_python/tests/ diff --git a/tests/ten_runtime/integration/python/BUILD.gn b/tests/ten_runtime/integration/python/BUILD.gn index 5ec10dd537..e9c7494ce4 100644 --- a/tests/ten_runtime/integration/python/BUILD.gn +++ b/tests/ten_runtime/integration/python/BUILD.gn @@ -26,7 +26,9 @@ group("python") { "go_app_async_extension_python", "large_json_python", "multi_process_python", - "multiple_results_python", + "multiple_results_python_1", + "multiple_results_python_2", + "multiple_results_python_3", "resp_handler_yield_python", "send_cmd_discard_result_python", "send_cmd_python", diff --git a/tests/ten_runtime/integration/python/multiple_results_python/BUILD.gn b/tests/ten_runtime/integration/python/multiple_results_python/BUILD.gn deleted file mode 100644 index d7c59ff4c0..0000000000 --- a/tests/ten_runtime/integration/python/multiple_results_python/BUILD.gn +++ /dev/null @@ -1,50 +0,0 @@ -# -# Copyright © 2024 Agora -# This file is part of TEN Framework, an open source project. -# Licensed under the Apache License, Version 2.0, with certain conditions. -# Refer to the "LICENSE" file in the root directory for more information. -# -import("//build/ten_runtime/feature/test.gni") -import("//build/ten_runtime/ten.gni") - -ten_package_test_prepare_app("multiple_results_python_app") { - src_app = "default_app_python" - src_app_language = "python" - generated_app_src_root_dir_name = "multiple_results_python_app" - - replace_files_after_install_app = [ - "multiple_results_python_app/manifest.json", - "multiple_results_python_app/property.json", - ] - - replace_files_after_install_all = [ "multiple_results_python_app/ten_packages/extension/default_extension_python/extension.py" ] - - if (ten_enable_package_manager) { - deps = [ - "//core/src/ten_manager", - "//packages/core_apps/default_app_python:upload_default_app_python_to_server", - "//packages/core_extensions/default_extension_python:upload_default_extension_python_to_server", - "//packages/example_extensions/simple_echo_cpp:upload_simple_echo_cpp_to_server", - "//packages/example_extensions/simple_http_server_cpp:upload_simple_http_server_cpp_to_server", - ] - } -} - -ten_package_test_prepare_auxiliary_resources( - "multiple_results_python_test_files") { - resources = [ - "//tests/ten_runtime/integration/common=>common", - "__init__.py", - "test_case.py", - ] - if (enable_sanitizer) { - resources += [ "//tests/ten_runtime/integration/tools/use_asan_lib_marker=>use_asan_lib_marker" ] - } -} - -group("multiple_results_python") { - deps = [ - ":multiple_results_python_app", - ":multiple_results_python_test_files", - ] -} diff --git a/tests/ten_runtime/integration/python/multiple_results_python/__init__.py b/tests/ten_runtime/integration/python/multiple_results_python/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/ten_runtime/integration/python/multiple_results_python/multiple_results_python_app/manifest.json b/tests/ten_runtime/integration/python/multiple_results_python/multiple_results_python_app/manifest.json deleted file mode 100644 index 1cfe6ef552..0000000000 --- a/tests/ten_runtime/integration/python/multiple_results_python/multiple_results_python_app/manifest.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "dependencies": [ - { - "type": "system", - "name": "ten_runtime", - "version": "0.3.0" - }, - { - "type": "extension", - "name": "simple_http_server_cpp", - "version": "0.1.0" - }, - { - "type": "extension", - "name": "default_extension_python", - "version": "0.3.0" - } - ] -} \ No newline at end of file diff --git a/tests/ten_runtime/integration/python/multiple_results_python/multiple_results_python_app/property.json b/tests/ten_runtime/integration/python/multiple_results_python/multiple_results_python_app/property.json deleted file mode 100644 index a0dc31ad96..0000000000 --- a/tests/ten_runtime/integration/python/multiple_results_python/multiple_results_python_app/property.json +++ /dev/null @@ -1,66 +0,0 @@ -{ - "_ten": { - "log_level": 2, - "predefined_graphs": [ - { - "name": "default", - "auto_start": true, - "nodes": [ - { - "type": "extension", - "name": "simple_http_server_cpp", - "addon": "simple_http_server_cpp", - "extension_group": "default_extension_group", - "property": { - "server_port": 8002 - } - }, - { - "type": "extension", - "name": "default_extension_python_1", - "addon": "default_extension_python", - "extension_group": "test1" - }, - { - "type": "extension", - "name": "default_extension_python_2", - "addon": "default_extension_python", - "extension_group": "test2" - } - ], - "connections": [ - { - "extension_group": "default_extension_group", - "extension": "simple_http_server_cpp", - "cmd": [ - { - "name": "test", - "dest": [ - { - "extension_group": "test1", - "extension": "default_extension_python_1" - } - ] - } - ] - }, - { - "extension_group": "test1", - "extension": "default_extension_python_1", - "cmd": [ - { - "name": "hello", - "dest": [ - { - "extension_group": "test2", - "extension": "default_extension_python_2" - } - ] - } - ] - } - ] - } - ] - } -} \ No newline at end of file diff --git a/tests/ten_runtime/integration/python/multiple_results_python/multiple_results_python_app/ten_packages/extension/default_extension_python/extension.py b/tests/ten_runtime/integration/python/multiple_results_python/multiple_results_python_app/ten_packages/extension/default_extension_python/extension.py deleted file mode 100644 index f7bc88fd2b..0000000000 --- a/tests/ten_runtime/integration/python/multiple_results_python/multiple_results_python_app/ten_packages/extension/default_extension_python/extension.py +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright © 2024 Agora -# This file is part of TEN Framework, an open source project. -# Licensed under the Apache License, Version 2.0, with certain conditions. -# Refer to the "LICENSE" file in the root directory for more information. -# -from ten import ( - Extension, - TenEnv, - Cmd, - StatusCode, - CmdResult, -) - - -class DefaultExtension(Extension): - def __init__(self, name: str) -> None: - super().__init__(name) - self.name = name - - self.__counter = 0 - - def on_init(self, ten_env: TenEnv) -> None: - ten_env.log_debug("on_init") - ten_env.on_init_done() - - def check_hello(self, ten_env: TenEnv, result: CmdResult, receivedCmd: Cmd): - self.__counter += 1 - - if self.__counter == 1: - assert result.is_final() is False - ten_env.log_info("receive 1 cmd result") - elif self.__counter == 2: - assert result.is_final() is True - ten_env.log_info("receive 2 cmd result") - - respCmd = CmdResult.create(StatusCode.OK) - respCmd.set_property_string("detail", "nbnb") - ten_env.return_result(respCmd, receivedCmd) - - def on_cmd(self, ten_env: TenEnv, cmd: Cmd) -> None: - cmd_json = cmd.to_json() - ten_env.log_debug(f"on_cmd json: {cmd_json}") - - if self.name == "default_extension_python_1": - new_cmd = Cmd.create("hello") - ten_env.send_cmd( - new_cmd, - lambda ten_env, result: self.check_hello(ten_env, result, cmd), - ) - elif self.name == "default_extension_python_2": - ten_env.log_info("create respCmd 1") - respCmd = CmdResult.create(StatusCode.OK) - # The following line is the key. - respCmd.set_final(False) - ten_env.return_result(respCmd, cmd) - - ten_env.log_info("create respCmd 2") - respCmd = CmdResult.create(StatusCode.OK) - ten_env.return_result(respCmd, cmd) diff --git a/tests/ten_runtime/integration/python/multiple_results_python/test_case.py b/tests/ten_runtime/integration/python/multiple_results_python/test_case.py deleted file mode 100644 index c822c47efc..0000000000 --- a/tests/ten_runtime/integration/python/multiple_results_python/test_case.py +++ /dev/null @@ -1,132 +0,0 @@ -""" -Test multiple_results_python. -""" - -import subprocess -import os -import sys -from sys import stdout -from .common import http - - -def http_request(): - return http.post( - "http://127.0.0.1:8002/", - { - "_ten": { - "name": "test", - }, - }, - ) - - -def test_multiple_results_python(): - """Test client and app server.""" - base_path = os.path.dirname(os.path.abspath(__file__)) - root_dir = os.path.join(base_path, "../../../../../") - - # Create virtual environment. - venv_dir = os.path.join(base_path, "venv") - subprocess.run([sys.executable, "-m", "venv", venv_dir]) - - my_env = os.environ.copy() - - # Set the required environment variables for the test. - my_env["PYTHONMALLOC"] = "malloc" - my_env["PYTHONDEVMODE"] = "1" - - # Launch virtual environment. - my_env["VIRTUAL_ENV"] = venv_dir - my_env["PATH"] = os.path.join(venv_dir, "bin") + os.pathsep + my_env["PATH"] - - if sys.platform == "win32": - print("test_multiple_results_python doesn't support win32") - assert False - elif sys.platform == "darwin": - # client depends on some libraries in the TEN app. - my_env["DYLD_LIBRARY_PATH"] = os.path.join( - base_path, "multiple_results_python_app/lib" - ) - else: - # client depends on some libraries in the TEN app. - my_env["LD_LIBRARY_PATH"] = os.path.join( - base_path, "multiple_results_python_app/lib" - ) - - app_root_path = os.path.join(base_path, "multiple_results_python_app") - - tman_install_cmd = [ - os.path.join(root_dir, "ten_manager/bin/tman"), - "--config-file", - os.path.join(root_dir, "tests/local_registry/config.json"), - "install", - ] - - tman_install_process = subprocess.Popen( - tman_install_cmd, - stdout=stdout, - stderr=subprocess.STDOUT, - env=my_env, - cwd=app_root_path, - ) - tman_install_process.wait() - - bootstrap_cmd = os.path.join( - base_path, "multiple_results_python_app/bin/bootstrap" - ) - - bootstrap_process = subprocess.Popen( - bootstrap_cmd, stdout=stdout, stderr=subprocess.STDOUT, env=my_env - ) - bootstrap_process.wait() - - if sys.platform == "linux": - if os.path.exists(os.path.join(base_path, "use_asan_lib_marker")): - libasan_path = os.path.join( - base_path, - "multiple_results_python_app/ten_packages/system/ten_runtime/lib/libasan.so", - ) - - if os.path.exists(libasan_path): - my_env["LD_PRELOAD"] = libasan_path - - server_cmd = os.path.join( - base_path, "multiple_results_python_app/bin/start" - ) - - server = subprocess.Popen( - server_cmd, - stdout=stdout, - stderr=subprocess.STDOUT, - env=my_env, - cwd=app_root_path, - ) - - is_started = http.is_app_started("127.0.0.1", 8002, 30) - if not is_started: - print("The multiple_results_python is not started after 30 seconds.") - - server.kill() - exit_code = server.wait() - print("The exit code of multiple_results_python: ", exit_code) - - assert exit_code == 0 - assert 0 - - return - - try: - resp = http_request() - assert resp != 500 - print(resp) - - finally: - is_stopped = http.stop_app("127.0.0.1", 8002, 30) - if not is_stopped: - print("The multiple_results_python can not stop after 30 seconds.") - server.kill() - - exit_code = server.wait() - print("The exit code of multiple_results_python: ", exit_code) - - assert exit_code == 0 diff --git a/tests/ten_runtime/smoke/cmd_result_test/multiple_result_3.cc b/tests/ten_runtime/smoke/cmd_result_test/multiple_result_3.cc index 3de7bef5c1..4c32e1d9be 100644 --- a/tests/ten_runtime/smoke/cmd_result_test/multiple_result_3.cc +++ b/tests/ten_runtime/smoke/cmd_result_test/multiple_result_3.cc @@ -150,7 +150,7 @@ TEST(CmdResultTest, MultipleResult3) { // NOLINT "extension": "test_extension_1", "cmd": [{ "name": "hello_world", - "result_return_policy": "each_immediately", + "result_return_policy": "each_ok_and_error", "dest": [{ "app": "msgpack://127.0.0.1:8001/", "extension_group": "basic_extension_group",