• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

TEN-framework / ten-framework / 20163117177

12 Dec 2025 09:59AM UTC coverage: 55.763% (-0.004%) from 55.767%
20163117177

push

github

web-flow
fix: make sure log completed when python extensions crash (#1867)

* fix: make sure log completed when python extensions crash

* fix: refine code

---------

Co-authored-by: Hu Yueh-Wei <wei.hu.tw@gmail.com>

32 of 48 new or added lines in 2 files covered. (66.67%)

23 existing lines in 4 files now uncovered.

45896 of 82305 relevant lines covered (55.76%)

872475.56 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

77.06
/core/src/ten_runtime/binding/python/native/test/env_tester/env_tester_log.c
1
//
2
// Copyright © 2025 Agora
3
// This file is part of TEN Framework, an open source project.
4
// Licensed under the Apache License, Version 2.0, with certain conditions.
5
// Refer to the "LICENSE" file in the root directory for more information.
6
//
7
#include "include_internal/ten_runtime/binding/python/common/error.h"
8
#include "include_internal/ten_runtime/binding/python/test/env_tester.h"
9
#include "ten_runtime/common/error_code.h"
10
#include "ten_runtime/test/env_tester.h"
11
#include "ten_runtime/test/env_tester_proxy.h"
12
#include "ten_utils/log/log.h"
13
#include "ten_utils/macro/check.h"
14
#include "ten_utils/macro/mark.h"
15
#include "ten_utils/macro/memory.h"
16

17
typedef struct ten_env_tester_notify_log_ctx_t {
18
  int32_t level;
19
  ten_string_t func_name;
20
  ten_string_t file_name;
21
  size_t line_no;
22
  ten_string_t msg;
23
  ten_string_t category;
24
  ten_event_t *completed;
25
} ten_env_tester_notify_log_ctx_t;
26

27
static ten_env_tester_notify_log_ctx_t *ten_env_tester_notify_log_ctx_create(
28
    int32_t level, const char *func_name, const char *file_name, size_t line_no,
29
    const char *msg, const char *category, bool sync) {
49✔
30
  ten_env_tester_notify_log_ctx_t *ctx =
49✔
31
      TEN_MALLOC(sizeof(ten_env_tester_notify_log_ctx_t));
49✔
32
  TEN_ASSERT(ctx, "Failed to allocate memory.");
49✔
33

34
  ctx->level = level;
49✔
35

36
  if (sync) {
49✔
NEW
37
    ctx->completed = ten_event_create(0, 1);
×
38
  } else {
49✔
39
    ctx->completed = NULL;
49✔
40
  }
49✔
41

42
  if (func_name) {
49✔
43
    ten_string_init_from_c_str_with_size(&ctx->func_name, func_name,
49✔
44
                                         strlen(func_name));
49✔
45
  } else {
49✔
46
    TEN_STRING_INIT(ctx->func_name);
×
47
  }
×
48

49
  if (file_name) {
49✔
50
    ten_string_init_from_c_str_with_size(&ctx->file_name, file_name,
49✔
51
                                         strlen(file_name));
49✔
52
  } else {
49✔
53
    TEN_STRING_INIT(ctx->file_name);
×
54
  }
×
55

56
  ctx->line_no = line_no;
49✔
57

58
  if (msg) {
49✔
59
    ten_string_init_from_c_str_with_size(&ctx->msg, msg, strlen(msg));
49✔
60
  } else {
49✔
61
    TEN_STRING_INIT(ctx->msg);
×
62
  }
×
63

64
  if (category) {
49✔
65
    ten_string_init_from_c_str_with_size(&ctx->category, category,
1✔
66
                                         strlen(category));
1✔
67
  } else {
48✔
68
    TEN_STRING_INIT(ctx->category);
48✔
69
  }
48✔
70

71
  return ctx;
49✔
72
}
49✔
73

74
static void ten_env_tester_notify_log_ctx_destroy(
75
    ten_env_tester_notify_log_ctx_t *ctx) {
49✔
76
  TEN_ASSERT(ctx, "Invalid argument.");
49✔
77

78
  ten_string_deinit(&ctx->func_name);
49✔
79
  ten_string_deinit(&ctx->file_name);
49✔
80
  ten_string_deinit(&ctx->msg);
49✔
81
  ten_string_deinit(&ctx->category);
49✔
82

83
  if (ctx->completed) {
49✔
NEW
84
    ten_event_destroy(ctx->completed);
×
NEW
85
    ctx->completed = NULL;
×
NEW
86
  }
×
87

88
  TEN_FREE(ctx);
49✔
89
}
49✔
90

91
static void ten_py_ten_env_tester_log_proxy_notify(
92
    ten_env_tester_t *ten_env_tester, void *user_data) {
49✔
93
  ten_env_tester_notify_log_ctx_t *ctx = user_data;
49✔
94
  TEN_ASSERT(ctx, "Should not happen.");
49✔
95

96
  ten_env_tester_log(ten_env_tester, ctx->level,
49✔
97
                     ten_string_get_raw_str(&ctx->func_name),
49✔
98
                     ten_string_get_raw_str(&ctx->file_name), ctx->line_no,
49✔
99
                     ten_string_get_raw_str(&ctx->msg),
49✔
100
                     ten_string_get_raw_str(&ctx->category), NULL, NULL);
49✔
101

102
  if (ctx->completed) {
49✔
NEW
103
    ten_event_set(ctx->completed);
×
104
  } else {
49✔
105
    ten_env_tester_notify_log_ctx_destroy(ctx);
49✔
106
  }
49✔
107
}
49✔
108

109
PyObject *ten_py_ten_env_tester_log(PyObject *self, TEN_UNUSED PyObject *args) {
50✔
110
  ten_py_ten_env_tester_t *py_ten_env_tester = (ten_py_ten_env_tester_t *)self;
50✔
111
  TEN_ASSERT(py_ten_env_tester &&
50✔
112
                 ten_py_ten_env_tester_check_integrity(py_ten_env_tester),
50✔
113
             "Invalid argument.");
50✔
114

115
  if (PyTuple_GET_SIZE(args) != 7) {
50✔
116
    return ten_py_raise_py_value_error_exception(
×
117
        "Invalid argument count when ten_env.log.");
×
118
  }
×
119

120
  TEN_LOG_LEVEL level = TEN_LOG_LEVEL_INVALID;
50✔
121
  const char *func_name = NULL;
50✔
122
  const char *file_name = NULL;
50✔
123
  size_t line_no = 0;
50✔
124
  const char *category = NULL;
50✔
125
  const char *msg = NULL;
50✔
126
  bool sync = false;
50✔
127

128
  if (!PyArg_ParseTuple(args, "izzizsb", &level, &func_name, &file_name,
50✔
129
                        &line_no, &category, &msg, &sync)) {
50✔
130
    return ten_py_raise_py_value_error_exception(
×
131
        "Failed to parse argument when ten_env.log.");
×
132
  }
×
133

134
  ten_error_t err;
50✔
135
  TEN_ERROR_INIT(err);
50✔
136

137
  if (!py_ten_env_tester->c_ten_env_tester_proxy) {
50✔
138
    ten_error_set(&err, TEN_ERROR_CODE_TEN_IS_CLOSED,
1✔
139
                  "ten_env_tester.log() failed because ten is closed.");
1✔
140
    PyObject *result = (PyObject *)ten_py_error_wrap(&err);
1✔
141
    ten_error_deinit(&err);
1✔
142
    return result;
1✔
143
  }
1✔
144

145
  ten_env_tester_notify_log_ctx_t *ctx = ten_env_tester_notify_log_ctx_create(
49✔
146
      level, func_name, file_name, line_no, msg, category, sync);
49✔
147

148
  if (!ten_env_tester_proxy_notify(py_ten_env_tester->c_ten_env_tester_proxy,
49✔
149
                                   ten_py_ten_env_tester_log_proxy_notify, ctx,
49✔
150
                                   &err)) {
49✔
151
    PyObject *result = (PyObject *)ten_py_error_wrap(&err);
×
152
    ten_error_deinit(&err);
×
153
    ten_env_tester_notify_log_ctx_destroy(ctx);
×
154
    return result;
×
155
  }
×
156

157
  if (sync) {
49✔
NEW
158
    ten_event_wait(ctx->completed, -1);
×
NEW
159
    ten_env_tester_notify_log_ctx_destroy(ctx);
×
NEW
160
  }
×
161

162
  ten_error_deinit(&err);
49✔
163

164
  Py_RETURN_NONE;
49✔
165
}
49✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc