• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 <uv.h>
19 
20 #include "napi/native_api.h"
21 #include "napi/native_node_api.h"
22 #include "securec.h"
23 #include "utils/log.h"
24 
25 struct CallJsCbData_t {
26     int32_t id = 0;
27     bool secondaryThread = false;
28     napi_threadsafe_function_call_mode blockOnFull = napi_tsfn_nonblocking;
29 };
30 
31 struct FinalCbData_t {
32     int32_t id = 0;
33 };
34 
35 static constexpr int32_t SEND_DATA_TEST = 11;
36 static constexpr int32_t CALL_JS_CB_DATA_TEST_ID = 101;
37 static constexpr int32_t FINAL_CB_DATA_TEST_ID = 1001;
38 static constexpr int32_t SEND_DATAS_LENGTH = 10;
39 static constexpr int32_t THREAD_COUNT = 2;
40 static constexpr int32_t THREAD_COUNT_FOUR = 4;
41 static constexpr int32_t MAX_QUEUE_SIZE = 3;
42 static constexpr int32_t SUCCESS_COUNT_JS_FOUR = 4;
43 
44 static pid_t g_mainTid = 0;
45 static CallJsCbData_t g_jsData;
46 static CallJsCbData_t g_jsDataInternal;
47 static FinalCbData_t g_finalData;
48 static int32_t g_sendData = 0;
49 static uv_thread_t g_uvThread;
50 static uv_thread_t g_uvThreadTest5;
51 static uv_thread_t g_uvThreadTest6;
52 static uv_thread_t g_uvThreadTest7;
53 static uv_thread_t g_uvThreadSecondary;
54 static uv_thread_t g_uvTheads2;
55 static uv_thread_t g_uvTheads3;
56 static int32_t g_sendDatas[SEND_DATAS_LENGTH];
57 static int32_t  callSuccessCount = 0;
58 static int32_t  callSuccessCountJS = 0;
59 static int32_t  callSuccessCountJSFour = 0;
60 bool  acquireFlag = false;
61 
TsFuncCallJs(napi_env env,napi_value tsfn_cb,void * context,void * data)62 static void TsFuncCallJs(napi_env env, napi_value tsfn_cb, void* context, void* data)
63 {
64     HILOG_INFO("TsFuncCallJs called");
65 
66     EXPECT_EQ(gettid(), g_mainTid);
67 
68     // expect context equal
69     EXPECT_EQ(((CallJsCbData_t*)context)->id, CALL_JS_CB_DATA_TEST_ID);
70 
71     // expect data equal
72     int* pData = (int32_t*)data;
73     EXPECT_EQ((*pData), SEND_DATA_TEST);
74 }
TsFuncCallJsTwo(napi_env env,napi_value tsfn_cb,void * context,void * data)75 static void TsFuncCallJsTwo(napi_env env, napi_value tsfn_cb, void* context, void* data)
76 {
77     HILOG_INFO("TsFuncCallJsTwo called");
78     TsFuncCallJs(env, tsfn_cb, context, data);
79     callSuccessCountJS++;
80 }
TsFuncCallJsFour(napi_env env,napi_value tsfn_cb,void * context,void * data)81 static void TsFuncCallJsFour(napi_env env, napi_value tsfn_cb, void* context, void* data)
82 {
83     HILOG_INFO("TsFuncCallJsFour called");
84 
85     TsFuncCallJs(env, tsfn_cb, context, data);
86     callSuccessCountJSFour++;
87 }
TsFuncCallJsMulti(napi_env env,napi_value tsfn_cb,void * context,void * data)88 static void TsFuncCallJsMulti(napi_env env,
89                               napi_value tsfn_cb,
90                               void* context,
91                               void* data)
92 {
93     HILOG_INFO("TsFuncCallJsMulti called");
94 
95     EXPECT_EQ(gettid(), g_mainTid);
96 
97     // expect context equal
98     EXPECT_EQ(((CallJsCbData_t*)context)->id, CALL_JS_CB_DATA_TEST_ID);
99 
100     int* pData = ((int32_t*)data);
101 
102     HILOG_INFO("TsFuncCallJsMulti data %d", (*pData));
103 }
104 
TsFuncFinal(napi_env env,void * finalizeData,void * hint)105 static void TsFuncFinal(napi_env env, void* finalizeData, void* hint)
106 {
107     HILOG_INFO("TsFuncFinal called");
108 
109     // expect thread id equal
110     EXPECT_EQ(gettid(), g_mainTid);
111 
112     // wait data source thread
113     uv_thread_join(&g_uvThread);
114 
115     // expect context equal
116     EXPECT_EQ(((CallJsCbData_t*)hint)->id, CALL_JS_CB_DATA_TEST_ID);
117 
118     // expect finalize data equal
119     EXPECT_EQ(((FinalCbData_t*)finalizeData)->id, FINAL_CB_DATA_TEST_ID);
120 }
TsFuncFinalTest5(napi_env env,void * finalizeData,void * hint)121 static void TsFuncFinalTest5(napi_env env, void* finalizeData, void* hint)
122 {
123     HILOG_INFO("TsFuncFinalTest5 called");
124 
125     // expect thread id equal
126     EXPECT_EQ(gettid(), g_mainTid);
127 
128     // wait data source thread
129     uv_thread_join(&g_uvThreadTest5);
130 
131     // expect context equal
132     EXPECT_EQ(((CallJsCbData_t*)hint)->id, CALL_JS_CB_DATA_TEST_ID);
133 
134     // expect finalize data equal
135     EXPECT_EQ(((FinalCbData_t*)finalizeData)->id, FINAL_CB_DATA_TEST_ID);
136 }
TsFuncFinalTotal(napi_env env,void * finalizeData,void * hint)137 static void TsFuncFinalTotal(napi_env env, void* finalizeData, void* hint)
138 {
139     HILOG_INFO("TsFuncFinalTotal called");
140     uv_thread_join(&g_uvThreadTest6);
141     // when add thread,repair  callSuccessCountJS eq  SUCCESS_COUNT_JS_TWO
142     EXPECT_EQ(callSuccessCountJS, SUCCESS_COUNT_JS_FOUR);
143     HILOG_INFO("TsFuncFinalTotal end");
144 }
TsFuncFinalTotalFour(napi_env env,void * finalizeData,void * hint)145 static void TsFuncFinalTotalFour(napi_env env, void* finalizeData, void* hint)
146 {
147     HILOG_INFO("TsFuncFinalTotalFour called");
148     uv_thread_join(&g_uvThreadTest7);
149     EXPECT_EQ(callSuccessCountJSFour, SUCCESS_COUNT_JS_FOUR);
150     HILOG_INFO("TsFuncFinalTotalFour end");
151 }
TsFuncFinalCallback(napi_env env,void * finalizeData,void * hint)152 static void TsFuncFinalCallback(napi_env env, void* finalizeData, void* hint)
153 {
154     HILOG_INFO("TsFuncFinalCallback called");
155     EXPECT_EQ(callSuccessCountJSFour, SUCCESS_COUNT_JS_FOUR);
156     HILOG_INFO("TsFuncFinalCallback end");
157 }
158 
TsFuncFinalJoinThread(napi_env env,void * data,void * hint)159 static void TsFuncFinalJoinThread(napi_env env, void* data, void* hint)
160 {
161     HILOG_INFO("TsFuncFinalJoinThread called");
162 
163     uv_thread_t *uvThread = reinterpret_cast<uv_thread_t*>(data);
164     CallJsCbData_t *jsData = reinterpret_cast<CallJsCbData_t*>(hint);
165 
166     uv_thread_join(uvThread);
167 
168     if (jsData->secondaryThread) {
169         uv_thread_join(&g_uvThreadSecondary);
170     }
171 }
172 
TsFuncSecondaryThread(void * data)173 static void TsFuncSecondaryThread(void* data)
174 {
175     HILOG_INFO("TsFuncSecondaryThread called");
176 
177     // expect thread id not equal
178     EXPECT_NE(gettid(), g_mainTid);
179 
180     napi_threadsafe_function func = (napi_threadsafe_function)data;
181 
182     auto status = napi_release_threadsafe_function(func, napi_tsfn_release);
183     EXPECT_EQ(status, napi_ok);
184 }
185 
TsFuncDataSourceThread(void * data)186 static void TsFuncDataSourceThread(void* data)
187 {
188     HILOG_INFO("TsFuncDataSourceThread called");
189 
190     // expect thread id not equal
191     EXPECT_NE(gettid(), g_mainTid);
192 
193     napi_threadsafe_function func = (napi_threadsafe_function)data;
194     napi_threadsafe_function_call_mode blockMode = napi_tsfn_nonblocking;
195     void* context = nullptr;
196 
197     auto status = napi_get_threadsafe_function_context(func, &context);
198     EXPECT_EQ(status, napi_ok);
199 
200     // expect context equal
201     EXPECT_EQ(((CallJsCbData_t*)context)->id, CALL_JS_CB_DATA_TEST_ID);
202 
203     // set send data
204     g_sendData = SEND_DATA_TEST;
205 
206     // As main thread has set initial_thread_count to 1 and only this one secondary thread,
207     // so no need to call `napi_acquire_threadsafe_function()`.
208     status = napi_call_threadsafe_function(func, &g_sendData, blockMode);
209     EXPECT_EQ(status, napi_ok);
210 
211     status = napi_release_threadsafe_function(func, napi_tsfn_release);
212     EXPECT_EQ(status, napi_ok);
213 }
TsFuncDataSourceThreadAbort(void * data)214 static void TsFuncDataSourceThreadAbort(void* data)
215 {
216     HILOG_INFO("TsFuncDataSourceThreadAbort called");
217 
218     // expect thread id not equal
219     EXPECT_NE(gettid(), g_mainTid);
220 
221     napi_threadsafe_function func = (napi_threadsafe_function)data;
222     napi_threadsafe_function_call_mode blockMode = napi_tsfn_nonblocking;
223     void* context = nullptr;
224 
225     auto status = napi_get_threadsafe_function_context(func, &context);
226     EXPECT_EQ(status, napi_ok);
227 
228     // expect context equal
229     EXPECT_EQ(((CallJsCbData_t*)context)->id, CALL_JS_CB_DATA_TEST_ID);
230 
231     // set send data
232     g_sendData = SEND_DATA_TEST;
233 
234     status = napi_call_threadsafe_function(func, &g_sendData, blockMode);
235     EXPECT_EQ(status, napi_closing);
236 }
237 
TsFuncDataSourceThreadCountTotal(void * data)238 static void TsFuncDataSourceThreadCountTotal(void* data)
239 {
240     HILOG_INFO("TsFuncDataSourceThreadCountTotal called");
241 
242     // expect thread id not equal
243     EXPECT_NE(gettid(), g_mainTid);
244 
245     napi_threadsafe_function func = (napi_threadsafe_function)data;
246     napi_threadsafe_function_call_mode blockMode = napi_tsfn_nonblocking;
247     void* context = nullptr;
248 
249     auto status = napi_get_threadsafe_function_context(func, &context);
250     EXPECT_EQ(status, napi_ok);
251 
252     // expect context equal
253     EXPECT_EQ(((CallJsCbData_t*)context)->id, CALL_JS_CB_DATA_TEST_ID);
254     // set send data
255     g_sendData = SEND_DATA_TEST;
256     if (acquireFlag) {
257         std::cout<<"acquireFlag  is true"<<std::endl;
258         status = napi_acquire_threadsafe_function(func);
259         EXPECT_EQ(status, napi_ok);
260         status = napi_call_threadsafe_function(func, &g_sendData, blockMode);
261         if (status == napi_ok) {
262             callSuccessCount++;
263         }
264         status = napi_release_threadsafe_function(func, napi_tsfn_release);
265     } else {
266         status = napi_call_threadsafe_function(func, &g_sendData, blockMode);
267         if (status == napi_ok) {
268             callSuccessCount++;
269         }
270     }
271     status = napi_release_threadsafe_function(func, napi_tsfn_release);
272 }
273 
TsFuncDataSourceThreadMulti(void * data)274 static void TsFuncDataSourceThreadMulti(void* data)
275 {
276     HILOG_INFO("TsFuncDataSourceThreadMulti called");
277 
278     // expect thread id not equal
279     EXPECT_NE(gettid(), g_mainTid);
280 
281     napi_threadsafe_function func =  (napi_threadsafe_function)data;
282     void* context = nullptr;
283 
284     auto status = napi_get_threadsafe_function_context(func, &context);
285     EXPECT_EQ(status, napi_ok);
286     CallJsCbData_t* jsData = nullptr;
287     jsData = (CallJsCbData_t*)context;
288 
289     if (jsData->secondaryThread) {
290         status = napi_acquire_threadsafe_function(func);
291         EXPECT_EQ(status, napi_ok);
292 
293         if (uv_thread_create(&g_uvThreadSecondary, TsFuncSecondaryThread, func) != 0) {
294             HILOG_ERROR("Failed to create uv thread!");
295         }
296     }
297 
298     bool queueClosing = false;
299     bool queueFull = false;
300     int32_t index = 0;
301     for (index = SEND_DATAS_LENGTH - 1; index > -1 && !queueClosing; index--) {
302         g_sendDatas[index] = index;
303         status = napi_call_threadsafe_function(func, &g_sendDatas[index], jsData->blockOnFull);
304         HILOG_INFO("napi_call_threadsafe_function index %d status %d", index, status);
305 
306         switch (status) {
307             case napi_queue_full:
308                 queueFull = true;
309                 index++;
310                 [[fallthrough]];
311             case napi_ok:
312                 continue;
313             case napi_closing:
314                 queueClosing = true;
315                 break;
316             default:
317                 HILOG_ERROR("Failed to call napi_call_threadsafe_function!");
318         }
319     }
320 
321     if (!queueClosing && (napi_release_threadsafe_function(func, napi_tsfn_release) != napi_ok)) {
322         HILOG_ERROR("Failed to call napi_release_threadsafe_function!");
323     }
324 }
325 
TsFuncThreadInternal(napi_env env,napi_threadsafe_function_call_js cb,uv_thread_t & uvThread,bool secondary,bool block)326 static void TsFuncThreadInternal(napi_env env,
327                                  napi_threadsafe_function_call_js cb,
328                                  uv_thread_t& uvThread,
329                                  bool secondary,
330                                  bool block)
331 {
332     HILOG_INFO("TsFuncThreadInternal start secondary %d block %d", secondary, block);
333 
334     napi_threadsafe_function tsFunc = nullptr;
335     napi_value resourceName = 0;
336 
337     napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
338     g_mainTid = gettid();
339 
340     g_jsDataInternal.id = CALL_JS_CB_DATA_TEST_ID;
341     g_jsDataInternal.secondaryThread = (secondary ? true : false);
342     g_jsDataInternal.blockOnFull = (block ? napi_tsfn_blocking : napi_tsfn_nonblocking);
343 
344     auto status = napi_create_threadsafe_function(env,
345                                                   nullptr,
346                                                   nullptr,
347                                                   resourceName,
348                                                   MAX_QUEUE_SIZE,
349                                                   THREAD_COUNT,
350                                                   &uvThread,
351                                                   TsFuncFinalJoinThread,
352                                                   &g_jsDataInternal,
353                                                   cb,
354                                                   &tsFunc);
355     EXPECT_EQ(status, napi_ok);
356 
357     if (uv_thread_create(&uvThread, TsFuncDataSourceThreadMulti, tsFunc) != 0) {
358         HILOG_ERROR("Failed to create uv thread!");
359     }
360 
361     HILOG_INFO("TsFuncThreadInternal end");
362 }
363 
364 class NapiThreadsafeTest : public NativeEngineTest {
365 public:
SetUpTestCase()366     static void SetUpTestCase()
367     {
368         GTEST_LOG_(INFO) << "NapiThreadsafeTest SetUpTestCase";
369     }
370 
TearDownTestCase()371     static void TearDownTestCase()
372     {
373         GTEST_LOG_(INFO) << "NapiThreadsafeTest TearDownTestCase";
374     }
375 
SetUp()376     void SetUp() override {}
TearDown()377     void TearDown() override {}
378 };
379 
380 /**
381  * @tc.name: ThreadsafeTest001
382  * @tc.desc: Test LoadModule Func.
383  * @tc.type: FUNC
384  * @tc.require: I5K6KF
385  */
386 HWTEST_F(NapiThreadsafeTest, ThreadsafeTest001, testing::ext::TestSize.Level1)
387 {
388     HILOG_INFO("Threadsafe_Test_0100 start");
389     napi_env env = (napi_env)engine_;
390     napi_threadsafe_function tsFunc = nullptr;
391     napi_value resourceName = 0;
392 
393     napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
394     g_mainTid = gettid();
395     g_jsData.id = CALL_JS_CB_DATA_TEST_ID;
396     g_finalData.id = FINAL_CB_DATA_TEST_ID;
397 
398     auto status = napi_create_threadsafe_function(env,
399                                                   nullptr,
400                                                   nullptr,
401                                                   resourceName,
402                                                   0,
403                                                   1,
404                                                   &g_finalData,
405                                                   TsFuncFinal,
406                                                   &g_jsData,
407                                                   TsFuncCallJs,
408                                                   &tsFunc);
409     EXPECT_EQ(status, napi_ok);
410 
411     if (uv_thread_create(&g_uvThread, TsFuncDataSourceThread, tsFunc) != 0) {
412         HILOG_ERROR("Failed to create uv thread!");
413     }
414 
415     HILOG_INFO("Threadsafe_Test_0100 end");
416 }
417 
418 /**
419  * @tc.name: ThreadsafeTest002
420  * @tc.desc: Test LoadModule Func.
421  * @tc.type: FUNC
422  * @tc.require: I5K6KF
423  */
424 HWTEST_F(NapiThreadsafeTest, ThreadsafeTest002, testing::ext::TestSize.Level1)
425 {
426     HILOG_INFO("Threadsafe_Test_0200 start");
427 
428     // start secondary thread, block on full
429     TsFuncThreadInternal((napi_env)engine_, TsFuncCallJsMulti, g_uvTheads2, true, true);
430 
431     HILOG_INFO("Threadsafe_Test_0200 end");
432 }
433 
434 /**
435  * @tc.name: ThreadsafeTest003
436  * @tc.desc: Test threadsafe Func, no js.
437  * @tc.type: FUNC
438  * @tc.require: I5K6KF
439  */
440 HWTEST_F(NapiThreadsafeTest, ThreadsafeTest003, testing::ext::TestSize.Level1)
441 {
442     HILOG_INFO("Threadsafe_Test_0300 start");
443 
444     // secondary thread, not block
445     TsFuncThreadInternal((napi_env)engine_, TsFuncCallJsMulti, g_uvTheads3, false, false);
446 
447     HILOG_INFO("Threadsafe_Test_0300 end");
448 }
449 
450 /**
451  * @tc.name: ThreadsafeTest004
452  * @tc.desc: Test napi_release_threadsafe_function, napi_tsfn_abort.
453  * @tc.type: FUNC
454  * @tc.require: I5K6KF
455  */
456 HWTEST_F(NapiThreadsafeTest, ThreadsafeTest004, testing::ext::TestSize.Level1)
457 {
458     HILOG_INFO("Threadsafe_Test_0400 start");
459     napi_env env = (napi_env)engine_;
460     napi_threadsafe_function tsFunc = nullptr;
461     napi_value resourceName = 0;
462 
463     napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
464     g_mainTid = gettid();
465     g_jsData.id = CALL_JS_CB_DATA_TEST_ID;
466     g_finalData.id = FINAL_CB_DATA_TEST_ID;
467 
468     auto status = napi_create_threadsafe_function(env,
469                                                   nullptr,
470                                                   nullptr,
471                                                   resourceName,
472                                                   0,
473                                                   10,
474                                                   &g_finalData,
475                                                   TsFuncFinalTest5,
476                                                   &g_jsData,
477                                                   TsFuncCallJs,
478                                                   &tsFunc);
479     EXPECT_EQ(status, napi_ok);
480     status = napi_release_threadsafe_function(tsFunc, napi_tsfn_abort);
481     EXPECT_EQ(status, napi_ok);
482     if (uv_thread_create(&g_uvThreadTest5, TsFuncDataSourceThreadAbort, tsFunc) != 0) {
483         HILOG_ERROR("Failed to create uv thread!");
484     }
485 
486     HILOG_INFO("Threadsafe_Test_0400 end");
487 }
488 
489 /**
490  * @tc.name: ThreadsafeTest005
491  * @tc.desc: Test initial_thread_count not enough.
492  * @tc.type: FUNC
493  * @tc.require: I5K6KF
494  */
495 HWTEST_F(NapiThreadsafeTest, ThreadsafeTest005, testing::ext::TestSize.Level1)
496 {
497     HILOG_INFO("Threadsafe_Test_0500 start");
498     napi_env env = (napi_env)engine_;
499     napi_threadsafe_function tsFunc = nullptr;
500     napi_value resourceName = 0;
501     callSuccessCountJS = 0;
502     callSuccessCount = 0;
503     napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
504     g_mainTid = gettid();
505     g_jsData.id = CALL_JS_CB_DATA_TEST_ID;
506     g_finalData.id = FINAL_CB_DATA_TEST_ID;
507 
508     auto status = napi_create_threadsafe_function(env,
509                                                   nullptr,
510                                                   nullptr,
511                                                   resourceName,
512                                                   0,
513                                                   2,
514                                                   &g_finalData,
515                                                   TsFuncFinalTotal,
516                                                   &g_jsData,
517                                                   TsFuncCallJsTwo,
518                                                   &tsFunc);
519     EXPECT_EQ(status, napi_ok);
520     int threadCount = THREAD_COUNT_FOUR;
521     acquireFlag = false;
522 
523     for (int i = 0; i < threadCount; i++) {
524         if (uv_thread_create(&g_uvThreadTest6, TsFuncDataSourceThreadCountTotal, tsFunc) != 0) {
525             HILOG_ERROR("Failed to create uv thread!");
526         }
527     }
528 
529     usleep(200 * 1000);
530     EXPECT_EQ(callSuccessCount, SUCCESS_COUNT_JS_FOUR);
531     HILOG_INFO("Threadsafe_Test_0500 end");
532 }
533 
534 /**
535  * @tc.name: ThreadsafeTest006
536  * @tc.desc: Test initial_thread_count not enough but acquire.
537  * @tc.type: FUNC
538  * @tc.require: I5K6KF
539  */
540 HWTEST_F(NapiThreadsafeTest, ThreadsafeTest006, testing::ext::TestSize.Level1)
541 {
542     HILOG_INFO("Threadsafe_Test_0600 start");
543     napi_env env = (napi_env)engine_;
544     napi_threadsafe_function tsFunc = nullptr;
545     napi_value resourceName = 0;
546     callSuccessCount = 0;
547     napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
548     g_mainTid = gettid();
549     g_jsData.id = CALL_JS_CB_DATA_TEST_ID;
550     g_finalData.id = FINAL_CB_DATA_TEST_ID;
551 
552     auto status = napi_create_threadsafe_function(env,
553                                                   nullptr,
554                                                   nullptr,
555                                                   resourceName,
556                                                   0,
557                                                   1,
558                                                   &g_finalData,
559                                                   TsFuncFinalTotalFour,
560                                                   &g_jsData,
561                                                   TsFuncCallJsFour,
562                                                   &tsFunc);
563     EXPECT_EQ(status, napi_ok);
564     int threadCount = THREAD_COUNT_FOUR;
565     acquireFlag = true;
566 
567     for (int i = 0; i < threadCount; i++) {
568         if (uv_thread_create(&g_uvThreadTest7, TsFuncDataSourceThreadCountTotal, tsFunc) != 0) {
569             HILOG_ERROR("Failed to create uv thread!");
570         }
571     }
572 
573     usleep(200 * 1000);
574     EXPECT_EQ(callSuccessCount, SUCCESS_COUNT_JS_FOUR);
575     HILOG_INFO("Threadsafe_Test_0600 end");
576 }
577 
578 /**
579  * @tc.name: ThreadsafeTest007
580  * @tc.desc: Test napi_ref_threadsafe_function.
581  * @tc.type: FUNC
582  * @tc.require: I5K6KF
583  */
584 HWTEST_F(NapiThreadsafeTest, ThreadsafeTest007, testing::ext::TestSize.Level1)
585 {
586     HILOG_INFO("Threadsafe_Test_0700 start");
587 
588     napi_env env = (napi_env)engine_;
589     napi_threadsafe_function tsFunc = nullptr;
590     napi_value resourceName = 0;
591 
592     napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
593     g_jsData.id = CALL_JS_CB_DATA_TEST_ID;
594     g_finalData.id = FINAL_CB_DATA_TEST_ID;
595 
596     auto status = napi_create_threadsafe_function(env, nullptr, nullptr, resourceName,
597         0, 1, &g_finalData, TsFuncFinalCallback, &g_jsData, TsFuncCallJsFour, &tsFunc);
598     EXPECT_EQ(status, napi_ok);
599 
600     status = napi_ref_threadsafe_function(env, tsFunc);
601     EXPECT_EQ(status, napi_ok);
602 
603     HILOG_INFO("Threadsafe_Test_0700 end");
604 }
605 
606 /**
607  * @tc.name: ThreadsafeTest008
608  * @tc.desc: Test napi_unref_threadsafe_function.
609  * @tc.type: FUNC
610  * @tc.require: I5K6KF
611  */
612 HWTEST_F(NapiThreadsafeTest, ThreadsafeTest008, testing::ext::TestSize.Level1)
613 {
614     HILOG_INFO("Threadsafe_Test_0800 start");
615     napi_env env = (napi_env)engine_;
616     napi_threadsafe_function tsFunc = nullptr;
617     napi_value resourceName = 0;
618 
619     napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
620     g_jsData.id = CALL_JS_CB_DATA_TEST_ID;
621     g_finalData.id = FINAL_CB_DATA_TEST_ID;
622 
623     auto status = napi_create_threadsafe_function(env, nullptr, nullptr, resourceName,
624         0, 1, &g_finalData, TsFuncFinalCallback, &g_jsData, TsFuncCallJsFour, &tsFunc);
625     EXPECT_EQ(status, napi_ok);
626 
627     status = napi_unref_threadsafe_function(env, tsFunc);
628     EXPECT_EQ(status, napi_ok);
629 
630     HILOG_INFO("Threadsafe_Test_0800 end");
631 }
632 
633 /**
634  * @tc.name: ThreadsafeTest009
635  * @tc.desc: Test napi_ref_threadsafe_function and napi_unref_threadsafe_function.
636  * @tc.type: FUNC
637  * @tc.require: I5K6KF
638  */
639 HWTEST_F(NapiThreadsafeTest, ThreadsafeTest009, testing::ext::TestSize.Level1)
640 {
641     HILOG_INFO("Threadsafe_Test_0900 start");
642     napi_env env = (napi_env)engine_;
643     napi_threadsafe_function tsFunc = nullptr;
644     napi_value resourceName = 0;
645 
646     napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
647     g_jsData.id = CALL_JS_CB_DATA_TEST_ID;
648     g_finalData.id = FINAL_CB_DATA_TEST_ID;
649 
650     auto status = napi_create_threadsafe_function(env, nullptr, nullptr, resourceName,
651         0, 1, &g_finalData, TsFuncFinalCallback, &g_jsData, TsFuncCallJsFour, &tsFunc);
652     EXPECT_EQ(status, napi_ok);
653 
654     status = napi_unref_threadsafe_function(env, tsFunc);
655     EXPECT_EQ(status, napi_ok);
656 
657     status = napi_unref_threadsafe_function(env, tsFunc);
658     EXPECT_EQ(status, napi_ok);
659 
660     HILOG_INFO("Threadsafe_Test_0900 end");
661 }
662 
663 /**
664  * @tc.name: ThreadsafeTest010
665  * @tc.desc: Test napi_unref_threadsafe_function and napi_release_threadsafe_function.
666  * @tc.type: FUNC
667  * @tc.require: I5K6KF
668  */
669 HWTEST_F(NapiThreadsafeTest, ThreadsafeTest010, testing::ext::TestSize.Level1)
670 {
671     HILOG_INFO("Threadsafe_Test_1000 start");
672     napi_env env = (napi_env)engine_;
673     napi_threadsafe_function tsFunc = nullptr;
674     napi_value resourceName = 0;
675     napi_threadsafe_function_release_mode abort = napi_tsfn_abort;
676 
677     napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
678     g_jsData.id = CALL_JS_CB_DATA_TEST_ID;
679     g_finalData.id = FINAL_CB_DATA_TEST_ID;
680 
681     auto status = napi_create_threadsafe_function(env, nullptr, nullptr, resourceName,
682         0, 1, &g_finalData, TsFuncFinalCallback, &g_jsData, TsFuncCallJsFour, &tsFunc);
683     EXPECT_EQ(status, napi_ok);
684 
685     status = napi_unref_threadsafe_function(env, tsFunc);
686     EXPECT_EQ(status, napi_ok);
687 
688     status = napi_release_threadsafe_function(tsFunc, abort);
689     EXPECT_EQ(status, napi_ok);
690 
691     HILOG_INFO("Threadsafe_Test_1000 end");
692 }
693 
694 /**
695  * @tc.name: ThreadsafeTest011
696  * @tc.desc: Test napi_ref_threadsafe_function and napi_release_threadsafe_function.
697  * @tc.type: FUNC
698  * @tc.require: I5K6KF
699  */
700 HWTEST_F(NapiThreadsafeTest, ThreadsafeTest011, testing::ext::TestSize.Level1)
701 {
702     HILOG_INFO("Threadsafe_Test_1100 start");
703 
704     napi_env env = (napi_env)engine_;
705     napi_threadsafe_function tsFunc = nullptr;
706     napi_value resourceName = 0;
707     napi_threadsafe_function_release_mode abort = napi_tsfn_abort;
708 
709     napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName);
710     g_jsData.id = CALL_JS_CB_DATA_TEST_ID;
711     g_finalData.id = FINAL_CB_DATA_TEST_ID;
712 
713     auto status = napi_create_threadsafe_function(env, nullptr, nullptr, resourceName,
714         0, 1, &g_finalData, TsFuncFinalCallback, &g_jsData, TsFuncCallJsFour, &tsFunc);
715     EXPECT_EQ(status, napi_ok);
716 
717     status = napi_ref_threadsafe_function(env, tsFunc);
718     EXPECT_EQ(status, napi_ok);
719 
720     status = napi_release_threadsafe_function(tsFunc, abort);
721     EXPECT_EQ(status, napi_ok);
722 
723     HILOG_INFO("Threadsafe_Test_1100 end");
724 }