1/*
2 * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http:// www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "test.h"
17
18#include <chrono>
19#include <thread>
20#include <uv.h>
21
22#include "event_runner.h"
23#include "napi/native_api.h"
24#include "napi/native_node_api.h"
25#include "securec.h"
26#include "utils/log.h"
27
28struct CallJsCbData_t {
29    int32_t id = 0;
30    bool secondaryThread = false;
31    napi_threadsafe_function_call_mode blockOnFull = napi_tsfn_nonblocking;
32};
33
34struct FinalCbData_t {
35    int32_t id = 0;
36};
37
38struct CallbackData {
39    napi_threadsafe_function tsfn;
40    napi_async_work work;
41    napi_task_priority priority;
42};
43
44static constexpr int32_t SEND_DATA_TEST = 11;
45static constexpr int32_t CALL_JS_CB_DATA_TEST_ID = 101;
46static constexpr int32_t FINAL_CB_DATA_TEST_ID = 1001;
47static constexpr int32_t SEND_DATAS_LENGTH = 10;
48static constexpr int32_t THREAD_COUNT = 2;
49static constexpr int32_t THREAD_COUNT_FOUR = 4;
50static constexpr int32_t MAX_QUEUE_SIZE = 3;
51static constexpr int32_t SUCCESS_COUNT_JS_FOUR = 4;
52static constexpr int32_t CALL_THREAD_SAFE_SLEEP = 2; // 2s
53static constexpr int32_t FIRST_TASK_SLEEP = 4; // 4s
54static constexpr int32_t INVALID_NAPI_THREAD_SAFE_PRIORITY = -1;
55static constexpr int32_t ADD_FIRST_NUMBER = 1;
56static constexpr int32_t ADD_SECOND_NUMBER = 2;
57static constexpr int32_t ADD_SUMMARY_RESULT = 3;
58static constexpr int32_t ARGS_SIZE = 2;
59static constexpr int32_t FIRST_RECEIVER = 1;
60static constexpr int32_t SECOND_RECEIVER = 2;
61static constexpr int32_t THIRD_RECEIVER = 3;
62static constexpr int32_t FOURTH_RECEIVER = 4;
63static constexpr int32_t FIFTH_RECEIVER = 5;
64static constexpr int32_t DATA_LENGTH = 40;
65static constexpr int32_t THREAD_SIZE = 5;
66static constexpr int32_t FIRST_THREAD_INDEX = 0;
67static constexpr int32_t SECOND_THREAD_INDEX = 1;
68static constexpr int32_t THIRD_THREAD_INDEX = 2;
69static constexpr int32_t FOURTH_THREAD_INDEX = 3;
70static constexpr int32_t FIFTH_THREAD_INDEX = 4;
71
72static pid_t g_mainTid = 0;
73static CallJsCbData_t g_jsData;
74static CallJsCbData_t g_jsDataInternal;
75static FinalCbData_t g_finalData;
76static int32_t g_sendData = 0;
77static uv_thread_t g_uvThread;
78static uv_thread_t g_uvThreadTest5;
79static uv_thread_t g_uvThreadTest6;
80static uv_thread_t g_uvThreadTest7;
81static uv_thread_t g_uvThreadSecondary;
82static uv_thread_t g_uvTheads2;
83static uv_thread_t g_uvTheads3;
84static int32_t g_sendDatas[SEND_DATAS_LENGTH];
85static int32_t  g_callSuccessCount = 0;
86static int32_t  g_callSuccessCountJS = 0;
87static int32_t  g_callSuccessCountJSFour = 0;
88static int32_t  g_callDepth = 4;
89bool acquireFlag = false;
90static int32_t g_receiveCnt = 0;
91static bool g_isTailA = false;
92static bool g_isTailB = false;
93
94static void TsFuncCallJs(napi_env env, napi_value tsfn_cb, void* context, void* data)
95{
96    HILOG_INFO("TsFuncCallJs called");
97
98    EXPECT_EQ(gettid(), g_mainTid);
99
100    // expect context equal
101    EXPECT_EQ(((CallJsCbData_t*)context)->id, CALL_JS_CB_DATA_TEST_ID);
102
103    // expect data equal
104    int* pData = (int32_t*)data;
105    EXPECT_EQ((*pData), SEND_DATA_TEST);
106}
107
108static void TsFuncCallJsWithNewCall(napi_env env, napi_value tsfn_cb, void* context, void* data)
109{
110    HILOG_INFO("TsFuncCallJsWithNewCall called");
111    EXPECT_EQ(gettid(), g_mainTid);
112
113    // expect context equal
114    EXPECT_EQ(((CallJsCbData_t*)context)->id, CALL_JS_CB_DATA_TEST_ID);
115
116    napi_threadsafe_function tsFunc = (napi_threadsafe_function)data;
117
118    if (g_callDepth > 0) {
119        g_callDepth--;
120        auto status = napi_call_threadsafe_function(tsFunc, data, napi_tsfn_nonblocking);
121        EXPECT_EQ(status, napi_ok);
122    }
123    if (g_callDepth == 0) {
124        auto status = napi_release_threadsafe_function(tsFunc, napi_tsfn_release);
125        EXPECT_EQ(status, napi_ok);
126    }
127}
128
129static void TsFuncCallJsTwo(napi_env env, napi_value tsfn_cb, void* context, void* data)
130{
131    HILOG_INFO("TsFuncCallJsTwo called");
132    TsFuncCallJs(env, tsfn_cb, context, data);
133    g_callSuccessCountJS++;
134}
135static void TsFuncCallJsFour(napi_env env, napi_value tsfn_cb, void* context, void* data)
136{
137    HILOG_INFO("TsFuncCallJsFour called");
138
139    TsFuncCallJs(env, tsfn_cb, context, data);
140    g_callSuccessCountJSFour++;
141}
142static void TsFuncCallJsMulti(napi_env env,
143                              napi_value tsfn_cb,
144                              void* context,
145                              void* data)
146{
147    HILOG_INFO("TsFuncCallJsMulti called");
148
149    EXPECT_EQ(gettid(), g_mainTid);
150
151    // expect context equal
152    EXPECT_EQ(((CallJsCbData_t*)context)->id, CALL_JS_CB_DATA_TEST_ID);
153
154    int* pData = ((int32_t*)data);
155
156    HILOG_INFO("TsFuncCallJsMulti data %d", (*pData));
157}
158
159static void TsFuncFinal(napi_env env, void* finalizeData, void* hint)
160{
161    HILOG_INFO("TsFuncFinal called");
162
163    // expect thread id equal
164    EXPECT_EQ(gettid(), g_mainTid);
165
166    // wait data source thread
167    uv_thread_join(&g_uvThread);
168
169    // expect context equal
170    EXPECT_EQ(((CallJsCbData_t*)hint)->id, CALL_JS_CB_DATA_TEST_ID);
171
172    // expect finalize data equal
173    EXPECT_EQ(((FinalCbData_t*)finalizeData)->id, FINAL_CB_DATA_TEST_ID);
174}
175static void TsFuncFinalTest5(napi_env env, void* finalizeData, void* hint)
176{
177    HILOG_INFO("TsFuncFinalTest5 called");
178
179    // expect thread id equal
180    EXPECT_EQ(gettid(), g_mainTid);
181
182    // wait data source thread
183    uv_thread_join(&g_uvThreadTest5);
184
185    // expect context equal
186    EXPECT_EQ(((CallJsCbData_t*)hint)->id, CALL_JS_CB_DATA_TEST_ID);
187
188    // expect finalize data equal
189    EXPECT_EQ(((FinalCbData_t*)finalizeData)->id, FINAL_CB_DATA_TEST_ID);
190}
191static void TsFuncFinalTotal(napi_env env, void* finalizeData, void* hint)
192{
193    HILOG_INFO("TsFuncFinalTotal called");
194    uv_thread_join(&g_uvThreadTest6);
195    // when add thread,repair  g_callSuccessCountJS eq  SUCCESS_COUNT_JS_TWO
196    EXPECT_EQ(g_callSuccessCountJS, SUCCESS_COUNT_JS_FOUR);
197    HILOG_INFO("TsFuncFinalTotal end");
198}
199static void TsFuncFinalTotalFour(napi_env env, void* finalizeData, void* hint)
200{
201    HILOG_INFO("TsFuncFinalTotalFour called");
202    uv_thread_join(&g_uvThreadTest7);
203    EXPECT_EQ(g_callSuccessCountJSFour, SUCCESS_COUNT_JS_FOUR);
204    HILOG_INFO("TsFuncFinalTotalFour end");
205}
206static void TsFuncFinalCallback(napi_env env, void* finalizeData, void* hint)
207{
208    HILOG_INFO("TsFuncFinalCallback called");
209    EXPECT_EQ(g_callSuccessCountJSFour, SUCCESS_COUNT_JS_FOUR);
210    HILOG_INFO("TsFuncFinalCallback end");
211}
212
213static void TsFuncFinalJoinThread(napi_env env, void* data, void* hint)
214{
215    HILOG_INFO("TsFuncFinalJoinThread called");
216
217    uv_thread_t *uvThread = reinterpret_cast<uv_thread_t*>(data);
218    CallJsCbData_t *jsData = reinterpret_cast<CallJsCbData_t*>(hint);
219
220    uv_thread_join(uvThread);
221
222    if (jsData->secondaryThread) {
223        uv_thread_join(&g_uvThreadSecondary);
224    }
225}
226
227static void TsFuncSecondaryThread(void* data)
228{
229    HILOG_INFO("TsFuncSecondaryThread called");
230
231    // expect thread id not equal
232    EXPECT_NE(gettid(), g_mainTid);
233
234    napi_threadsafe_function func = (napi_threadsafe_function)data;
235
236    auto status = napi_release_threadsafe_function(func, napi_tsfn_release);
237    EXPECT_EQ(status, napi_ok);
238}
239
240static void TsFuncDataSourceThread(void* data)
241{
242    HILOG_INFO("TsFuncDataSourceThread called");
243
244    // expect thread id not equal
245    EXPECT_NE(gettid(), g_mainTid);
246
247    napi_threadsafe_function func = (napi_threadsafe_function)data;
248    napi_threadsafe_function_call_mode blockMode = napi_tsfn_nonblocking;
249    void* context = nullptr;
250
251    auto status = napi_get_threadsafe_function_context(func, &context);
252    EXPECT_EQ(status, napi_ok);
253
254    // expect context equal
255    EXPECT_EQ(((CallJsCbData_t*)context)->id, CALL_JS_CB_DATA_TEST_ID);
256
257    // set send data
258    g_sendData = SEND_DATA_TEST;
259
260    // As main thread has set initial_thread_count to 1 and only this one secondary thread,
261    // so no need to call `napi_acquire_threadsafe_function()`.
262    status = napi_call_threadsafe_function(func, &g_sendData, blockMode);
263    EXPECT_EQ(status, napi_ok);
264
265    status = napi_release_threadsafe_function(func, napi_tsfn_release);
266    EXPECT_EQ(status, napi_ok);
267}
268static void TsFuncDataSourceThreadAbort(void* data)
269{
270    HILOG_INFO("TsFuncDataSourceThreadAbort called");
271
272    // expect thread id not equal
273    EXPECT_NE(gettid(), g_mainTid);
274
275    napi_threadsafe_function func = (napi_threadsafe_function)data;
276    napi_threadsafe_function_call_mode blockMode = napi_tsfn_nonblocking;
277    void* context = nullptr;
278
279    auto status = napi_get_threadsafe_function_context(func, &context);
280    EXPECT_EQ(status, napi_ok);
281
282    // expect context equal
283    EXPECT_EQ(((CallJsCbData_t*)context)->id, CALL_JS_CB_DATA_TEST_ID);
284
285    // set send data
286    g_sendData = SEND_DATA_TEST;
287
288    status = napi_call_threadsafe_function(func, &g_sendData, blockMode);
289    EXPECT_EQ(status, napi_closing);
290}
291
292static void TsFuncDataSourceThreadCountTotal(void* data)
293{
294    HILOG_INFO("TsFuncDataSourceThreadCountTotal called");
295
296    // expect thread id not equal
297    EXPECT_NE(gettid(), g_mainTid);
298
299    napi_threadsafe_function func = (napi_threadsafe_function)data;
300    napi_threadsafe_function_call_mode blockMode = napi_tsfn_nonblocking;
301    void* context = nullptr;
302
303    auto status = napi_get_threadsafe_function_context(func, &context);
304    EXPECT_EQ(status, napi_ok);
305
306    // expect context equal
307    EXPECT_EQ(((CallJsCbData_t*)context)->id, CALL_JS_CB_DATA_TEST_ID);
308    // set send data
309    g_sendData = SEND_DATA_TEST;
310    if (acquireFlag) {
311        std::cout<<"acquireFlag  is true"<<std::endl;
312        status = napi_acquire_threadsafe_function(func);
313        EXPECT_EQ(status, napi_ok);
314        status = napi_call_threadsafe_function(func, &g_sendData, blockMode);
315        if (status == napi_ok) {
316            g_callSuccessCount++;
317        }
318        status = napi_release_threadsafe_function(func, napi_tsfn_release);
319    } else {
320        status = napi_call_threadsafe_function(func, &g_sendData, blockMode);
321        if (status == napi_ok) {
322            g_callSuccessCount++;
323        }
324    }
325    status = napi_release_threadsafe_function(func, napi_tsfn_release);
326}
327
328static void TsFuncDataSourceThreadMulti(void* data)
329{
330    HILOG_INFO("TsFuncDataSourceThreadMulti called");
331
332    // expect thread id not equal
333    EXPECT_NE(gettid(), g_mainTid);
334
335    napi_threadsafe_function func =  (napi_threadsafe_function)data;
336    void* context = nullptr;
337
338    auto status = napi_get_threadsafe_function_context(func, &context);
339    EXPECT_EQ(status, napi_ok);
340    CallJsCbData_t* jsData = nullptr;
341    jsData = (CallJsCbData_t*)context;
342
343    if (jsData->secondaryThread) {
344        status = napi_acquire_threadsafe_function(func);
345        EXPECT_EQ(status, napi_ok);
346
347        if (uv_thread_create(&g_uvThreadSecondary, TsFuncSecondaryThread, func) != 0) {
348            HILOG_ERROR("Failed to create uv thread!");
349        }
350    }
351
352    bool queueClosing = false;
353    bool queueFull = false;
354    int32_t index = 0;
355    for (index = SEND_DATAS_LENGTH - 1; index > -1 && !queueClosing; index--) {
356        g_sendDatas[index] = index;
357        status = napi_call_threadsafe_function(func, &g_sendDatas[index], jsData->blockOnFull);
358        HILOG_INFO("napi_call_threadsafe_function index %d status %d", index, status);
359
360        switch (status) {
361            case napi_queue_full:
362                queueFull = true;
363                index++;
364                [[fallthrough]];
365            case napi_ok:
366                continue;
367            case napi_closing:
368                queueClosing = true;
369                break;
370            default:
371                HILOG_ERROR("Failed to call napi_call_threadsafe_function!");
372        }
373    }
374
375    if (!queueClosing && (napi_release_threadsafe_function(func, napi_tsfn_release) != napi_ok)) {
376        HILOG_ERROR("Failed to call napi_release_threadsafe_function!");
377    }
378}
379
380static void TsFuncThreadInternal(napi_env env,
381                                 napi_threadsafe_function_call_js cb,
382                                 uv_thread_t& uvThread,
383                                 bool secondary,
384                                 bool block)
385{
386    HILOG_INFO("TsFuncThreadInternal start secondary %d block %d", secondary, block);
387
388    napi_threadsafe_function tsFunc = nullptr;
389    napi_value resourceName = 0;
390
391    napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
392    g_mainTid = gettid();
393
394    g_jsDataInternal.id = CALL_JS_CB_DATA_TEST_ID;
395    g_jsDataInternal.secondaryThread = (secondary ? true : false);
396    g_jsDataInternal.blockOnFull = (block ? napi_tsfn_blocking : napi_tsfn_nonblocking);
397
398    auto status = napi_create_threadsafe_function(env,
399                                                  nullptr,
400                                                  nullptr,
401                                                  resourceName,
402                                                  MAX_QUEUE_SIZE,
403                                                  THREAD_COUNT,
404                                                  &uvThread,
405                                                  TsFuncFinalJoinThread,
406                                                  &g_jsDataInternal,
407                                                  cb,
408                                                  &tsFunc);
409    EXPECT_EQ(status, napi_ok);
410
411    if (uv_thread_create(&uvThread, TsFuncDataSourceThreadMulti, tsFunc) != 0) {
412        HILOG_ERROR("Failed to create uv thread!");
413    }
414
415    HILOG_INFO("TsFuncThreadInternal end");
416}
417
418static napi_value JsCallback(napi_env env, napi_callback_info info)
419{
420    size_t agrc = ARGS_SIZE;
421    napi_value argv[ARGS_SIZE] = { nullptr };
422    napi_get_cb_info(env, info, &agrc, argv, nullptr, nullptr);
423
424    int32_t number1 = 0;
425    napi_get_value_int32(env, argv[0], &number1);
426
427    int32_t number2 = 0;
428    napi_get_value_int32(env, argv[1], &number2);
429
430    napi_value result = nullptr;
431    napi_create_int32(env, number1 + number2, &result);
432    return result;
433}
434
435static void CallJsCallback(napi_env env, napi_value jsCb)
436{
437    napi_value undefined;
438    napi_get_undefined(env, &undefined);
439    napi_value numberOne = nullptr;
440    napi_create_int32(env, ADD_FIRST_NUMBER, &numberOne);
441    napi_value numberTwo = nullptr;
442    napi_create_int32(env, ADD_SECOND_NUMBER, &numberTwo);
443    napi_value argv[ARGS_SIZE] = { numberOne, numberTwo };
444
445    napi_value result = nullptr;
446    napi_call_function(env, undefined, jsCb, ARGS_SIZE, argv, &result);
447
448    int32_t res = 0;
449    napi_get_value_int32(env, result, &res);
450    EXPECT_EQ(res, ADD_SUMMARY_RESULT);
451}
452
453static void StopCurrentRunner()
454{
455    auto runner = OHOS::AppExecFwk::EventRunner::Current();
456    if (runner != nullptr) {
457        HILOG_INFO("Stop the current runner!");
458        runner->Stop();
459    }
460}
461
462static void CallJs(napi_env env, napi_value jsCb, void *context, void *data)
463{
464    EXPECT_NE(env, nullptr);
465
466    g_receiveCnt++;
467    if (g_receiveCnt == FIRST_RECEIVER) {
468        std::this_thread::sleep_for(std::chrono::seconds(FIRST_TASK_SLEEP));
469        return;
470    }
471    // check data string
472    char *testData = reinterpret_cast<char *>(data);
473    EXPECT_NE(testData, nullptr) << "testData is nullptr";
474    int32_t ret = 0;
475    if (g_receiveCnt == SECOND_RECEIVER) {
476        if (!g_isTailB) {
477            ret = strcmp(testData, "hello world from B");
478        } else {
479            ret = strcmp(testData, "hello world from A");
480        }
481    }
482    if (g_receiveCnt == THIRD_RECEIVER) {
483        if (!g_isTailB) {
484            ret = strcmp(testData, "hello world from A");
485        } else {
486            ret = strcmp(testData, "hello world from B");
487        }
488    }
489    EXPECT_EQ(ret, 0);
490
491    CallJsCallback(env, jsCb);
492    if (g_receiveCnt == THIRD_RECEIVER) {
493        StopCurrentRunner();
494    }
495}
496
497static void CallJsWithDiffPriority(napi_env env, napi_value jsCb, void *context, void *data)
498{
499    EXPECT_NE(env, nullptr);
500
501    g_receiveCnt++;
502    if (g_receiveCnt == FIRST_RECEIVER) {
503        std::this_thread::sleep_for(std::chrono::seconds(FIRST_TASK_SLEEP));
504        return;
505    }
506    // check data string
507    char *testData = reinterpret_cast<char *>(data);
508    EXPECT_NE(testData, nullptr) << "testData is nullptr";
509    int32_t ret = 0;
510    if (g_receiveCnt == SECOND_RECEIVER) {
511        ret = strcmp(testData, "hello world from A");
512    } else if (g_receiveCnt == THIRD_RECEIVER) {
513        ret = strcmp(testData, "hello world from B");
514    } else if (g_receiveCnt == FOURTH_RECEIVER) {
515        ret = strcmp(testData, "hello world from C");
516    } else if (g_receiveCnt == FIFTH_RECEIVER) {
517        ret = strcmp(testData, "hello world from D");
518    }
519    EXPECT_EQ(ret, 0);
520
521    CallJsCallback(env, jsCb);
522    if (g_receiveCnt == FIFTH_RECEIVER) {
523        StopCurrentRunner();
524    }
525}
526
527class UnitLoopHandler : public OHOS::AppExecFwk::FileDescriptorListener,
528    public std::enable_shared_from_this<UnitLoopHandler> {
529public:
530    explicit UnitLoopHandler(uv_loop_t* uvLoop) : uvLoop_(uvLoop) {}
531    void OnReadable(int32_t) override { uv_run(uvLoop_, UV_RUN_NOWAIT); }
532    void OnWritable(int32_t) override { uv_run(uvLoop_, UV_RUN_NOWAIT); }
533
534private:
535    uv_loop_t* uvLoop_ = nullptr;
536};
537
538class NapiThreadsafeTest : public NativeEngineTest {
539public:
540    static void SetUpTestCase()
541    {
542        GTEST_LOG_(INFO) << "NapiThreadsafeTest SetUpTestCase";
543    }
544
545    static void TearDownTestCase()
546    {
547        GTEST_LOG_(INFO) << "NapiThreadsafeTest TearDownTestCase";
548    }
549
550    void SetUp() override { AttachEventHandler(); }
551    void TearDown() override {}
552
553    void CallThreadSafeWithSamePriorityTest(napi_task_priority priority);
554    void CallThreadSafeWithDiffPriorityTest();
555    void CallThreadSafeWithDiffPriorityMultipleThreadTest();
556    void AttachEventHandler();
557};
558
559void NapiThreadsafeTest::AttachEventHandler()
560{
561    if (eventHandler_ != nullptr) {
562        return;
563    }
564    auto uvLoop = engine_->GetUVLoop();
565    auto fd = uvLoop != nullptr ? uv_backend_fd(uvLoop) : -1;
566    EXPECT_GE(fd, 0);
567    uv_run(uvLoop, UV_RUN_NOWAIT);
568    auto runner = OHOS::AppExecFwk::EventRunner::Create(false);
569    EXPECT_NE(runner, nullptr);
570    eventHandler_ = std::make_shared<OHOS::AppExecFwk::EventHandler>(runner);
571    EXPECT_NE(eventHandler_, nullptr);
572    uint32_t events = OHOS::AppExecFwk::FILE_DESCRIPTOR_INPUT_EVENT | OHOS::AppExecFwk::FILE_DESCRIPTOR_OUTPUT_EVENT;
573    eventHandler_->AddFileDescriptorListener(fd, events, std::make_shared<UnitLoopHandler>(uvLoop), "uvLoopTask");
574    HILOG_INFO("AttachEventHandler is completed!");
575}
576
577static void CallThreadSafeFunc(napi_threadsafe_function tsfn, napi_task_priority priority)
578{
579    char *testData = (char *)malloc(DATA_LENGTH);
580    if (testData == nullptr) {
581        return;
582    }
583    memset_s(testData, DATA_LENGTH, 0, DATA_LENGTH);
584    if (priority == napi_priority_immediate) {
585        strcpy_s(testData, DATA_LENGTH, "hello world from A");
586    } else if (priority == napi_priority_high) {
587        strcpy_s(testData, DATA_LENGTH, "hello world from B");
588    } else if (priority == napi_priority_low) {
589        strcpy_s(testData, DATA_LENGTH, "hello world from C");
590    } else if (priority == napi_priority_idle) {
591        strcpy_s(testData, DATA_LENGTH, "hello world from D");
592    }
593    auto status =
594        napi_call_threadsafe_function_with_priority(tsfn, testData, priority, true);
595    EXPECT_EQ(status, napi_ok);
596}
597
598void NapiThreadsafeTest::CallThreadSafeWithSamePriorityTest(napi_task_priority priority)
599{
600    napi_env env = (napi_env)engine_;
601    napi_value resourceName = 0;
602    napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
603    CallbackData *callbackData = new CallbackData();
604    callbackData->priority = priority;
605    napi_value testFunc = nullptr;
606    napi_create_function(env, "jsCallback", NAPI_AUTO_LENGTH, JsCallback, nullptr, &testFunc);
607
608    auto status = napi_create_threadsafe_function(env, testFunc, nullptr, resourceName,
609        0, 1, callbackData, nullptr, callbackData, CallJs, &callbackData->tsfn);
610    EXPECT_EQ(status, napi_ok);
611
612    g_receiveCnt = 0;
613    napi_create_async_work(
614        env, nullptr, resourceName, [](napi_env env, void* data) {
615            CallbackData* callbackData = (CallbackData*)data;
616            char *testDataA = (char *)malloc(DATA_LENGTH);
617            memset_s(testDataA, DATA_LENGTH, 0, DATA_LENGTH);
618            strcpy_s(testDataA, DATA_LENGTH, "hello world from A");
619
620            char *testDataB = (char *)malloc(DATA_LENGTH);
621            memset_s(testDataB, DATA_LENGTH, 0, DATA_LENGTH);
622            strcpy_s(testDataB, DATA_LENGTH, "hello world from B");
623            // first call function to post a sleep task, then the next execution from event queue which
624            // contains two tasks.
625            auto status =
626                napi_call_threadsafe_function_with_priority(callbackData->tsfn, testDataA, napi_priority_immediate,
627                    true);
628            EXPECT_EQ(status, napi_ok);
629            std::this_thread::sleep_for(std::chrono::seconds(CALL_THREAD_SAFE_SLEEP));
630            status = napi_call_threadsafe_function_with_priority(callbackData->tsfn, testDataA,
631                callbackData->priority, g_isTailA);
632            EXPECT_EQ(status, napi_ok);
633            status = napi_call_threadsafe_function_with_priority(callbackData->tsfn, testDataB,
634                callbackData->priority, g_isTailB);
635            EXPECT_EQ(status, napi_ok);
636        },
637        [](napi_env env, napi_status status, void* data) {
638            CallbackData* callbackData = (CallbackData*)data;
639            napi_delete_async_work(env, callbackData->work);
640            auto status1 = napi_release_threadsafe_function(callbackData->tsfn, napi_tsfn_release);
641            EXPECT_EQ(status1, napi_ok);
642            delete callbackData;
643        },
644        callbackData, &callbackData->work);
645    napi_queue_async_work(env, callbackData->work);
646}
647
648void NapiThreadsafeTest::CallThreadSafeWithDiffPriorityTest()
649{
650    napi_env env = (napi_env)engine_;
651    napi_value resourceName = 0;
652    napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
653    CallbackData *callbackData = new CallbackData();
654    napi_value testFunc = nullptr;
655    napi_create_function(env, "jsCallback", NAPI_AUTO_LENGTH, JsCallback, nullptr, &testFunc);
656
657    auto status = napi_create_threadsafe_function(env, testFunc, nullptr, resourceName,
658        0, 1, callbackData, nullptr, callbackData, CallJsWithDiffPriority, &callbackData->tsfn);
659    EXPECT_EQ(status, napi_ok);
660
661    g_receiveCnt = 0;
662    napi_create_async_work(
663        env, nullptr, resourceName, [](napi_env env, void* data) {
664            CallbackData* callbackData = (CallbackData*)data;
665            // first call function to post a sleep task, then the next execution from event queue which
666            // contains four different priority tasks.
667            auto status =
668                napi_call_threadsafe_function_with_priority(callbackData->tsfn, nullptr, napi_priority_immediate,
669                    true);
670            EXPECT_EQ(status, napi_ok);
671            std::this_thread::sleep_for(std::chrono::seconds(CALL_THREAD_SAFE_SLEEP));
672            CallThreadSafeFunc(callbackData->tsfn, napi_priority_immediate);
673            CallThreadSafeFunc(callbackData->tsfn, napi_priority_high);
674            CallThreadSafeFunc(callbackData->tsfn, napi_priority_low);
675            CallThreadSafeFunc(callbackData->tsfn, napi_priority_idle);
676        },
677        [](napi_env env, napi_status status, void* data) {
678            CallbackData* callbackData = (CallbackData*)data;
679            napi_delete_async_work(env, callbackData->work);
680            auto status1 = napi_release_threadsafe_function(callbackData->tsfn, napi_tsfn_release);
681            EXPECT_EQ(status1, napi_ok);
682            delete callbackData;
683        },
684        callbackData, &callbackData->work);
685    napi_queue_async_work(env, callbackData->work);
686}
687
688void NapiThreadsafeTest::CallThreadSafeWithDiffPriorityMultipleThreadTest()
689{
690    napi_env env = (napi_env)engine_;
691    napi_value resourceName = 0;
692    napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
693    CallbackData *callbackData = new CallbackData();
694    napi_value testFunc = nullptr;
695    napi_create_function(env, "jsCallback", NAPI_AUTO_LENGTH, JsCallback, nullptr, &testFunc);
696
697    auto status = napi_create_threadsafe_function(env, testFunc, nullptr, resourceName,
698        0, 1, callbackData, nullptr, callbackData, CallJsWithDiffPriority, &callbackData->tsfn);
699    EXPECT_EQ(status, napi_ok);
700
701    g_receiveCnt = 0;
702    auto runFunc = [callbackData](const napi_env &env, int32_t threadIndex) {
703        if (threadIndex == FIRST_THREAD_INDEX) {
704            auto status =
705                napi_call_threadsafe_function_with_priority(callbackData->tsfn, nullptr, napi_priority_immediate,
706                    true);
707            EXPECT_EQ(status, napi_ok);
708        } else if (threadIndex == SECOND_THREAD_INDEX) {
709            CallThreadSafeFunc(callbackData->tsfn, napi_priority_immediate);
710        } else if (threadIndex == THIRD_THREAD_INDEX) {
711            CallThreadSafeFunc(callbackData->tsfn, napi_priority_high);
712        } else if (threadIndex == FOURTH_THREAD_INDEX) {
713            CallThreadSafeFunc(callbackData->tsfn, napi_priority_low);
714        } else if (threadIndex == FIFTH_THREAD_INDEX) {
715            CallThreadSafeFunc(callbackData->tsfn, napi_priority_idle);
716        }
717    };
718    std::thread runFirstThread = std::thread(runFunc, std::ref(env), 0);
719    runFirstThread.detach();
720    std::this_thread::sleep_for(std::chrono::seconds(CALL_THREAD_SAFE_SLEEP));
721    for (int32_t index = 1; index < THREAD_SIZE; ++index) {
722        std::thread runThread = std::thread(runFunc, std::ref(env), index);
723        runThread.detach();
724    }
725}
726
727/**
728 * @tc.name: ThreadsafeTest001
729 * @tc.desc: Test LoadModule Func.
730 * @tc.type: FUNC
731 * @tc.require: I5K6KF
732 */
733HWTEST_F(NapiThreadsafeTest, ThreadsafeTest001, testing::ext::TestSize.Level1)
734{
735    HILOG_INFO("Threadsafe_Test_0100 start");
736    napi_env env = (napi_env)engine_;
737    napi_threadsafe_function tsFunc = nullptr;
738    napi_value resourceName = 0;
739
740    napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
741    g_mainTid = gettid();
742    g_jsData.id = CALL_JS_CB_DATA_TEST_ID;
743    g_finalData.id = FINAL_CB_DATA_TEST_ID;
744
745    auto status = napi_create_threadsafe_function(env,
746                                                  nullptr,
747                                                  nullptr,
748                                                  resourceName,
749                                                  0,
750                                                  1,
751                                                  &g_finalData,
752                                                  TsFuncFinal,
753                                                  &g_jsData,
754                                                  TsFuncCallJs,
755                                                  &tsFunc);
756    EXPECT_EQ(status, napi_ok);
757
758    if (uv_thread_create(&g_uvThread, TsFuncDataSourceThread, tsFunc) != 0) {
759        HILOG_ERROR("Failed to create uv thread!");
760    }
761
762    HILOG_INFO("Threadsafe_Test_0100 end");
763}
764
765/**
766 * @tc.name: ThreadsafeTest002
767 * @tc.desc: Test LoadModule Func.
768 * @tc.type: FUNC
769 * @tc.require: I5K6KF
770 */
771HWTEST_F(NapiThreadsafeTest, ThreadsafeTest002, testing::ext::TestSize.Level1)
772{
773    HILOG_INFO("Threadsafe_Test_0200 start");
774
775    // start secondary thread, block on full
776    TsFuncThreadInternal((napi_env)engine_, TsFuncCallJsMulti, g_uvTheads2, true, true);
777
778    HILOG_INFO("Threadsafe_Test_0200 end");
779}
780
781/**
782 * @tc.name: ThreadsafeTest003
783 * @tc.desc: Test threadsafe Func, no js.
784 * @tc.type: FUNC
785 * @tc.require: I5K6KF
786 */
787HWTEST_F(NapiThreadsafeTest, ThreadsafeTest003, testing::ext::TestSize.Level1)
788{
789    HILOG_INFO("Threadsafe_Test_0300 start");
790
791    // secondary thread, not block
792    TsFuncThreadInternal((napi_env)engine_, TsFuncCallJsMulti, g_uvTheads3, false, false);
793
794    HILOG_INFO("Threadsafe_Test_0300 end");
795}
796
797/**
798 * @tc.name: ThreadsafeTest004
799 * @tc.desc: Test napi_release_threadsafe_function, napi_tsfn_abort.
800 * @tc.type: FUNC
801 * @tc.require: I5K6KF
802 */
803HWTEST_F(NapiThreadsafeTest, ThreadsafeTest004, testing::ext::TestSize.Level1)
804{
805    HILOG_INFO("Threadsafe_Test_0400 start");
806    napi_env env = (napi_env)engine_;
807    napi_threadsafe_function tsFunc = nullptr;
808    napi_value resourceName = 0;
809
810    napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
811    g_mainTid = gettid();
812    g_jsData.id = CALL_JS_CB_DATA_TEST_ID;
813    g_finalData.id = FINAL_CB_DATA_TEST_ID;
814
815    auto status = napi_create_threadsafe_function(env,
816                                                  nullptr,
817                                                  nullptr,
818                                                  resourceName,
819                                                  0,
820                                                  10,
821                                                  &g_finalData,
822                                                  TsFuncFinalTest5,
823                                                  &g_jsData,
824                                                  TsFuncCallJs,
825                                                  &tsFunc);
826    EXPECT_EQ(status, napi_ok);
827    status = napi_release_threadsafe_function(tsFunc, napi_tsfn_abort);
828    EXPECT_EQ(status, napi_ok);
829    if (uv_thread_create(&g_uvThreadTest5, TsFuncDataSourceThreadAbort, tsFunc) != 0) {
830        HILOG_ERROR("Failed to create uv thread!");
831    }
832
833    HILOG_INFO("Threadsafe_Test_0400 end");
834}
835
836/**
837 * @tc.name: ThreadsafeTest005
838 * @tc.desc: Test initial_thread_count not enough.
839 * @tc.type: FUNC
840 * @tc.require: I5K6KF
841 */
842HWTEST_F(NapiThreadsafeTest, ThreadsafeTest005, testing::ext::TestSize.Level1)
843{
844    HILOG_INFO("Threadsafe_Test_0500 start");
845    napi_env env = (napi_env)engine_;
846    napi_threadsafe_function tsFunc = nullptr;
847    napi_value resourceName = 0;
848    g_callSuccessCountJS = 0;
849    g_callSuccessCount = 0;
850    napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
851    g_mainTid = gettid();
852    g_jsData.id = CALL_JS_CB_DATA_TEST_ID;
853    g_finalData.id = FINAL_CB_DATA_TEST_ID;
854
855    auto status = napi_create_threadsafe_function(env,
856                                                  nullptr,
857                                                  nullptr,
858                                                  resourceName,
859                                                  0,
860                                                  2,
861                                                  &g_finalData,
862                                                  TsFuncFinalTotal,
863                                                  &g_jsData,
864                                                  TsFuncCallJsTwo,
865                                                  &tsFunc);
866    EXPECT_EQ(status, napi_ok);
867    int threadCount = THREAD_COUNT_FOUR;
868    acquireFlag = false;
869
870    for (int i = 0; i < threadCount; i++) {
871        if (uv_thread_create(&g_uvThreadTest6, TsFuncDataSourceThreadCountTotal, tsFunc) != 0) {
872            HILOG_ERROR("Failed to create uv thread!");
873        }
874    }
875
876    usleep(200 * 1000);
877    EXPECT_EQ(g_callSuccessCount, SUCCESS_COUNT_JS_FOUR);
878    HILOG_INFO("Threadsafe_Test_0500 end");
879}
880
881/**
882 * @tc.name: ThreadsafeTest006
883 * @tc.desc: Test initial_thread_count not enough but acquire.
884 * @tc.type: FUNC
885 * @tc.require: I5K6KF
886 */
887HWTEST_F(NapiThreadsafeTest, ThreadsafeTest006, testing::ext::TestSize.Level1)
888{
889    HILOG_INFO("Threadsafe_Test_0600 start");
890    napi_env env = (napi_env)engine_;
891    napi_threadsafe_function tsFunc = nullptr;
892    napi_value resourceName = 0;
893    g_callSuccessCount = 0;
894    napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
895    g_mainTid = gettid();
896    g_jsData.id = CALL_JS_CB_DATA_TEST_ID;
897    g_finalData.id = FINAL_CB_DATA_TEST_ID;
898
899    auto status = napi_create_threadsafe_function(env,
900                                                  nullptr,
901                                                  nullptr,
902                                                  resourceName,
903                                                  0,
904                                                  1,
905                                                  &g_finalData,
906                                                  TsFuncFinalTotalFour,
907                                                  &g_jsData,
908                                                  TsFuncCallJsFour,
909                                                  &tsFunc);
910    EXPECT_EQ(status, napi_ok);
911    int threadCount = THREAD_COUNT_FOUR;
912    acquireFlag = true;
913
914    for (int i = 0; i < threadCount; i++) {
915        if (uv_thread_create(&g_uvThreadTest7, TsFuncDataSourceThreadCountTotal, tsFunc) != 0) {
916            HILOG_ERROR("Failed to create uv thread!");
917        }
918    }
919
920    usleep(200 * 1000);
921    EXPECT_EQ(g_callSuccessCount, SUCCESS_COUNT_JS_FOUR);
922    HILOG_INFO("Threadsafe_Test_0600 end");
923}
924
925/**
926 * @tc.name: ThreadsafeTest007
927 * @tc.desc: Test napi_ref_threadsafe_function.
928 * @tc.type: FUNC
929 * @tc.require: I5K6KF
930 */
931HWTEST_F(NapiThreadsafeTest, ThreadsafeTest007, testing::ext::TestSize.Level1)
932{
933    HILOG_INFO("Threadsafe_Test_0700 start");
934
935    napi_env env = (napi_env)engine_;
936    napi_threadsafe_function tsFunc = nullptr;
937    napi_value resourceName = 0;
938
939    napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
940    g_jsData.id = CALL_JS_CB_DATA_TEST_ID;
941    g_finalData.id = FINAL_CB_DATA_TEST_ID;
942
943    auto status = napi_create_threadsafe_function(env, nullptr, nullptr, resourceName,
944        0, 1, &g_finalData, TsFuncFinalCallback, &g_jsData, TsFuncCallJsFour, &tsFunc);
945    EXPECT_EQ(status, napi_ok);
946
947    status = napi_ref_threadsafe_function(env, tsFunc);
948    EXPECT_EQ(status, napi_ok);
949
950    HILOG_INFO("Threadsafe_Test_0700 end");
951}
952
953/**
954 * @tc.name: ThreadsafeTest008
955 * @tc.desc: Test napi_unref_threadsafe_function.
956 * @tc.type: FUNC
957 * @tc.require: I5K6KF
958 */
959HWTEST_F(NapiThreadsafeTest, ThreadsafeTest008, testing::ext::TestSize.Level1)
960{
961    HILOG_INFO("Threadsafe_Test_0800 start");
962    napi_env env = (napi_env)engine_;
963    napi_threadsafe_function tsFunc = nullptr;
964    napi_value resourceName = 0;
965
966    napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
967    g_jsData.id = CALL_JS_CB_DATA_TEST_ID;
968    g_finalData.id = FINAL_CB_DATA_TEST_ID;
969
970    auto status = napi_create_threadsafe_function(env, nullptr, nullptr, resourceName,
971        0, 1, &g_finalData, TsFuncFinalCallback, &g_jsData, TsFuncCallJsFour, &tsFunc);
972    EXPECT_EQ(status, napi_ok);
973
974    status = napi_unref_threadsafe_function(env, tsFunc);
975    EXPECT_EQ(status, napi_ok);
976
977    HILOG_INFO("Threadsafe_Test_0800 end");
978}
979
980/**
981 * @tc.name: ThreadsafeTest009
982 * @tc.desc: Test napi_ref_threadsafe_function and napi_unref_threadsafe_function.
983 * @tc.type: FUNC
984 * @tc.require: I5K6KF
985 */
986HWTEST_F(NapiThreadsafeTest, ThreadsafeTest009, testing::ext::TestSize.Level1)
987{
988    HILOG_INFO("Threadsafe_Test_0900 start");
989    napi_env env = (napi_env)engine_;
990    napi_threadsafe_function tsFunc = nullptr;
991    napi_value resourceName = 0;
992
993    napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
994    g_jsData.id = CALL_JS_CB_DATA_TEST_ID;
995    g_finalData.id = FINAL_CB_DATA_TEST_ID;
996
997    auto status = napi_create_threadsafe_function(env, nullptr, nullptr, resourceName,
998        0, 1, &g_finalData, TsFuncFinalCallback, &g_jsData, TsFuncCallJsFour, &tsFunc);
999    EXPECT_EQ(status, napi_ok);
1000
1001    status = napi_unref_threadsafe_function(env, tsFunc);
1002    EXPECT_EQ(status, napi_ok);
1003
1004    status = napi_unref_threadsafe_function(env, tsFunc);
1005    EXPECT_EQ(status, napi_ok);
1006
1007    HILOG_INFO("Threadsafe_Test_0900 end");
1008}
1009
1010/**
1011 * @tc.name: ThreadsafeTest010
1012 * @tc.desc: Test napi_unref_threadsafe_function and napi_release_threadsafe_function.
1013 * @tc.type: FUNC
1014 * @tc.require: I5K6KF
1015 */
1016HWTEST_F(NapiThreadsafeTest, ThreadsafeTest010, testing::ext::TestSize.Level1)
1017{
1018    HILOG_INFO("Threadsafe_Test_1000 start");
1019    napi_env env = (napi_env)engine_;
1020    napi_threadsafe_function tsFunc = nullptr;
1021    napi_value resourceName = 0;
1022    napi_threadsafe_function_release_mode abort = napi_tsfn_abort;
1023
1024    napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
1025    g_jsData.id = CALL_JS_CB_DATA_TEST_ID;
1026    g_finalData.id = FINAL_CB_DATA_TEST_ID;
1027
1028    auto status = napi_create_threadsafe_function(env, nullptr, nullptr, resourceName,
1029        0, 1, &g_finalData, TsFuncFinalCallback, &g_jsData, TsFuncCallJsFour, &tsFunc);
1030    EXPECT_EQ(status, napi_ok);
1031
1032    status = napi_unref_threadsafe_function(env, tsFunc);
1033    EXPECT_EQ(status, napi_ok);
1034
1035    status = napi_release_threadsafe_function(tsFunc, abort);
1036    EXPECT_EQ(status, napi_ok);
1037
1038    HILOG_INFO("Threadsafe_Test_1000 end");
1039}
1040
1041/**
1042 * @tc.name: ThreadsafeTest011
1043 * @tc.desc: Test napi_ref_threadsafe_function and napi_release_threadsafe_function.
1044 * @tc.type: FUNC
1045 * @tc.require: I5K6KF
1046 */
1047HWTEST_F(NapiThreadsafeTest, ThreadsafeTest011, testing::ext::TestSize.Level1)
1048{
1049    HILOG_INFO("Threadsafe_Test_1100 start");
1050
1051    napi_env env = (napi_env)engine_;
1052    napi_threadsafe_function tsFunc = nullptr;
1053    napi_value resourceName = 0;
1054    napi_threadsafe_function_release_mode abort = napi_tsfn_abort;
1055
1056    napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
1057    g_jsData.id = CALL_JS_CB_DATA_TEST_ID;
1058    g_finalData.id = FINAL_CB_DATA_TEST_ID;
1059
1060    auto status = napi_create_threadsafe_function(env, nullptr, nullptr, resourceName,
1061        0, 1, &g_finalData, TsFuncFinalCallback, &g_jsData, TsFuncCallJsFour, &tsFunc);
1062    EXPECT_EQ(status, napi_ok);
1063
1064    status = napi_ref_threadsafe_function(env, tsFunc);
1065    EXPECT_EQ(status, napi_ok);
1066
1067    status = napi_release_threadsafe_function(tsFunc, abort);
1068    EXPECT_EQ(status, napi_ok);
1069
1070    HILOG_INFO("Threadsafe_Test_1100 end");
1071}
1072
1073/**
1074 * @tc.name: ThreadsafeWithPriorityArgsCheckTest001
1075 * @tc.desc: Test napi_call_threadsafe_function_with_priority.
1076 * @tc.type: FUNC
1077 * @tc.require: I99QUH
1078 */
1079HWTEST_F(NapiThreadsafeTest, ThreadsafeWithPriorityArgsCheckTest001, testing::ext::TestSize.Level1)
1080{
1081    HILOG_INFO("ThreadsafeWithPriorityArgsCheckTest001 start");
1082    auto status =
1083        napi_call_threadsafe_function_with_priority(nullptr, nullptr, napi_priority_immediate, true);
1084    EXPECT_EQ(status, napi_invalid_arg);
1085    HILOG_INFO("ThreadsafeWithPriorityArgsCheckTest001 end");
1086}
1087
1088/**
1089 * @tc.name: ThreadsafeWithPriorityArgsCheckTest002
1090 * @tc.desc: Test napi_call_threadsafe_function_with_priority.
1091 * @tc.type: FUNC
1092 * @tc.require: I99QUH
1093 */
1094HWTEST_F(NapiThreadsafeTest, ThreadsafeWithPriorityArgsCheckTest002, testing::ext::TestSize.Level1)
1095{
1096    HILOG_INFO("ThreadsafeWithPriorityArgsCheckTest002 start");
1097    napi_env env = (napi_env)engine_;
1098    napi_value resourceName = 0;
1099    napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
1100    CallbackData *callbackData = new CallbackData();
1101    auto status = napi_create_threadsafe_function(env, nullptr, nullptr, resourceName,
1102        0, 1, callbackData, nullptr, callbackData, CallJs, &callbackData->tsfn);
1103    EXPECT_EQ(status, napi_ok);
1104    status =
1105        napi_call_threadsafe_function_with_priority(callbackData->tsfn, nullptr,
1106            static_cast<napi_task_priority>(INVALID_NAPI_THREAD_SAFE_PRIORITY), true);
1107    delete callbackData;
1108    HILOG_INFO("ThreadsafeWithPriorityArgsCheckTest002 end");
1109}
1110
1111/**
1112 * @tc.name: ThreadsafeWithPriorityTest001
1113 * @tc.desc: Test napi_call_threadsafe_function_with_priority.
1114 * @tc.type: FUNC
1115 * @tc.require: I99QUH
1116 */
1117HWTEST_F(NapiThreadsafeTest, ThreadsafeWithPriorityTest001, testing::ext::TestSize.Level1)
1118{
1119    HILOG_INFO("ThreadsafeWithPriorityTest001 start");
1120    g_isTailA = true;
1121    g_isTailB = true;
1122    auto task = [test = this]() {
1123        test->CallThreadSafeWithSamePriorityTest(napi_priority_immediate);
1124    };
1125    EXPECT_NE(eventHandler_, nullptr);
1126    eventHandler_->PostTask(task);
1127    auto runner = eventHandler_->GetEventRunner();
1128    EXPECT_NE(runner, nullptr);
1129    runner->Run();
1130    HILOG_INFO("ThreadsafeWithPriorityTest001 end");
1131}
1132
1133/**
1134 * @tc.name: ThreadsafeWithPriorityTest002
1135 * @tc.desc: Test napi_call_threadsafe_function_with_priority.
1136 * @tc.type: FUNC
1137 * @tc.require: I99QUH
1138 */
1139HWTEST_F(NapiThreadsafeTest, ThreadsafeWithPriorityTest002, testing::ext::TestSize.Level1)
1140{
1141    HILOG_INFO("ThreadsafeWithPriorityTest002 start");
1142    g_isTailA = false;
1143    g_isTailB = false;
1144    auto task = [test = this]() {
1145        test->CallThreadSafeWithSamePriorityTest(napi_priority_immediate);
1146    };
1147    EXPECT_NE(eventHandler_, nullptr);
1148    eventHandler_->PostTask(task);
1149    auto runner = eventHandler_->GetEventRunner();
1150    EXPECT_NE(runner, nullptr);
1151    runner->Run();
1152    HILOG_INFO("ThreadsafeWithPriorityTest002 end");
1153}
1154
1155/**
1156 * @tc.name: ThreadsafeWithPriorityTest003
1157 * @tc.desc: Test napi_call_threadsafe_function_with_priority.
1158 * @tc.type: FUNC
1159 * @tc.require: I99QUH
1160 */
1161HWTEST_F(NapiThreadsafeTest, ThreadsafeWithPriorityTest003, testing::ext::TestSize.Level1)
1162{
1163    HILOG_INFO("ThreadsafeWithPriorityTest003 start");
1164    g_isTailA = true;
1165    g_isTailB = false;
1166    auto task = [test = this]() {
1167        test->CallThreadSafeWithSamePriorityTest(napi_priority_immediate);
1168    };
1169    EXPECT_NE(eventHandler_, nullptr);
1170    eventHandler_->PostTask(task);
1171    auto runner = eventHandler_->GetEventRunner();
1172    EXPECT_NE(runner, nullptr);
1173    runner->Run();
1174    HILOG_INFO("ThreadsafeWithPriorityTest003 end");
1175}
1176
1177/**
1178 * @tc.name: ThreadsafeWithPriorityTest004
1179 * @tc.desc: Test napi_call_threadsafe_function_with_priority.
1180 * @tc.type: FUNC
1181 * @tc.require: I99QUH
1182 */
1183HWTEST_F(NapiThreadsafeTest, ThreadsafeWithPriorityTest004, testing::ext::TestSize.Level1)
1184{
1185    HILOG_INFO("ThreadsafeWithPriorityTest004 start");
1186    g_isTailA = true;
1187    g_isTailB = true;
1188    auto task = [test = this]() {
1189        test->CallThreadSafeWithSamePriorityTest(napi_priority_high);
1190    };
1191    EXPECT_NE(eventHandler_, nullptr);
1192    eventHandler_->PostTask(task);
1193    auto runner = eventHandler_->GetEventRunner();
1194    EXPECT_NE(runner, nullptr);
1195    runner->Run();
1196    HILOG_INFO("ThreadsafeWithPriorityTest004 end");
1197}
1198
1199/**
1200 * @tc.name: ThreadsafeWithPriorityTest005
1201 * @tc.desc: Test napi_call_threadsafe_function_with_priority.
1202 * @tc.type: FUNC
1203 * @tc.require: I99QUH
1204 */
1205HWTEST_F(NapiThreadsafeTest, ThreadsafeWithPriorityTest005, testing::ext::TestSize.Level1)
1206{
1207    HILOG_INFO("ThreadsafeWithPriorityTest005 start");
1208    g_isTailA = false;
1209    g_isTailB = false;
1210    auto task = [test = this]() {
1211        test->CallThreadSafeWithSamePriorityTest(napi_priority_high);
1212    };
1213    EXPECT_NE(eventHandler_, nullptr);
1214    eventHandler_->PostTask(task);
1215    auto runner = eventHandler_->GetEventRunner();
1216    EXPECT_NE(runner, nullptr);
1217    runner->Run();
1218    HILOG_INFO("ThreadsafeWithPriorityTest005 end");
1219}
1220
1221/**
1222 * @tc.name: ThreadsafeWithPriorityTest006
1223 * @tc.desc: Test napi_call_threadsafe_function_with_priority.
1224 * @tc.type: FUNC
1225 * @tc.require: I99QUH
1226 */
1227HWTEST_F(NapiThreadsafeTest, ThreadsafeWithPriorityTest006, testing::ext::TestSize.Level1)
1228{
1229    HILOG_INFO("ThreadsafeWithPriorityTest006 start");
1230    g_isTailA = true;
1231    g_isTailB = false;
1232    auto task = [test = this]() {
1233        test->CallThreadSafeWithSamePriorityTest(napi_priority_high);
1234    };
1235    EXPECT_NE(eventHandler_, nullptr);
1236    eventHandler_->PostTask(task);
1237    auto runner = eventHandler_->GetEventRunner();
1238    EXPECT_NE(runner, nullptr);
1239    runner->Run();
1240    HILOG_INFO("ThreadsafeWithPriorityTest006 end");
1241}
1242
1243/**
1244 * @tc.name: ThreadsafeWithPriorityTest007
1245 * @tc.desc: Test napi_call_threadsafe_function_with_priority.
1246 * @tc.type: FUNC
1247 * @tc.require: I99QUH
1248 */
1249HWTEST_F(NapiThreadsafeTest, ThreadsafeWithPriorityTest007, testing::ext::TestSize.Level1)
1250{
1251    HILOG_INFO("ThreadsafeWithPriorityTest007 start");
1252    g_isTailA = true;
1253    g_isTailB = true;
1254    auto task = [test = this]() {
1255        test->CallThreadSafeWithSamePriorityTest(napi_priority_low);
1256    };
1257    EXPECT_NE(eventHandler_, nullptr);
1258    eventHandler_->PostTask(task);
1259    auto runner = eventHandler_->GetEventRunner();
1260    EXPECT_NE(runner, nullptr);
1261    runner->Run();
1262    HILOG_INFO("ThreadsafeWithPriorityTest007 end");
1263}
1264
1265/**
1266 * @tc.name: ThreadsafeWithPriorityTest008
1267 * @tc.desc: Test napi_call_threadsafe_function_with_priority.
1268 * @tc.type: FUNC
1269 * @tc.require: I99QUH
1270 */
1271HWTEST_F(NapiThreadsafeTest, ThreadsafeWithPriorityTest008, testing::ext::TestSize.Level1)
1272{
1273    HILOG_INFO("ThreadsafeWithPriorityTest008 start");
1274    g_isTailA = false;
1275    g_isTailB = false;
1276    auto task = [test = this]() {
1277        test->CallThreadSafeWithSamePriorityTest(napi_priority_low);
1278    };
1279    EXPECT_NE(eventHandler_, nullptr);
1280    eventHandler_->PostTask(task);
1281    auto runner = eventHandler_->GetEventRunner();
1282    EXPECT_NE(runner, nullptr);
1283    runner->Run();
1284    HILOG_INFO("ThreadsafeWithPriorityTest008 end");
1285}
1286
1287/**
1288 * @tc.name: ThreadsafeWithPriorityTest009
1289 * @tc.desc: Test napi_call_threadsafe_function_with_priority.
1290 * @tc.type: FUNC
1291 * @tc.require: I99QUH
1292 */
1293HWTEST_F(NapiThreadsafeTest, ThreadsafeWithPriorityTest009, testing::ext::TestSize.Level1)
1294{
1295    HILOG_INFO("ThreadsafeWithPriorityTest009 start");
1296    g_isTailA = true;
1297    g_isTailB = false;
1298    auto task = [test = this]() {
1299        test->CallThreadSafeWithSamePriorityTest(napi_priority_low);
1300    };
1301    EXPECT_NE(eventHandler_, nullptr);
1302    eventHandler_->PostTask(task);
1303    auto runner = eventHandler_->GetEventRunner();
1304    EXPECT_NE(runner, nullptr);
1305    runner->Run();
1306    HILOG_INFO("ThreadsafeWithPriorityTest009 end");
1307}
1308
1309
1310/**
1311 * @tc.name: ThreadsafeWithPriorityTest010
1312 * @tc.desc: Test napi_call_threadsafe_function_with_priority.
1313 * @tc.type: FUNC
1314 * @tc.require: I99QUH
1315 */
1316HWTEST_F(NapiThreadsafeTest, ThreadsafeWithPriorityTest010, testing::ext::TestSize.Level1)
1317{
1318    HILOG_INFO("ThreadsafeWithPriorityTest010 start");
1319    g_isTailA = true;
1320    g_isTailB = true;
1321    auto task = [test = this]() {
1322        test->CallThreadSafeWithSamePriorityTest(napi_priority_idle);
1323    };
1324    EXPECT_NE(eventHandler_, nullptr);
1325    eventHandler_->PostTask(task);
1326    auto runner = eventHandler_->GetEventRunner();
1327    EXPECT_NE(runner, nullptr);
1328    runner->Run();
1329    HILOG_INFO("ThreadsafeWithPriorityTest010 end");
1330}
1331
1332/**
1333 * @tc.name: ThreadsafeWithPriorityTest011
1334 * @tc.desc: Test napi_call_threadsafe_function_with_priority.
1335 * @tc.type: FUNC
1336 * @tc.require: I99QUH
1337 */
1338HWTEST_F(NapiThreadsafeTest, ThreadsafeWithPriorityTest011, testing::ext::TestSize.Level1)
1339{
1340    HILOG_INFO("ThreadsafeWithPriorityTest005 start");
1341    g_isTailA = false;
1342    g_isTailB = false;
1343    auto task = [test = this]() {
1344        test->CallThreadSafeWithSamePriorityTest(napi_priority_idle);
1345    };
1346    EXPECT_NE(eventHandler_, nullptr);
1347    eventHandler_->PostTask(task);
1348    auto runner = eventHandler_->GetEventRunner();
1349    EXPECT_NE(runner, nullptr);
1350    runner->Run();
1351    HILOG_INFO("ThreadsafeWithPriorityTest011 end");
1352}
1353
1354/**
1355 * @tc.name: ThreadsafeWithPriorityTest012
1356 * @tc.desc: Test napi_call_threadsafe_function_with_priority.
1357 * @tc.type: FUNC
1358 * @tc.require: I99QUH
1359 */
1360HWTEST_F(NapiThreadsafeTest, ThreadsafeWithPriorityTest012, testing::ext::TestSize.Level1)
1361{
1362    HILOG_INFO("ThreadsafeWithPriorityTest012 start");
1363    g_isTailA = true;
1364    g_isTailB = false;
1365    auto task = [test = this]() {
1366        test->CallThreadSafeWithSamePriorityTest(napi_priority_idle);
1367    };
1368    EXPECT_NE(eventHandler_, nullptr);
1369    eventHandler_->PostTask(task);
1370    auto runner = eventHandler_->GetEventRunner();
1371    EXPECT_NE(runner, nullptr);
1372    runner->Run();
1373    HILOG_INFO("ThreadsafeWithPriorityTest012 end");
1374}
1375
1376/**
1377 * @tc.name: ThreadsafeWithPriorityTest013
1378 * @tc.desc: Test napi_call_threadsafe_function_with_priority.
1379 * @tc.type: FUNC
1380 * @tc.require: I99QUH
1381 */
1382HWTEST_F(NapiThreadsafeTest, ThreadsafeWithPriorityTest013, testing::ext::TestSize.Level1)
1383{
1384    HILOG_INFO("ThreadsafeWithPriorityTest013 start");
1385    auto task = [test = this]() {
1386        test->CallThreadSafeWithDiffPriorityTest();
1387    };
1388    EXPECT_NE(eventHandler_, nullptr);
1389    eventHandler_->PostTask(task);
1390    auto runner = eventHandler_->GetEventRunner();
1391    EXPECT_NE(runner, nullptr);
1392    runner->Run();
1393    HILOG_INFO("ThreadsafeWithPriorityTest013 end");
1394}
1395
1396/**
1397 * @tc.name: ThreadsafeWithPriorityTest014
1398 * @tc.desc: Test napi_call_threadsafe_function_with_priority.
1399 * @tc.type: FUNC
1400 * @tc.require: I99QUH
1401 */
1402HWTEST_F(NapiThreadsafeTest, ThreadsafeWithPriorityTest014, testing::ext::TestSize.Level1)
1403{
1404    HILOG_INFO("ThreadsafeWithPriorityTest014 start");
1405    auto task = [test = this]() {
1406        test->CallThreadSafeWithDiffPriorityMultipleThreadTest();
1407    };
1408    EXPECT_NE(eventHandler_, nullptr);
1409    eventHandler_->PostTask(task);
1410    auto runner = eventHandler_->GetEventRunner();
1411    EXPECT_NE(runner, nullptr);
1412    runner->Run();
1413    HILOG_INFO("ThreadsafeWithPriorityTest014 end");
1414}
1415
1416/**
1417 * @tc.name: ThreadsafeTest012
1418 * @tc.desc: Test LoadModule Func, call napi_call_threadsafe_function in callback.
1419 * @tc.type: FUNC
1420 * @tc.require: I5K6KF
1421 */
1422HWTEST_F(NapiThreadsafeTest, ThreadsafeTest012, testing::ext::TestSize.Level1)
1423{
1424    HILOG_INFO("Threadsafe_Test_1200 start");
1425    napi_env env = (napi_env)engine_;
1426    napi_threadsafe_function tsFunc = nullptr;
1427    napi_value resourceName = 0;
1428
1429    napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
1430    g_mainTid = gettid();
1431    g_jsData.id = CALL_JS_CB_DATA_TEST_ID;
1432    g_finalData.id = FINAL_CB_DATA_TEST_ID;
1433
1434    auto status = napi_create_threadsafe_function(env,
1435                                                  nullptr,
1436                                                  nullptr,
1437                                                  resourceName,
1438                                                  0,
1439                                                  1,
1440                                                  &g_finalData,
1441                                                  TsFuncFinal,
1442                                                  &g_jsData,
1443                                                  TsFuncCallJsWithNewCall,
1444                                                  &tsFunc);
1445    EXPECT_EQ(status, napi_ok);
1446
1447    if (uv_thread_create(
1448            &g_uvThread,
1449            [](void *data) {
1450                napi_threadsafe_function func = (napi_threadsafe_function)data;
1451                auto status = napi_call_threadsafe_function(func, data, napi_tsfn_nonblocking);
1452                EXPECT_EQ(status, napi_ok);
1453            },
1454            tsFunc) != 0) {
1455        HILOG_ERROR("Failed to create uv thread!");
1456    }
1457
1458    HILOG_INFO("Threadsafe_Test_1200 end");
1459}