From 7d42fc43ce7f8ae8e5da3cdc4087e4f6a974c01a Mon Sep 17 00:00:00 2001 From: sunxilin Date: Thu, 9 Jan 2025 19:11:14 +0800 Subject: [PATCH] fix: support calling ten_env_tester api on outer thread in python --- .../cpp/detail/test/extension_tester.h | 1 + core/include/ten_runtime/test/env_tester.h | 3 + .../ten_runtime/test/extension_tester.h | 9 +++ .../binding/python/test/env_tester.h | 3 + .../ten_runtime/test/extension_tester.h | 1 + .../ten_runtime/test/test_extension.h | 4 + .../binding/go/native/test/extension_tester.c | 6 +- .../native/test/env_tester/env_tester.c | 8 ++ .../env_tester/env_tester_on_start_done.c | 11 ++- .../test/env_tester/env_tester_stop_test.c | 22 +++-- .../test/env_tester/ten_env_return_result.c | 80 +++++++++++++++---- .../env_tester/ten_env_send_audio_frame.c | 74 +++++++++++++---- .../native/test/env_tester/ten_env_send_cmd.c | 71 ++++++++++++---- .../test/env_tester/ten_env_send_data.c | 70 ++++++++++++---- .../env_tester/ten_env_send_video_frame.c | 74 +++++++++++++---- .../python/native/test/extension_tester.c | 43 +++++++++- core/src/ten_runtime/test/env_tester.c | 11 ++- core/src/ten_runtime/test/extension_tester.c | 27 +++++++ core/src/ten_runtime/test/test_extension.c | 40 +++++++++- .../tests/test_outer_thread.py | 70 ++++++++++++++++ .../smoke/standalone_test/basic_c.cc | 5 +- .../smoke/standalone_test/on_cmd_c.cc | 4 +- 22 files changed, 541 insertions(+), 96 deletions(-) create mode 100644 tests/ten_runtime/integration/python/standalone_test_python/default_extension_python/tests/test_outer_thread.py diff --git a/core/include/ten_runtime/binding/cpp/detail/test/extension_tester.h b/core/include/ten_runtime/binding/cpp/detail/test/extension_tester.h index 13a4b97916..b63552cf86 100644 --- a/core/include/ten_runtime/binding/cpp/detail/test/extension_tester.h +++ b/core/include/ten_runtime/binding/cpp/detail/test/extension_tester.h @@ -65,6 +65,7 @@ class extension_tester_t { : c_extension_tester(::ten_extension_tester_create( reinterpret_cast( &proxy_on_start), + nullptr, reinterpret_cast(&proxy_on_cmd), reinterpret_cast( &proxy_on_data), diff --git a/core/include/ten_runtime/test/env_tester.h b/core/include/ten_runtime/test/env_tester.h index 808f8b660d..0be0a0623f 100644 --- a/core/include/ten_runtime/test/env_tester.h +++ b/core/include/ten_runtime/test/env_tester.h @@ -16,6 +16,9 @@ typedef struct ten_env_tester_t ten_env_tester_t; TEN_RUNTIME_API bool ten_env_tester_on_start_done(ten_env_tester_t *self, ten_error_t *err); +TEN_RUNTIME_API bool ten_env_tester_on_stop_done(ten_env_tester_t *self, + ten_error_t *err); + typedef void (*ten_env_tester_cmd_result_handler_func_t)( ten_env_tester_t *self, ten_shared_ptr_t *cmd_result, void *user_data, ten_error_t *error); diff --git a/core/include/ten_runtime/test/extension_tester.h b/core/include/ten_runtime/test/extension_tester.h index 972f992853..35ae47124a 100644 --- a/core/include/ten_runtime/test/extension_tester.h +++ b/core/include/ten_runtime/test/extension_tester.h @@ -22,6 +22,8 @@ typedef enum TEN_EXTENSION_TESTER_TEST_MODE { typedef void (*ten_extension_tester_on_start_func_t)( ten_extension_tester_t *self, ten_env_tester_t *ten_env); +typedef void (*ten_extension_tester_on_stop_func_t)( + ten_extension_tester_t *self, ten_env_tester_t *ten_env); typedef void (*ten_extension_tester_on_cmd_func_t)(ten_extension_tester_t *self, ten_env_tester_t *ten_env, @@ -41,6 +43,7 @@ typedef void (*ten_extension_tester_on_video_frame_func_t)( TEN_RUNTIME_API ten_extension_tester_t *ten_extension_tester_create( ten_extension_tester_on_start_func_t on_start, + ten_extension_tester_on_stop_func_t on_stop, ten_extension_tester_on_cmd_func_t on_cmd, ten_extension_tester_on_data_func_t on_data, ten_extension_tester_on_audio_frame_func_t on_audio_frame, @@ -75,8 +78,14 @@ TEN_RUNTIME_API ten_env_tester_t *ten_extension_tester_get_ten_env_tester( TEN_RUNTIME_PRIVATE_API void ten_extension_tester_on_test_extension_start( ten_extension_tester_t *self); +TEN_RUNTIME_PRIVATE_API void ten_extension_tester_on_test_extension_stop( + ten_extension_tester_t *self); + TEN_RUNTIME_PRIVATE_API void ten_extension_tester_on_test_extension_deinit( ten_extension_tester_t *self); TEN_RUNTIME_PRIVATE_API void ten_extension_tester_on_start_done( ten_extension_tester_t *self); + +TEN_RUNTIME_PRIVATE_API void ten_extension_tester_on_stop_done( + ten_extension_tester_t *self); diff --git a/core/include_internal/ten_runtime/binding/python/test/env_tester.h b/core/include_internal/ten_runtime/binding/python/test/env_tester.h index 2a33c06d66..3400db19e1 100644 --- a/core/include_internal/ten_runtime/binding/python/test/env_tester.h +++ b/core/include_internal/ten_runtime/binding/python/test/env_tester.h @@ -12,6 +12,7 @@ #include "include_internal/ten_runtime/binding/python/common/python_stuff.h" #include "include_internal/ten_runtime/test/env_tester.h" +#include "include_internal/ten_runtime/test/env_tester_proxy.h" #include "ten_utils/lib/signature.h" #define TEN_PY_TEN_ENV_TESTER_SIGNATURE 0x9DF807EAFAF9F6D5U @@ -22,6 +23,8 @@ typedef struct ten_py_ten_env_tester_t { ten_signature_t signature; ten_env_tester_t *c_ten_env_tester; + ten_env_tester_proxy_t *c_ten_env_tester_proxy; + PyObject *actual_py_ten_env_tester; } ten_py_ten_env_tester_t; diff --git a/core/include_internal/ten_runtime/test/extension_tester.h b/core/include_internal/ten_runtime/test/extension_tester.h index ea2b579ab1..9aebd0659b 100644 --- a/core/include_internal/ten_runtime/test/extension_tester.h +++ b/core/include_internal/ten_runtime/test/extension_tester.h @@ -50,6 +50,7 @@ struct ten_extension_tester_t { ten_string_t test_app_property_json; ten_extension_tester_on_start_func_t on_start; + ten_extension_tester_on_stop_func_t on_stop; ten_extension_tester_on_cmd_func_t on_cmd; ten_extension_tester_on_data_func_t on_data; ten_extension_tester_on_audio_frame_func_t on_audio_frame; diff --git a/core/include_internal/ten_runtime/test/test_extension.h b/core/include_internal/ten_runtime/test/test_extension.h index 7cf84c957d..b1810f0f61 100644 --- a/core/include_internal/ten_runtime/test/test_extension.h +++ b/core/include_internal/ten_runtime/test/test_extension.h @@ -17,3 +17,7 @@ TEN_RUNTIME_PRIVATE_API void ten_builtin_test_extension_addon_unregister(void); TEN_RUNTIME_PRIVATE_API void ten_builtin_test_extension_ten_env_notify_on_start_done(ten_env_t *ten_env, void *user_data); + +TEN_RUNTIME_PRIVATE_API void +ten_builtin_test_extension_ten_env_notify_on_stop_done(ten_env_t *ten_env, + void *user_data); diff --git a/core/src/ten_runtime/binding/go/native/test/extension_tester.c b/core/src/ten_runtime/binding/go/native/test/extension_tester.c index 7fadc3686d..1cb65e6c9a 100644 --- a/core/src/ten_runtime/binding/go/native/test/extension_tester.c +++ b/core/src/ten_runtime/binding/go/native/test/extension_tester.c @@ -258,9 +258,9 @@ ten_go_extension_tester_t *ten_go_extension_tester_create_internal( extension_tester_bridge, ten_go_extension_tester_bridge_destroy); extension_tester_bridge->bridge.sp_ref_by_c = NULL; - extension_tester_bridge->c_extension_tester = - ten_extension_tester_create(proxy_on_start, proxy_on_cmd, proxy_on_data, - proxy_on_audio_frame, proxy_on_video_frame); + extension_tester_bridge->c_extension_tester = ten_extension_tester_create( + proxy_on_start, NULL, proxy_on_cmd, proxy_on_data, proxy_on_audio_frame, + proxy_on_video_frame); ten_binding_handle_set_me_in_target_lang( &extension_tester_bridge->c_extension_tester->binding_handle, diff --git a/core/src/ten_runtime/binding/python/native/test/env_tester/env_tester.c b/core/src/ten_runtime/binding/python/native/test/env_tester/env_tester.c index bb8551aaa7..83aa06e398 100644 --- a/core/src/ten_runtime/binding/python/native/test/env_tester/env_tester.c +++ b/core/src/ten_runtime/binding/python/native/test/env_tester/env_tester.c @@ -10,6 +10,7 @@ #include "include_internal/ten_runtime/binding/python/common/error.h" #include "ten_runtime/binding/common.h" +#include "ten_runtime/test/env_tester_proxy.h" #include "ten_utils/macro/check.h" bool ten_py_ten_env_tester_check_integrity(ten_py_ten_env_tester_t *self) { @@ -33,6 +34,12 @@ static void ten_py_ten_env_tester_c_part_destroyed( "Should not happen."); ten_env_tester_bridge->c_ten_env_tester = NULL; + if (ten_env_tester_bridge->c_ten_env_tester_proxy) { + ten_env_tester_proxy_release(ten_env_tester_bridge->c_ten_env_tester_proxy, + NULL); + ten_env_tester_bridge->c_ten_env_tester_proxy = NULL; + } + ten_py_ten_env_tester_invalidate(ten_env_tester_bridge); } @@ -100,6 +107,7 @@ ten_py_ten_env_tester_t *ten_py_ten_env_tester_wrap( ten_signature_set(&py_ten_env_tester->signature, TEN_PY_TEN_ENV_TESTER_SIGNATURE); py_ten_env_tester->c_ten_env_tester = ten_env_tester; + py_ten_env_tester->c_ten_env_tester_proxy = NULL; py_ten_env_tester->actual_py_ten_env_tester = create_actual_py_ten_env_tester_instance(py_ten_env_tester); diff --git a/core/src/ten_runtime/binding/python/native/test/env_tester/env_tester_on_start_done.c b/core/src/ten_runtime/binding/python/native/test/env_tester/env_tester_on_start_done.c index 617a7e9199..5fec698ddd 100644 --- a/core/src/ten_runtime/binding/python/native/test/env_tester/env_tester_on_start_done.c +++ b/core/src/ten_runtime/binding/python/native/test/env_tester/env_tester_on_start_done.c @@ -6,10 +6,16 @@ // #include "include_internal/ten_runtime/binding/python/test/env_tester.h" #include "ten_runtime/test/env_tester.h" +#include "ten_runtime/test/env_tester_proxy.h" #include "ten_utils/lib/error.h" #include "ten_utils/macro/check.h" #include "ten_utils/macro/mark.h" +static void ten_py_ten_env_tester_on_start_done_proxy_notify( + ten_env_tester_t *ten_env_tester, void *user_data) { + ten_env_tester_on_start_done(ten_env_tester, NULL); +} + PyObject *ten_py_ten_env_tester_on_start_done(PyObject *self, TEN_UNUSED PyObject *args) { ten_py_ten_env_tester_t *py_ten_env_tester = (ten_py_ten_env_tester_t *)self; @@ -20,7 +26,10 @@ PyObject *ten_py_ten_env_tester_on_start_done(PyObject *self, ten_error_t err; ten_error_init(&err); - ten_env_tester_on_start_done(py_ten_env_tester->c_ten_env_tester, &err); + bool rc = ten_env_tester_proxy_notify( + py_ten_env_tester->c_ten_env_tester_proxy, + ten_py_ten_env_tester_on_start_done_proxy_notify, NULL, &err); + TEN_ASSERT(rc, "Should not happen."); ten_error_deinit(&err); diff --git a/core/src/ten_runtime/binding/python/native/test/env_tester/env_tester_stop_test.c b/core/src/ten_runtime/binding/python/native/test/env_tester/env_tester_stop_test.c index 6ce2e8c4bc..abe45c7b0f 100644 --- a/core/src/ten_runtime/binding/python/native/test/env_tester/env_tester_stop_test.c +++ b/core/src/ten_runtime/binding/python/native/test/env_tester/env_tester_stop_test.c @@ -6,9 +6,15 @@ // #include "include_internal/ten_runtime/binding/python/test/env_tester.h" #include "ten_runtime/test/env_tester.h" +#include "ten_runtime/test/env_tester_proxy.h" #include "ten_utils/macro/check.h" #include "ten_utils/macro/mark.h" +static void ten_py_ten_env_tester_stop_test_proxy_notify( + ten_env_tester_t *ten_env_tester, void *user_data) { + ten_env_tester_stop_test(ten_env_tester, NULL); +} + PyObject *ten_py_ten_env_tester_stop_test(PyObject *self, TEN_UNUSED PyObject *args) { ten_py_ten_env_tester_t *py_ten_env_tester = (ten_py_ten_env_tester_t *)self; @@ -16,11 +22,15 @@ PyObject *ten_py_ten_env_tester_stop_test(PyObject *self, ten_py_ten_env_tester_check_integrity(py_ten_env_tester), "Invalid argument."); - bool rc = ten_env_tester_stop_test(py_ten_env_tester->c_ten_env_tester, NULL); + ten_error_t err; + ten_error_init(&err); + + bool rc = ten_env_tester_proxy_notify( + py_ten_env_tester->c_ten_env_tester_proxy, + ten_py_ten_env_tester_stop_test_proxy_notify, NULL, &err); + TEN_ASSERT(rc, "Should not happen."); + + ten_error_deinit(&err); - if (rc) { - Py_RETURN_NONE; - } else { - return NULL; - } + Py_RETURN_NONE; } diff --git a/core/src/ten_runtime/binding/python/native/test/env_tester/ten_env_return_result.c b/core/src/ten_runtime/binding/python/native/test/env_tester/ten_env_return_result.c index f37569bdb3..bacb648ab4 100644 --- a/core/src/ten_runtime/binding/python/native/test/env_tester/ten_env_return_result.c +++ b/core/src/ten_runtime/binding/python/native/test/env_tester/ten_env_return_result.c @@ -12,7 +12,46 @@ #include "include_internal/ten_runtime/binding/python/test/env_tester.h" #include "ten_runtime/msg/cmd_result/cmd_result.h" #include "ten_runtime/test/env_tester.h" +#include "ten_runtime/test/env_tester_proxy.h" #include "ten_utils/macro/check.h" +#include "ten_utils/macro/memory.h" + +typedef struct ten_py_ten_env_tester_notify_return_result_ctx_t { + ten_shared_ptr_t *cmd_result; + ten_shared_ptr_t *target_cmd; + PyObject *cb_func; +} ten_py_ten_env_tester_notify_return_result_ctx_t; + +static ten_py_ten_env_tester_notify_return_result_ctx_t * +ten_py_ten_env_tester_notify_return_result_ctx_create( + ten_shared_ptr_t *cmd_result, ten_shared_ptr_t *target_cmd, + PyObject *cb_func) { + ten_py_ten_env_tester_notify_return_result_ctx_t *ctx = + TEN_MALLOC(sizeof(ten_py_ten_env_tester_notify_return_result_ctx_t)); + ctx->cmd_result = ten_shared_ptr_clone(cmd_result); + ctx->target_cmd = ten_shared_ptr_clone(target_cmd); + + // Increase the reference count of the callback function to ensure that it + // will not be destroyed before the callback is called. + if (cb_func) { + Py_INCREF(cb_func); + } + + ctx->cb_func = cb_func; + return ctx; +} + +static void ten_py_ten_env_tester_notify_return_result_ctx_destroy( + ten_py_ten_env_tester_notify_return_result_ctx_t *ctx) { + ten_shared_ptr_destroy(ctx->cmd_result); + ten_shared_ptr_destroy(ctx->target_cmd); + + if (ctx->cb_func) { + Py_XDECREF(ctx->cb_func); + } + + TEN_FREE(ctx); +} static void proxy_return_result_callback(ten_env_tester_t *self, void *user_data, ten_error_t *error) { @@ -56,6 +95,25 @@ static void proxy_return_result_callback(ten_env_tester_t *self, ten_py_gil_state_release_internal(prev_state); } +static void ten_py_ten_env_tester_notify_return_result_proxy_notify( + ten_env_tester_t *ten_env_tester, void *user_data) { + ten_py_ten_env_tester_notify_return_result_ctx_t *ctx = + (ten_py_ten_env_tester_notify_return_result_ctx_t *)user_data; + + if (ctx->cb_func) { + Py_INCREF(ctx->cb_func); + + ten_env_tester_return_result(ten_env_tester, ctx->cmd_result, + ctx->target_cmd, proxy_return_result_callback, + ctx->cb_func, NULL); + } else { + ten_env_tester_return_result(ten_env_tester, ctx->cmd_result, + ctx->target_cmd, NULL, NULL, NULL); + } + + ten_py_ten_env_tester_notify_return_result_ctx_destroy(ctx); +} + PyObject *ten_py_ten_env_tester_return_result(PyObject *self, PyObject *args) { ten_py_ten_env_tester_t *py_ten_env_tester = (ten_py_ten_env_tester_t *)self; TEN_ASSERT(py_ten_env_tester && @@ -90,24 +148,16 @@ PyObject *ten_py_ten_env_tester_return_result(PyObject *self, PyObject *args) { cb_func = NULL; } - if (cb_func) { - // Increase the reference count of the callback function to ensure that it - // will not be destroyed before the callback is called. - Py_INCREF(cb_func); + ten_py_ten_env_tester_notify_return_result_ctx_t *ctx = + ten_py_ten_env_tester_notify_return_result_ctx_create( + py_cmd_result->msg.c_msg, py_target_cmd->msg.c_msg, cb_func); - success = ten_env_tester_return_result( - py_ten_env_tester->c_ten_env_tester, py_cmd_result->msg.c_msg, - py_target_cmd->msg.c_msg, proxy_return_result_callback, cb_func, &err); - } else { - success = ten_env_tester_return_result( - py_ten_env_tester->c_ten_env_tester, py_cmd_result->msg.c_msg, - py_target_cmd->msg.c_msg, NULL, NULL, &err); - } + success = ten_env_tester_proxy_notify( + py_ten_env_tester->c_ten_env_tester_proxy, + ten_py_ten_env_tester_notify_return_result_proxy_notify, ctx, &err); if (!success) { - if (cb_func) { - Py_XDECREF(cb_func); - } + ten_py_ten_env_tester_notify_return_result_ctx_destroy(ctx); ten_py_raise_py_runtime_error_exception("Failed to return result."); goto done; diff --git a/core/src/ten_runtime/binding/python/native/test/env_tester/ten_env_send_audio_frame.c b/core/src/ten_runtime/binding/python/native/test/env_tester/ten_env_send_audio_frame.c index 8a8764e735..9d44640188 100644 --- a/core/src/ten_runtime/binding/python/native/test/env_tester/ten_env_send_audio_frame.c +++ b/core/src/ten_runtime/binding/python/native/test/env_tester/ten_env_send_audio_frame.c @@ -10,7 +10,40 @@ #include "include_internal/ten_runtime/binding/python/msg/msg.h" #include "include_internal/ten_runtime/binding/python/test/env_tester.h" #include "ten_runtime/test/env_tester.h" +#include "ten_runtime/test/env_tester_proxy.h" #include "ten_utils/macro/check.h" +#include "ten_utils/macro/memory.h" + +typedef struct ten_py_ten_env_tester_send_audio_frame_ctx_t { + ten_shared_ptr_t *audio_frame; + PyObject *cb_func; +} ten_py_ten_env_tester_send_audio_frame_ctx_t; + +static ten_py_ten_env_tester_send_audio_frame_ctx_t * +ten_py_ten_env_tester_send_audio_frame_ctx_create(ten_shared_ptr_t *audio_frame, + PyObject *cb_func) { + ten_py_ten_env_tester_send_audio_frame_ctx_t *ctx = + TEN_MALLOC(sizeof(ten_py_ten_env_tester_send_audio_frame_ctx_t)); + ctx->audio_frame = ten_shared_ptr_clone(audio_frame); + + if (cb_func) { + Py_INCREF(cb_func); + } + + ctx->cb_func = cb_func; + return ctx; +} + +static void ten_py_ten_env_tester_send_audio_frame_ctx_destroy( + ten_py_ten_env_tester_send_audio_frame_ctx_t *ctx) { + ten_shared_ptr_destroy(ctx->audio_frame); + + if (ctx->cb_func) { + Py_XDECREF(ctx->cb_func); + } + + TEN_FREE(ctx); +} static void proxy_send_xxx_callback(ten_env_tester_t *self, void *user_audio_frame, @@ -55,6 +88,25 @@ static void proxy_send_xxx_callback(ten_env_tester_t *self, ten_py_gil_state_release_internal(prev_state); } +static void ten_py_ten_env_tester_send_audio_frame_proxy_notify( + ten_env_tester_t *ten_env_tester, void *user_data) { + ten_py_ten_env_tester_send_audio_frame_ctx_t *ctx = + (ten_py_ten_env_tester_send_audio_frame_ctx_t *)user_data; + + if (ctx->cb_func) { + Py_INCREF(ctx->cb_func); + + ten_env_tester_send_audio_frame(ten_env_tester, ctx->audio_frame, + proxy_send_xxx_callback, ctx->cb_func, + NULL); + } else { + ten_env_tester_send_audio_frame(ten_env_tester, ctx->audio_frame, NULL, + NULL, NULL); + } + + ten_py_ten_env_tester_send_audio_frame_ctx_destroy(ctx); +} + PyObject *ten_py_ten_env_tester_send_audio_frame(PyObject *self, PyObject *args) { ten_py_ten_env_tester_t *py_ten_env_tester = (ten_py_ten_env_tester_t *)self; @@ -88,24 +140,16 @@ PyObject *ten_py_ten_env_tester_send_audio_frame(PyObject *self, cb_func = NULL; } - if (cb_func) { - // Increase the reference count of the callback function to ensure that it - // will not be destroyed before the callback is called. - Py_INCREF(cb_func); + ten_py_ten_env_tester_send_audio_frame_ctx_t *ctx = + ten_py_ten_env_tester_send_audio_frame_ctx_create( + py_audio_frame->msg.c_msg, cb_func); - success = ten_env_tester_send_audio_frame( - py_ten_env_tester->c_ten_env_tester, py_audio_frame->msg.c_msg, - proxy_send_xxx_callback, cb_func, &err); - } else { - success = ten_env_tester_send_audio_frame( - py_ten_env_tester->c_ten_env_tester, py_audio_frame->msg.c_msg, NULL, - NULL, &err); - } + success = ten_env_tester_proxy_notify( + py_ten_env_tester->c_ten_env_tester_proxy, + ten_py_ten_env_tester_send_audio_frame_proxy_notify, ctx, &err); if (!success) { - if (cb_func) { - Py_XDECREF(cb_func); - } + ten_py_ten_env_tester_send_audio_frame_ctx_destroy(ctx); ten_py_raise_py_runtime_error_exception("Failed to send audio_frame."); goto done; diff --git a/core/src/ten_runtime/binding/python/native/test/env_tester/ten_env_send_cmd.c b/core/src/ten_runtime/binding/python/native/test/env_tester/ten_env_send_cmd.c index 215c6c2d50..d1eb3c578a 100644 --- a/core/src/ten_runtime/binding/python/native/test/env_tester/ten_env_send_cmd.c +++ b/core/src/ten_runtime/binding/python/native/test/env_tester/ten_env_send_cmd.c @@ -12,7 +12,41 @@ #include "include_internal/ten_runtime/binding/python/test/env_tester.h" #include "ten_runtime/msg/cmd_result/cmd_result.h" #include "ten_runtime/test/env_tester.h" +#include "ten_runtime/test/env_tester_proxy.h" #include "ten_utils/macro/check.h" +#include "ten_utils/macro/memory.h" + +typedef struct ten_py_ten_env_tester_send_cmd_ctx_t { + ten_shared_ptr_t *cmd; + PyObject *cb_func; +} ten_py_ten_env_tester_send_cmd_ctx_t; + +static ten_py_ten_env_tester_send_cmd_ctx_t * +ten_py_ten_env_tester_send_cmd_ctx_create(ten_shared_ptr_t *cmd, + PyObject *cb_func) { + ten_py_ten_env_tester_send_cmd_ctx_t *ctx = + TEN_MALLOC(sizeof(ten_py_ten_env_tester_send_cmd_ctx_t)); + ctx->cmd = ten_shared_ptr_clone(cmd); + + if (cb_func) { + Py_INCREF(cb_func); + } + + ctx->cb_func = cb_func; + + return ctx; +} + +static void ten_py_ten_env_tester_send_cmd_ctx_destroy( + ten_py_ten_env_tester_send_cmd_ctx_t *ctx) { + ten_shared_ptr_destroy(ctx->cmd); + + if (ctx->cb_func) { + Py_XDECREF(ctx->cb_func); + } + + TEN_FREE(ctx); +} static void proxy_send_xxx_callback(ten_env_tester_t *ten_env_tester, ten_shared_ptr_t *cmd_result, @@ -73,6 +107,23 @@ static void proxy_send_xxx_callback(ten_env_tester_t *ten_env_tester, ten_py_gil_state_release_internal(prev_state); } +static void ten_py_ten_env_tester_send_cmd_proxy_notify( + ten_env_tester_t *ten_env_tester, void *user_data) { + ten_py_ten_env_tester_send_cmd_ctx_t *ctx = + (ten_py_ten_env_tester_send_cmd_ctx_t *)user_data; + + if (ctx->cb_func) { + Py_INCREF(ctx->cb_func); + + ten_env_tester_send_cmd(ten_env_tester, ctx->cmd, proxy_send_xxx_callback, + ctx->cb_func, NULL); + } else { + ten_env_tester_send_cmd(ten_env_tester, ctx->cmd, NULL, NULL, NULL); + } + + ten_py_ten_env_tester_send_cmd_ctx_destroy(ctx); +} + PyObject *ten_py_ten_env_tester_send_cmd(PyObject *self, PyObject *args) { ten_py_ten_env_tester_t *py_ten_env_tester = (ten_py_ten_env_tester_t *)self; TEN_ASSERT(py_ten_env_tester && @@ -104,23 +155,15 @@ PyObject *ten_py_ten_env_tester_send_cmd(PyObject *self, PyObject *args) { cb_func = NULL; } - if (cb_func) { - // Increase the reference count of the callback function to ensure that it - // will not be destroyed before the callback is called. - Py_INCREF(cb_func); + ten_py_ten_env_tester_send_cmd_ctx_t *ctx = + ten_py_ten_env_tester_send_cmd_ctx_create(py_cmd->msg.c_msg, cb_func); - success = ten_env_tester_send_cmd(py_ten_env_tester->c_ten_env_tester, - py_cmd->msg.c_msg, - proxy_send_xxx_callback, cb_func, &err); - } else { - success = ten_env_tester_send_cmd(py_ten_env_tester->c_ten_env_tester, - py_cmd->msg.c_msg, NULL, NULL, &err); - } + success = ten_env_tester_proxy_notify( + py_ten_env_tester->c_ten_env_tester_proxy, + ten_py_ten_env_tester_send_cmd_proxy_notify, ctx, &err); if (!success) { - if (cb_func) { - Py_XDECREF(cb_func); - } + ten_py_ten_env_tester_send_cmd_ctx_destroy(ctx); ten_py_raise_py_runtime_error_exception("Failed to send cmd."); goto done; diff --git a/core/src/ten_runtime/binding/python/native/test/env_tester/ten_env_send_data.c b/core/src/ten_runtime/binding/python/native/test/env_tester/ten_env_send_data.c index 6ae7546fd7..29c89d65dc 100644 --- a/core/src/ten_runtime/binding/python/native/test/env_tester/ten_env_send_data.c +++ b/core/src/ten_runtime/binding/python/native/test/env_tester/ten_env_send_data.c @@ -10,7 +10,40 @@ #include "include_internal/ten_runtime/binding/python/msg/msg.h" #include "include_internal/ten_runtime/binding/python/test/env_tester.h" #include "ten_runtime/test/env_tester.h" +#include "ten_runtime/test/env_tester_proxy.h" #include "ten_utils/macro/check.h" +#include "ten_utils/macro/memory.h" + +typedef struct ten_py_ten_env_tester_send_data_ctx_t { + ten_shared_ptr_t *data; + PyObject *cb_func; +} ten_py_ten_env_tester_send_data_ctx_t; + +static ten_py_ten_env_tester_send_data_ctx_t * +ten_py_ten_env_tester_send_data_ctx_create(ten_shared_ptr_t *data, + PyObject *cb_func) { + ten_py_ten_env_tester_send_data_ctx_t *ctx = + TEN_MALLOC(sizeof(ten_py_ten_env_tester_send_data_ctx_t)); + ctx->data = ten_shared_ptr_clone(data); + + if (cb_func) { + Py_INCREF(cb_func); + } + + ctx->cb_func = cb_func; + return ctx; +} + +static void ten_py_ten_env_tester_send_data_ctx_destroy( + ten_py_ten_env_tester_send_data_ctx_t *ctx) { + ten_shared_ptr_destroy(ctx->data); + + if (ctx->cb_func) { + Py_XDECREF(ctx->cb_func); + } + + TEN_FREE(ctx); +} static void proxy_send_xxx_callback(ten_env_tester_t *self, void *user_data, ten_error_t *error) { @@ -54,6 +87,23 @@ static void proxy_send_xxx_callback(ten_env_tester_t *self, void *user_data, ten_py_gil_state_release_internal(prev_state); } +static void ten_py_ten_env_tester_send_data_proxy_notify( + ten_env_tester_t *ten_env_tester, void *user_data) { + ten_py_ten_env_tester_send_data_ctx_t *ctx = + (ten_py_ten_env_tester_send_data_ctx_t *)user_data; + + if (ctx->cb_func) { + Py_INCREF(ctx->cb_func); + + ten_env_tester_send_data(ten_env_tester, ctx->data, proxy_send_xxx_callback, + ctx->cb_func, NULL); + } else { + ten_env_tester_send_data(ten_env_tester, ctx->data, NULL, NULL, NULL); + } + + ten_py_ten_env_tester_send_data_ctx_destroy(ctx); +} + PyObject *ten_py_ten_env_tester_send_data(PyObject *self, PyObject *args) { ten_py_ten_env_tester_t *py_ten_env_tester = (ten_py_ten_env_tester_t *)self; TEN_ASSERT(py_ten_env_tester && @@ -86,23 +136,15 @@ PyObject *ten_py_ten_env_tester_send_data(PyObject *self, PyObject *args) { cb_func = NULL; } - if (cb_func) { - // Increase the reference count of the callback function to ensure that it - // will not be destroyed before the callback is called. - Py_INCREF(cb_func); + ten_py_ten_env_tester_send_data_ctx_t *ctx = + ten_py_ten_env_tester_send_data_ctx_create(py_data->msg.c_msg, cb_func); - success = ten_env_tester_send_data(py_ten_env_tester->c_ten_env_tester, - py_data->msg.c_msg, - proxy_send_xxx_callback, cb_func, &err); - } else { - success = ten_env_tester_send_data(py_ten_env_tester->c_ten_env_tester, - py_data->msg.c_msg, NULL, NULL, &err); - } + success = ten_env_tester_proxy_notify( + py_ten_env_tester->c_ten_env_tester_proxy, + ten_py_ten_env_tester_send_data_proxy_notify, ctx, &err); if (!success) { - if (cb_func) { - Py_XDECREF(cb_func); - } + ten_py_ten_env_tester_send_data_ctx_destroy(ctx); ten_py_raise_py_runtime_error_exception("Failed to send data."); goto done; diff --git a/core/src/ten_runtime/binding/python/native/test/env_tester/ten_env_send_video_frame.c b/core/src/ten_runtime/binding/python/native/test/env_tester/ten_env_send_video_frame.c index 9c3fc64bd9..f789eab5c9 100644 --- a/core/src/ten_runtime/binding/python/native/test/env_tester/ten_env_send_video_frame.c +++ b/core/src/ten_runtime/binding/python/native/test/env_tester/ten_env_send_video_frame.c @@ -10,7 +10,40 @@ #include "include_internal/ten_runtime/binding/python/msg/video_frame.h" #include "include_internal/ten_runtime/binding/python/test/env_tester.h" #include "ten_runtime/test/env_tester.h" +#include "ten_runtime/test/env_tester_proxy.h" #include "ten_utils/macro/check.h" +#include "ten_utils/macro/memory.h" + +typedef struct ten_py_ten_env_tester_send_video_frame_ctx_t { + ten_shared_ptr_t *video_frame; + PyObject *cb_func; +} ten_py_ten_env_tester_send_video_frame_ctx_t; + +static ten_py_ten_env_tester_send_video_frame_ctx_t * +ten_py_ten_env_tester_send_video_frame_ctx_create(ten_shared_ptr_t *video_frame, + PyObject *cb_func) { + ten_py_ten_env_tester_send_video_frame_ctx_t *ctx = + TEN_MALLOC(sizeof(ten_py_ten_env_tester_send_video_frame_ctx_t)); + ctx->video_frame = ten_shared_ptr_clone(video_frame); + + if (cb_func) { + Py_INCREF(cb_func); + } + + ctx->cb_func = cb_func; + return ctx; +} + +static void ten_py_ten_env_tester_send_video_frame_ctx_destroy( + ten_py_ten_env_tester_send_video_frame_ctx_t *ctx) { + ten_shared_ptr_destroy(ctx->video_frame); + + if (ctx->cb_func) { + Py_XDECREF(ctx->cb_func); + } + + TEN_FREE(ctx); +} static void proxy_send_xxx_callback(ten_env_tester_t *self, void *user_video_frame, @@ -55,6 +88,25 @@ static void proxy_send_xxx_callback(ten_env_tester_t *self, ten_py_gil_state_release_internal(prev_state); } +static void ten_py_ten_env_tester_send_video_frame_proxy_notify( + ten_env_tester_t *ten_env_tester, void *user_data) { + ten_py_ten_env_tester_send_video_frame_ctx_t *ctx = + (ten_py_ten_env_tester_send_video_frame_ctx_t *)user_data; + + if (ctx->cb_func) { + Py_INCREF(ctx->cb_func); + + ten_env_tester_send_video_frame(ten_env_tester, ctx->video_frame, + proxy_send_xxx_callback, ctx->cb_func, + NULL); + } else { + ten_env_tester_send_video_frame(ten_env_tester, ctx->video_frame, NULL, + NULL, NULL); + } + + ten_py_ten_env_tester_send_video_frame_ctx_destroy(ctx); +} + PyObject *ten_py_ten_env_tester_send_video_frame(PyObject *self, PyObject *args) { ten_py_ten_env_tester_t *py_ten_env_tester = (ten_py_ten_env_tester_t *)self; @@ -88,24 +140,16 @@ PyObject *ten_py_ten_env_tester_send_video_frame(PyObject *self, cb_func = NULL; } - if (cb_func) { - // Increase the reference count of the callback function to ensure that it - // will not be destroyed before the callback is called. - Py_INCREF(cb_func); + ten_py_ten_env_tester_send_video_frame_ctx_t *ctx = + ten_py_ten_env_tester_send_video_frame_ctx_create( + py_video_frame->msg.c_msg, cb_func); - success = ten_env_tester_send_video_frame( - py_ten_env_tester->c_ten_env_tester, py_video_frame->msg.c_msg, - proxy_send_xxx_callback, cb_func, &err); - } else { - success = ten_env_tester_send_video_frame( - py_ten_env_tester->c_ten_env_tester, py_video_frame->msg.c_msg, NULL, - NULL, &err); - } + success = ten_env_tester_proxy_notify( + py_ten_env_tester->c_ten_env_tester_proxy, + ten_py_ten_env_tester_send_video_frame_proxy_notify, ctx, &err); if (!success) { - if (cb_func) { - Py_XDECREF(cb_func); - } + ten_py_ten_env_tester_send_video_frame_ctx_destroy(ctx); ten_py_raise_py_runtime_error_exception("Failed to send video_frame."); goto done; diff --git a/core/src/ten_runtime/binding/python/native/test/extension_tester.c b/core/src/ten_runtime/binding/python/native/test/extension_tester.c index 6bba00daf8..ae87db5d0c 100644 --- a/core/src/ten_runtime/binding/python/native/test/extension_tester.c +++ b/core/src/ten_runtime/binding/python/native/test/extension_tester.c @@ -18,6 +18,8 @@ #include "include_internal/ten_runtime/msg/msg.h" #include "include_internal/ten_runtime/test/extension_tester.h" #include "ten_runtime/binding/common.h" +#include "ten_runtime/test/env_tester.h" +#include "ten_runtime/test/env_tester_proxy.h" #include "ten_utils/macro/check.h" #include "ten_utils/macro/mark.h" @@ -73,6 +75,10 @@ static void proxy_on_start(ten_extension_tester_t *extension_tester, py_extension_tester->py_ten_env_tester = (PyObject *)py_ten_env_tester; TEN_ASSERT(py_ten_env_tester->actual_py_ten_env_tester, "Should not happen."); + py_ten_env_tester->c_ten_env_tester_proxy = + ten_env_tester_proxy_create(ten_env_tester, NULL); + TEN_ASSERT(py_ten_env_tester->c_ten_env_tester_proxy, "Should not happen."); + PyObject *py_res = PyObject_CallMethod((PyObject *)py_extension_tester, "on_start", "O", py_ten_env_tester->actual_py_ten_env_tester); @@ -84,6 +90,37 @@ static void proxy_on_start(ten_extension_tester_t *extension_tester, ten_py_gil_state_release_internal(prev_state); } +static void proxy_on_stop(ten_extension_tester_t *extension_tester, + ten_env_tester_t *ten_env_tester) { + TEN_ASSERT(extension_tester && + ten_extension_tester_check_integrity(extension_tester, true), + "Invalid argument."); + TEN_ASSERT(ten_env_tester && ten_env_tester_check_integrity(ten_env_tester), + "Invalid argument."); + + ten_py_extension_tester_t *py_extension_tester = + (ten_py_extension_tester_t *)ten_binding_handle_get_me_in_target_lang( + (ten_binding_handle_t *)extension_tester); + TEN_ASSERT(py_extension_tester && + ten_py_extension_tester_check_integrity(py_extension_tester), + "Invalid argument."); + + PyObject *py_ten_env_tester = py_extension_tester->py_ten_env_tester; + TEN_ASSERT(py_ten_env_tester, "Should not happen."); + TEN_ASSERT( + ((ten_py_ten_env_tester_t *)py_ten_env_tester)->actual_py_ten_env_tester, + "Should not happen."); + + // Release the ten_env_tester_proxy. + ten_env_tester_proxy_release( + ((ten_py_ten_env_tester_t *)py_ten_env_tester)->c_ten_env_tester_proxy, + NULL); + + ((ten_py_ten_env_tester_t *)py_ten_env_tester)->c_ten_env_tester_proxy = NULL; + + ten_env_tester_on_stop_done(ten_env_tester, NULL); +} + static void proxy_on_cmd(ten_extension_tester_t *extension_tester, ten_env_tester_t *ten_env_tester, ten_shared_ptr_t *cmd) { @@ -266,9 +303,9 @@ static ten_py_extension_tester_t *ten_py_extension_tester_init( (ten_py_extension_tester_t *)py_extension_tester), "Invalid argument."); - py_extension_tester->c_extension_tester = - ten_extension_tester_create(proxy_on_start, proxy_on_cmd, proxy_on_data, - proxy_on_audio_frame, proxy_on_video_frame); + py_extension_tester->c_extension_tester = ten_extension_tester_create( + proxy_on_start, proxy_on_stop, proxy_on_cmd, proxy_on_data, + proxy_on_audio_frame, proxy_on_video_frame); ten_binding_handle_set_me_in_target_lang( &py_extension_tester->c_extension_tester->binding_handle, diff --git a/core/src/ten_runtime/test/env_tester.c b/core/src/ten_runtime/test/env_tester.c index 338b5cd9f4..c0967b331f 100644 --- a/core/src/ten_runtime/test/env_tester.c +++ b/core/src/ten_runtime/test/env_tester.c @@ -35,9 +35,6 @@ bool ten_env_tester_check_integrity(ten_env_tester_t *self) { return false; } - // TODO(Wei): Currently, all calls to ten_env_tester must be made within the - // tester thread. If we need to call the ten_env_tester API from a non-tester - // thread, a mechanism similar to ten_env_tester_proxy must be created. if (!ten_sanitizer_thread_check_do_check(&self->tester->thread_check)) { return false; } @@ -682,6 +679,14 @@ bool ten_env_tester_on_start_done(ten_env_tester_t *self, ten_error_t *err) { return true; } +bool ten_env_tester_on_stop_done(ten_env_tester_t *self, ten_error_t *err) { + TEN_ASSERT(self && ten_env_tester_check_integrity(self), "Invalid argument."); + + ten_extension_tester_on_stop_done(self->tester); + + return true; +} + void ten_env_tester_set_close_handler_in_target_lang( ten_env_tester_t *self, ten_env_tester_close_handler_in_target_lang_func_t close_handler) { diff --git a/core/src/ten_runtime/test/extension_tester.c b/core/src/ten_runtime/test/extension_tester.c index 2569d96b48..5ad75c92e5 100644 --- a/core/src/ten_runtime/test/extension_tester.c +++ b/core/src/ten_runtime/test/extension_tester.c @@ -59,6 +59,7 @@ bool ten_extension_tester_check_integrity(ten_extension_tester_t *self, ten_extension_tester_t *ten_extension_tester_create( ten_extension_tester_on_start_func_t on_start, + ten_extension_tester_on_stop_func_t on_stop, ten_extension_tester_on_cmd_func_t on_cmd, ten_extension_tester_on_data_func_t on_data, ten_extension_tester_on_audio_frame_func_t on_audio_frame, @@ -74,6 +75,7 @@ ten_extension_tester_t *ten_extension_tester_create( ten_list_init(&self->addon_base_dirs); self->on_start = on_start; + self->on_stop = on_stop; self->on_cmd = on_cmd; self->on_data = on_data; self->on_audio_frame = on_audio_frame; @@ -417,6 +419,19 @@ void ten_extension_tester_on_start_done(ten_extension_tester_t *self) { TEN_ASSERT(rc, "Should not happen."); } +void ten_extension_tester_on_stop_done(ten_extension_tester_t *self) { + TEN_ASSERT(self && ten_extension_tester_check_integrity(self, true), + "Invalid argument."); + + TEN_LOGI("tester on_stop() done."); + + bool rc = ten_env_proxy_notify( + self->test_extension_ten_env_proxy, + ten_builtin_test_extension_ten_env_notify_on_stop_done, NULL, false, + NULL); + TEN_ASSERT(rc, "Should not happen."); +} + void ten_extension_tester_on_test_extension_start( ten_extension_tester_t *self) { TEN_ASSERT(self && ten_extension_tester_check_integrity(self, true), @@ -429,6 +444,18 @@ void ten_extension_tester_on_test_extension_start( } } +void ten_extension_tester_on_test_extension_stop( + ten_extension_tester_t *self) { + TEN_ASSERT(self && ten_extension_tester_check_integrity(self, true), + "Invalid argument."); + + if (self->on_stop) { + self->on_stop(self, self->ten_env_tester); + } else { + ten_extension_tester_on_stop_done(self); + } +} + void ten_extension_tester_on_test_extension_deinit( ten_extension_tester_t *self) { TEN_ASSERT(self && ten_extension_tester_check_integrity(self, true), diff --git a/core/src/ten_runtime/test/test_extension.c b/core/src/ten_runtime/test/test_extension.c index 1377711db6..ded678e578 100644 --- a/core/src/ten_runtime/test/test_extension.c +++ b/core/src/ten_runtime/test/test_extension.c @@ -65,6 +65,15 @@ static void ten_extension_tester_on_test_extension_start_task( ten_extension_tester_on_test_extension_start(tester); } +static void ten_extension_tester_on_test_extension_stop_task(void *self_, + void *arg) { + ten_extension_tester_t *tester = self_; + TEN_ASSERT(tester && ten_extension_tester_check_integrity(tester, true), + "Invalid argument."); + + ten_extension_tester_on_test_extension_stop(tester); +} + static void test_extension_on_start(ten_extension_t *self, ten_env_t *ten_env) { TEN_ASSERT(self && ten_env, "Invalid argument."); @@ -80,6 +89,21 @@ static void test_extension_on_start(ten_extension_t *self, ten_env_t *ten_env) { tester, NULL); } +static void test_extension_on_stop(ten_extension_t *self, ten_env_t *ten_env) { + TEN_ASSERT(self && ten_env, "Invalid argument."); + + // The tester framework needs to ensure that the tester's environment is + // always destroyed later than the test_extension, so calling the tester + // within the test_extension is always valid. + ten_extension_tester_t *tester = + test_extension_get_extension_tester_ptr(ten_env); + self->user_data = tester; + + ten_runloop_post_task_tail(tester->tester_runloop, + ten_extension_tester_on_test_extension_stop_task, + tester, NULL); +} + void ten_builtin_test_extension_ten_env_notify_on_start_done( ten_env_t *ten_env, TEN_UNUSED void *user_data) { TEN_ASSERT(ten_env && ten_env_check_integrity(ten_env, true), @@ -89,6 +113,15 @@ void ten_builtin_test_extension_ten_env_notify_on_start_done( TEN_ASSERT(rc, "Should not happen."); } +void ten_builtin_test_extension_ten_env_notify_on_stop_done(ten_env_t *ten_env, + void *user_data) { + TEN_ASSERT(ten_env && ten_env_check_integrity(ten_env, true), + "Should not happen."); + + bool rc = ten_env_on_stop_done(ten_env, NULL); + TEN_ASSERT(rc, "Should not happen."); +} + static void ten_extension_tester_on_test_extension_cmd_task(void *self_, void *arg) { ten_extension_tester_t *tester = self_; @@ -255,9 +288,10 @@ static void test_extension_addon_create_instance(ten_addon_t *addon, TEN_ASSERT(addon && name, "Invalid argument."); ten_extension_t *extension = ten_extension_create( - name, test_extension_on_configure, NULL, test_extension_on_start, NULL, - test_extension_on_deinit, test_extension_on_cmd, test_extension_on_data, - test_extension_on_audio_frame, test_extension_on_video_frame, NULL); + name, test_extension_on_configure, NULL, test_extension_on_start, + test_extension_on_stop, test_extension_on_deinit, test_extension_on_cmd, + test_extension_on_data, test_extension_on_audio_frame, + test_extension_on_video_frame, NULL); ten_env_on_create_instance_done(ten_env, extension, context, NULL); } diff --git a/tests/ten_runtime/integration/python/standalone_test_python/default_extension_python/tests/test_outer_thread.py b/tests/ten_runtime/integration/python/standalone_test_python/default_extension_python/tests/test_outer_thread.py new file mode 100644 index 0000000000..a42b53e997 --- /dev/null +++ b/tests/ten_runtime/integration/python/standalone_test_python/default_extension_python/tests/test_outer_thread.py @@ -0,0 +1,70 @@ +# +# Copyright © 2025 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 pathlib import Path +import threading +from typing import Optional +from ten import ( + ExtensionTester, + TenEnvTester, + Cmd, + Data, + AudioFrame, + VideoFrame, + CmdResult, + StatusCode, + TenError, +) + + +class ExtensionTesterOuterThread(ExtensionTester): + def check_hello( + self, + ten_env: TenEnvTester, + result: Optional[CmdResult], + error: Optional[TenError], + ): + if error is not None: + assert False, error + + assert result is not None + + statusCode = result.get_status_code() + print("receive hello_world, status:" + str(statusCode)) + + if statusCode == StatusCode.OK: + ten_env.stop_test() + + def send_msgs(self, ten_env: TenEnvTester): + new_cmd = Cmd.create("hello_world") + ten_env.send_cmd( + new_cmd, + lambda ten_env, result, error: self.check_hello( + ten_env, result, error + ), + ) + + ten_env.send_data(Data.create("test")) + ten_env.send_audio_frame(AudioFrame.create("test")) + ten_env.send_video_frame(VideoFrame.create("test")) + + def on_start(self, ten_env: TenEnvTester) -> None: + self.thread = threading.Thread(target=self.send_msgs, args=(ten_env,)) + self.thread.start() + + print("tester on_start_done") + ten_env.on_start_done() + + +def test_basic(): + tester = ExtensionTesterOuterThread() + tester.add_addon_base_dir(str(Path(__file__).resolve().parent.parent)) + tester.set_test_mode_single("default_extension_python") + tester.run() + + +if __name__ == "__main__": + test_basic() diff --git a/tests/ten_runtime/smoke/standalone_test/basic_c.cc b/tests/ten_runtime/smoke/standalone_test/basic_c.cc index ff50f34d06..9e1e47ea3c 100644 --- a/tests/ten_runtime/smoke/standalone_test/basic_c.cc +++ b/tests/ten_runtime/smoke/standalone_test/basic_c.cc @@ -73,8 +73,9 @@ void ten_extension_tester_on_start(TEN_UNUSED ten_extension_tester_t *tester, } // namespace TEST(StandaloneTest, BasicC) { // NOLINT - ten_extension_tester_t *tester = ten_extension_tester_create( - ten_extension_tester_on_start, nullptr, nullptr, nullptr, nullptr); + ten_extension_tester_t *tester = + ten_extension_tester_create(ten_extension_tester_on_start, nullptr, + nullptr, nullptr, nullptr, nullptr); ten_extension_tester_set_test_mode_single( tester, "standalone_test_basic_c__test_extension_1", nullptr); diff --git a/tests/ten_runtime/smoke/standalone_test/on_cmd_c.cc b/tests/ten_runtime/smoke/standalone_test/on_cmd_c.cc index 6109b4a5b8..ec2bacc214 100644 --- a/tests/ten_runtime/smoke/standalone_test/on_cmd_c.cc +++ b/tests/ten_runtime/smoke/standalone_test/on_cmd_c.cc @@ -107,8 +107,8 @@ void ten_extension_tester_on_cmd(TEN_UNUSED ten_extension_tester_t *tester, TEST(StandaloneTest, OnCmdC) { // NOLINT ten_extension_tester_t *tester = ten_extension_tester_create( - ten_extension_tester_on_start, ten_extension_tester_on_cmd, nullptr, - nullptr, nullptr); + ten_extension_tester_on_start, nullptr, ten_extension_tester_on_cmd, + nullptr, nullptr, nullptr); ten_extension_tester_set_test_mode_single( tester, "standalone_test_on_cmd_c__test_extension_1", nullptr);