Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: enable cpp extension standalone test case #64

Merged
merged 15 commits into from
Oct 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,3 @@ TEN_RUNTIME_PRIVATE_API PyGILState_STATE ten_py_gil_state_ensure(void);
TEN_RUNTIME_PRIVATE_API void ten_py_gil_state_release(PyGILState_STATE state);

TEN_RUNTIME_PRIVATE_API bool ten_py_is_holding_gil(void);

TEN_RUNTIME_PRIVATE_API PyThreadState *ten_py_gil_state_get_this_thread_state(
void);
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
// Do not enable the debugging facility in Python even if TEN runtime is built
// in the debug mode.
#ifdef _DEBUG
#undef _DEBUG
#include <Python.h> // IWYU pragma: always_keep
#define _DEBUG
#undef _DEBUG
#include <Python.h> // IWYU pragma: always_keep
#define _DEBUG
#else
#include <Python.h> // IWYU pragma: always_keep
#include <Python.h> // IWYU pragma: always_keep
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ typedef struct ten_py_extension_t {
ten_signature_t signature;
ten_extension_t *c_extension;

// Companion TEN object, the actual type is ten_py_ten_env_t.
// Companion ten_env object, the actual type is ten_py_ten_env_t.
PyObject *py_ten_env;
} ten_py_extension_t;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#include "include_internal/ten_runtime/ten_env_proxy/ten_env_proxy.h"
#include "ten_runtime/ten_env/ten_env.h"

#define TEN_PY_TEN_SIGNATURE 0xCCCC1DD4BB4CA743U
#define TEN_PY_TEN_ENV_SIGNATURE 0xCCCC1DD4BB4CA743U

typedef struct ten_py_ten_env_t {
PyObject_HEAD
Expand All @@ -33,7 +33,8 @@ TEN_RUNTIME_PRIVATE_API bool ten_py_ten_env_check_integrity(

TEN_RUNTIME_PRIVATE_API PyTypeObject *ten_py_ten_env_type(void);

TEN_RUNTIME_PRIVATE_API ten_py_ten_env_t *ten_py_ten_wrap(ten_env_t *ten_env);
TEN_RUNTIME_PRIVATE_API ten_py_ten_env_t *ten_py_ten_env_wrap(
ten_env_t *ten_env);

TEN_RUNTIME_PRIVATE_API void ten_py_ten_env_invalidate(
ten_py_ten_env_t *py_ten);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//
// 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.
//
#pragma once

#include "ten_runtime/ten_config.h"

#include <stdbool.h>

#include "include_internal/ten_runtime/binding/python/common/python_stuff.h"
#include "include_internal/ten_runtime/test/env_tester.h"
#include "ten_utils/lib/signature.h"

#define TEN_PY_TEN_ENV_TESTER_SIGNATURE 0x9DF807EAFAF9F6D5U

typedef struct ten_py_ten_env_tester_t {
PyObject_HEAD

ten_signature_t signature;

ten_env_tester_t *c_ten_env_tester;
PyObject *actual_py_ten_env_tester;
} ten_py_ten_env_tester_t;

TEN_RUNTIME_PRIVATE_API PyTypeObject *ten_py_ten_env_tester_py_type(void);

TEN_RUNTIME_PRIVATE_API bool ten_py_ten_env_tester_init_for_module(
PyObject *module);

TEN_RUNTIME_PRIVATE_API ten_py_ten_env_tester_t *ten_py_ten_env_tester_wrap(
ten_env_tester_t *ten_env_tester);

TEN_RUNTIME_PRIVATE_API void ten_py_ten_env_tester_invalidate(
ten_py_ten_env_tester_t *py_ten);

TEN_RUNTIME_PRIVATE_API PyTypeObject *ten_py_ten_env_tester_type(void);

TEN_RUNTIME_PRIVATE_API PyObject *ten_py_ten_env_tester_on_start_done(
PyObject *self, PyObject *args);

TEN_RUNTIME_PRIVATE_API PyObject *ten_py_ten_env_tester_stop_test(
PyObject *self, PyObject *args);

TEN_RUNTIME_PRIVATE_API PyObject *ten_py_ten_env_tester_send_cmd(
PyObject *self, PyObject *args);

TEN_RUNTIME_PRIVATE_API bool ten_py_ten_env_tester_check_integrity(
ten_py_ten_env_tester_t *self);
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//
// 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.
//
#pragma once

#include "ten_runtime/ten_config.h"

#include <stdbool.h>

#include "include_internal/ten_runtime/binding/python/common/python_stuff.h"
#include "include_internal/ten_runtime/test/extension_tester.h"
#include "ten_utils/lib/signature.h"

#define TEN_PY_EXTENSION_TESTER_SIGNATURE 0x2B343E0B87397B5FU

typedef struct ten_py_extension_tester_t {
PyObject_HEAD
ten_signature_t signature;
ten_extension_tester_t *c_extension_tester;

// Companion ten_env_tester object, the actual type is
// ten_py_ten_env_tester_t.
PyObject *py_ten_env_tester;
} ten_py_extension_tester_t;

TEN_RUNTIME_PRIVATE_API PyTypeObject *ten_py_extension_tester_py_type(void);

TEN_RUNTIME_API bool ten_py_extension_tester_init_for_module(PyObject *module);
6 changes: 3 additions & 3 deletions core/include_internal/ten_runtime/ten_env/ten_env.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ typedef struct ten_engine_t ten_engine_t;
typedef void (*ten_close_handler_in_target_lang_func_t)(
void *me_in_target_lang);

typedef void (*ten_destroy_handler_in_target_lang_func_t)(
typedef void (*ten_env_destroy_handler_in_target_lang_func_t)(
void *me_in_target_lang);

typedef enum TEN_CATEGORY {
Expand Down Expand Up @@ -69,7 +69,7 @@ typedef struct ten_env_t {
} attached_target;

ten_close_handler_in_target_lang_func_t close_handler;
ten_destroy_handler_in_target_lang_func_t destroy_handler;
ten_env_destroy_handler_in_target_lang_func_t destroy_handler;

ten_list_t ten_proxy_list;
} ten_env_t;
Expand All @@ -96,7 +96,7 @@ TEN_RUNTIME_API void ten_env_set_close_handler_in_target_lang(
ten_env_t *self, ten_close_handler_in_target_lang_func_t handler);

TEN_RUNTIME_API void ten_env_set_destroy_handler_in_target_lang(
ten_env_t *self, ten_destroy_handler_in_target_lang_func_t handler);
ten_env_t *self, ten_env_destroy_handler_in_target_lang_func_t handler);

TEN_RUNTIME_API TEN_ENV_ATTACH_TO ten_env_get_attach_to(ten_env_t *self);

Expand Down
15 changes: 15 additions & 0 deletions core/include_internal/ten_runtime/test/env_tester.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,38 @@
// Licensed under the Apache License, Version 2.0, with certain conditions.
// Refer to the "LICENSE" file in the root directory for more information.
//
#pragma once

#include "ten_runtime/ten_config.h"

#include <stdbool.h>

#include "include_internal/ten_runtime/binding/common.h"
#include "ten_utils/lib/signature.h"

#define TEN_ENV_TESTER_SIGNATURE 0x66C619FBA7DC8BD9U

typedef struct ten_extension_tester_t ten_extension_tester_t;

typedef void (*ten_env_tester_destroy_handler_in_target_lang_func_t)(
void *me_in_target_lang);

typedef struct ten_env_tester_t {
ten_binding_handle_t binding_handle;

ten_signature_t signature;
ten_extension_tester_t *tester;

ten_env_tester_destroy_handler_in_target_lang_func_t destroy_handler;
} ten_env_tester_t;

TEN_RUNTIME_API bool ten_env_tester_check_integrity(ten_env_tester_t *self);

TEN_RUNTIME_PRIVATE_API ten_env_tester_t *ten_env_tester_create(
ten_extension_tester_t *tester);

TEN_RUNTIME_PRIVATE_API void ten_env_tester_destroy(ten_env_tester_t *self);

TEN_RUNTIME_API void ten_env_tester_set_destroy_handler_in_target_lang(
ten_env_tester_t *self,
ten_env_tester_destroy_handler_in_target_lang_func_t handler);
4 changes: 3 additions & 1 deletion core/include_internal/ten_runtime/test/extension_tester.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
// Licensed under the Apache License, Version 2.0, with certain conditions.
// Refer to the "LICENSE" file in the root directory for more information.
//
#pragma once

#include "ten_runtime/ten_config.h"

#include "include_internal/ten_runtime/binding/common.h"
Expand Down Expand Up @@ -42,7 +44,7 @@ struct ten_extension_tester_t {
void *user_data;
};

TEN_RUNTIME_PRIVATE_API bool ten_extension_tester_check_integrity(
TEN_RUNTIME_API bool ten_extension_tester_check_integrity(
ten_extension_tester_t *self, bool check_thread);

TEN_RUNTIME_PRIVATE_API void test_app_ten_env_send_cmd(ten_env_t *ten_env,
Expand Down
2 changes: 2 additions & 0 deletions core/include_internal/ten_runtime/test/test_app.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
// Licensed under the Apache License, Version 2.0, with certain conditions.
// Refer to the "LICENSE" file in the root directory for more information.
//
#pragma once

#include "ten_runtime/ten_config.h"

TEN_RUNTIME_PRIVATE_API void *ten_builtin_tester_app_thread_main(void *args);
2 changes: 2 additions & 0 deletions core/include_internal/ten_runtime/test/test_extension.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
// Licensed under the Apache License, Version 2.0, with certain conditions.
// Refer to the "LICENSE" file in the root directory for more information.
//
#pragma once

#include "ten_runtime/ten_config.h"

TEN_RUNTIME_PRIVATE_API void ten_builtin_tester_extension_addon_register(void);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from .audio_frame import AudioFrame, AudioFrameDataFmt
from .data import Data
from .log_level import LogLevel
from .test import ExtensionTester, TenEnvTester

# Specify what should be imported when a user imports * from the
# ten_runtime_python package.
Expand All @@ -37,4 +38,6 @@
"PixelFmt",
"AudioFrameDataFmt",
"LogLevel",
"ExtensionTester",
"TenEnvTester",
]
Original file line number Diff line number Diff line change
Expand Up @@ -155,5 +155,15 @@ class _Addon:
self, ten_env: _TenEnv, name: str, context
) -> None: ...

class _TenEnvTester:
def on_start_done(self) -> None: ...
def send_cmd(self, cmd: _Cmd, result_handler) -> None: ...
def stop_test(self) -> None: ...

class _ExtensionTester:
def add_addon_base_dir(self, base_dir: str) -> None: ...
def set_test_mode_single(self, addon_name: str) -> None: ...
def run(self) -> None: ...

def _register_addon_as_extension(name: str, base_dir: str | None): ...
def _register_addon_as_extension_group(name: str, base_dir: str | None): ...
54 changes: 54 additions & 0 deletions core/src/ten_runtime/binding/python/interface/ten/test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#
# 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 typing import Callable, final
from libten_runtime_python import _ExtensionTester, _TenEnvTester
from .cmd import Cmd
from .cmd_result import CmdResult


class TenEnvTester: ... # type: ignore


ResultHandler = Callable[[TenEnvTester, CmdResult], None] | None


class TenEnvTester:

def __init__(self, internal_obj: _TenEnvTester) -> None:
self._internal = internal_obj

def __del__(self) -> None:
pass

def on_start_done(self) -> None:
return self._internal.on_start_done()

def send_cmd(self, cmd: Cmd, result_handler: ResultHandler) -> None:
return self._internal.send_cmd(cmd, result_handler)

def stop_test(self) -> None:
return self._internal.stop_test()


class ExtensionTester(_ExtensionTester):
@final
def add_addon_base_dir(self, base_dir: str) -> None:
return _ExtensionTester.add_addon_base_dir(self, base_dir)

@final
def set_test_mode_single(self, addon_name: str) -> None:
return _ExtensionTester.set_test_mode_single(self, addon_name)

@final
def run(self) -> None:
return _ExtensionTester.run(self)

def on_start(self, ten_env_tester: TenEnvTester) -> None:
ten_env_tester.on_start_done()

def on_cmd(self, ten_env_tester: TenEnvTester, cmd: Cmd) -> None:
pass
1 change: 1 addition & 0 deletions core/src/ten_runtime/binding/python/native/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ ten_shared_library("ten_runtime_python") {
"extension",
"msg",
"ten_env",
"test",
"//core/src/ten_runtime:ten_runtime_library",
]
}
14 changes: 11 additions & 3 deletions core/src/ten_runtime/binding/python/native/addon/addon.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,11 @@ static void proxy_on_init(ten_addon_t *addon, ten_env_t *ten_env) {
TEN_ASSERT(ten_env && ten_env_check_integrity(ten_env, true),
"Invalid argument.");

// About to call the Python function, so it's necessary to ensure that the GIL
// has been acquired.
PyGILState_STATE prev_state = ten_py_gil_state_ensure();

ten_py_ten_env_t *py_ten_env = ten_py_ten_wrap(ten_env);
ten_py_ten_env_t *py_ten_env = ten_py_ten_env_wrap(ten_env);
if (!py_ten_env) {
TEN_ASSERT(0, "Failed to wrap ten.");
goto done;
Expand Down Expand Up @@ -97,9 +99,11 @@ static void proxy_on_deinit(ten_addon_t *addon, ten_env_t *ten_env) {
TEN_ASSERT(ten_env && ten_env_check_integrity(ten_env, true),
"Invalid argument.");

// About to call the Python function, so it's necessary to ensure that the GIL
// has been acquired.
PyGILState_STATE prev_state = ten_py_gil_state_ensure();

ten_py_ten_env_t *py_ten_env = ten_py_ten_wrap(ten_env);
ten_py_ten_env_t *py_ten_env = ten_py_ten_env_wrap(ten_env);
if (!py_ten_env) {
TEN_ASSERT(0, "Failed to wrap ten.");
goto done;
Expand Down Expand Up @@ -143,6 +147,8 @@ static void proxy_on_create_instance_async(ten_addon_t *addon,
TEN_ASSERT(py_addon && ten_py_addon_check_integrity(py_addon),
"Should not happen.");

// About to call the Python function, so it's necessary to ensure that the GIL
// has been acquired.
PyGILState_STATE prev_state = ten_py_gil_state_ensure();

if (!py_addon || !name || !strlen(name)) {
Expand All @@ -153,7 +159,7 @@ static void proxy_on_create_instance_async(ten_addon_t *addon,
goto done;
}

ten_py_ten_env_t *py_ten_env = ten_py_ten_wrap(ten_env);
ten_py_ten_env_t *py_ten_env = ten_py_ten_env_wrap(ten_env);
if (!py_ten_env) {
TEN_ASSERT(0, "Failed to wrap ten.");
goto done;
Expand Down Expand Up @@ -191,6 +197,8 @@ static void proxy_on_destroy_instance_async(ten_addon_t *addon,
TEN_ASSERT(py_addon && ten_py_addon_check_integrity(py_addon),
"Should not happen.");

// About to call the Python function, so it's necessary to ensure that the GIL
// has been acquired.
PyGILState_STATE prev_state = ten_py_gil_state_ensure();

switch (py_addon->type) {
Expand Down
Loading
Loading