13f4cbf05Sopenharmony_ci/*
23f4cbf05Sopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd.
33f4cbf05Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
43f4cbf05Sopenharmony_ci * you may not use this file except in compliance with the License.
53f4cbf05Sopenharmony_ci * You may obtain a copy of the License at
63f4cbf05Sopenharmony_ci *
73f4cbf05Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
83f4cbf05Sopenharmony_ci *
93f4cbf05Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
103f4cbf05Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
113f4cbf05Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
123f4cbf05Sopenharmony_ci * See the License for the specific language governing permissions and
133f4cbf05Sopenharmony_ci * limitations under the License.
143f4cbf05Sopenharmony_ci */
153f4cbf05Sopenharmony_ci#include <gtest/gtest.h>
163f4cbf05Sopenharmony_ci#include "thread_ex.h"
173f4cbf05Sopenharmony_ci#include <iostream>
183f4cbf05Sopenharmony_ci#include <cstdio>
193f4cbf05Sopenharmony_ci#include <sys/prctl.h>
203f4cbf05Sopenharmony_ciusing namespace testing::ext;
213f4cbf05Sopenharmony_ciusing namespace std;
223f4cbf05Sopenharmony_ci
233f4cbf05Sopenharmony_cinamespace OHOS {
243f4cbf05Sopenharmony_cinamespace {
253f4cbf05Sopenharmony_cistatic int times = 0;
263f4cbf05Sopenharmony_ciusing ThreadRunFunc = bool (*)(int& data);
273f4cbf05Sopenharmony_ci
283f4cbf05Sopenharmony_ciclass UtilsThreadTest : public testing::Test {
293f4cbf05Sopenharmony_cipublic:
303f4cbf05Sopenharmony_ci    static void SetUpTestCase(void);
313f4cbf05Sopenharmony_ci    static void TearDownTestCase(void);
323f4cbf05Sopenharmony_ci    void SetUp();
333f4cbf05Sopenharmony_ci    void TearDown();
343f4cbf05Sopenharmony_ci};
353f4cbf05Sopenharmony_ci
363f4cbf05Sopenharmony_civoid UtilsThreadTest::SetUpTestCase(void)
373f4cbf05Sopenharmony_ci{
383f4cbf05Sopenharmony_ci    // input testsuit setup step
393f4cbf05Sopenharmony_ci}
403f4cbf05Sopenharmony_ci
413f4cbf05Sopenharmony_civoid UtilsThreadTest::TearDownTestCase(void)
423f4cbf05Sopenharmony_ci{
433f4cbf05Sopenharmony_ci    // input testsuit teardown step
443f4cbf05Sopenharmony_ci}
453f4cbf05Sopenharmony_ci
463f4cbf05Sopenharmony_civoid UtilsThreadTest::SetUp(void)
473f4cbf05Sopenharmony_ci{
483f4cbf05Sopenharmony_ci    // recover times
493f4cbf05Sopenharmony_ci    times = 0;
503f4cbf05Sopenharmony_ci}
513f4cbf05Sopenharmony_ci
523f4cbf05Sopenharmony_civoid UtilsThreadTest::TearDown(void)
533f4cbf05Sopenharmony_ci{
543f4cbf05Sopenharmony_ci    // recover times
553f4cbf05Sopenharmony_ci    times = 0;
563f4cbf05Sopenharmony_ci}
573f4cbf05Sopenharmony_ci
583f4cbf05Sopenharmony_cibool TestRun01(int& data)
593f4cbf05Sopenharmony_ci{
603f4cbf05Sopenharmony_ci    ++data;
613f4cbf05Sopenharmony_ci    return false;
623f4cbf05Sopenharmony_ci}
633f4cbf05Sopenharmony_ci
643f4cbf05Sopenharmony_cibool TestRun02(int& data)
653f4cbf05Sopenharmony_ci{
663f4cbf05Sopenharmony_ci    ++data;
673f4cbf05Sopenharmony_ci    return true;
683f4cbf05Sopenharmony_ci}
693f4cbf05Sopenharmony_ci
703f4cbf05Sopenharmony_cibool TestRun03(int& data)
713f4cbf05Sopenharmony_ci{
723f4cbf05Sopenharmony_ci    static const int TRY_TIMES = 10;
733f4cbf05Sopenharmony_ci    if (times <= TRY_TIMES) {
743f4cbf05Sopenharmony_ci        ++data;
753f4cbf05Sopenharmony_ci        return true;
763f4cbf05Sopenharmony_ci    }
773f4cbf05Sopenharmony_ci
783f4cbf05Sopenharmony_ci    return false;
793f4cbf05Sopenharmony_ci}
803f4cbf05Sopenharmony_ci
813f4cbf05Sopenharmony_ciconstexpr int DEFAULT_PRIO = 0;
823f4cbf05Sopenharmony_ciconst std::string& DEFAULT_THREAD_NAME = "default";
833f4cbf05Sopenharmony_ci
843f4cbf05Sopenharmony_ciclass TestThread : public OHOS::Thread {
853f4cbf05Sopenharmony_cipublic:
863f4cbf05Sopenharmony_ci    TestThread(const int data, const bool readyToWork, ThreadRunFunc runFunc)
873f4cbf05Sopenharmony_ci        : data_(data), priority_(DEFAULT_PRIO), name_(DEFAULT_THREAD_NAME), readyToWork_(readyToWork), runFunc_(runFunc)
883f4cbf05Sopenharmony_ci        {};
893f4cbf05Sopenharmony_ci
903f4cbf05Sopenharmony_ci    TestThread() = delete;
913f4cbf05Sopenharmony_ci    ~TestThread() {}
923f4cbf05Sopenharmony_ci
933f4cbf05Sopenharmony_ci    bool ReadyToWork() override;
943f4cbf05Sopenharmony_ci
953f4cbf05Sopenharmony_ci    int data_;
963f4cbf05Sopenharmony_ci    int priority_;
973f4cbf05Sopenharmony_ci    std::string name_;
983f4cbf05Sopenharmony_ciprotected:
993f4cbf05Sopenharmony_ci    bool Run() override;
1003f4cbf05Sopenharmony_ci
1013f4cbf05Sopenharmony_ciprivate:
1023f4cbf05Sopenharmony_ci    bool readyToWork_;
1033f4cbf05Sopenharmony_ci    ThreadRunFunc runFunc_;
1043f4cbf05Sopenharmony_ci};
1053f4cbf05Sopenharmony_ci
1063f4cbf05Sopenharmony_cibool TestThread::ReadyToWork()
1073f4cbf05Sopenharmony_ci{
1083f4cbf05Sopenharmony_ci    return readyToWork_;
1093f4cbf05Sopenharmony_ci}
1103f4cbf05Sopenharmony_ci
1113f4cbf05Sopenharmony_cibool TestThread::Run()
1123f4cbf05Sopenharmony_ci{
1133f4cbf05Sopenharmony_ci    priority_ = getpriority(PRIO_PROCESS, 0);
1143f4cbf05Sopenharmony_ci    char threadName[MAX_THREAD_NAME_LEN + 1] = {0};
1153f4cbf05Sopenharmony_ci    prctl(PR_GET_NAME, threadName, 0, 0);
1163f4cbf05Sopenharmony_ci    name_ = threadName;
1173f4cbf05Sopenharmony_ci
1183f4cbf05Sopenharmony_ci    if (runFunc_ != nullptr) {
1193f4cbf05Sopenharmony_ci        return (*runFunc_)(data_);
1203f4cbf05Sopenharmony_ci    }
1213f4cbf05Sopenharmony_ci
1223f4cbf05Sopenharmony_ci    return false;
1233f4cbf05Sopenharmony_ci}
1243f4cbf05Sopenharmony_ci
1253f4cbf05Sopenharmony_ci/*
1263f4cbf05Sopenharmony_ci * @tc.name: testThread001
1273f4cbf05Sopenharmony_ci * @tc.desc: ThreadTest
1283f4cbf05Sopenharmony_ci */
1293f4cbf05Sopenharmony_ciHWTEST_F(UtilsThreadTest, testThread001, TestSize.Level0)
1303f4cbf05Sopenharmony_ci{
1313f4cbf05Sopenharmony_ci    times = 0;
1323f4cbf05Sopenharmony_ci    std::unique_ptr<TestThread> test = std::make_unique<TestThread>(0, false, TestRun01);
1333f4cbf05Sopenharmony_ci    ThreadStatus status = test->Start("test_thread_01", THREAD_PROI_LOW, 1024);
1343f4cbf05Sopenharmony_ci    EXPECT_EQ(status == ThreadStatus::OK, true);
1353f4cbf05Sopenharmony_ci
1363f4cbf05Sopenharmony_ci    pthread_t thread = test->GetThread();
1373f4cbf05Sopenharmony_ci
1383f4cbf05Sopenharmony_ci    // pthread_equal return non-zero if equal
1393f4cbf05Sopenharmony_ci    EXPECT_EQ(pthread_equal(thread, -1) != 0, (test->IsRunning() ? false : true));
1403f4cbf05Sopenharmony_ci
1413f4cbf05Sopenharmony_ci    // ReadyToWork return false, RUN will not be called!
1423f4cbf05Sopenharmony_ci    EXPECT_EQ(test->priority_, DEFAULT_PRIO);
1433f4cbf05Sopenharmony_ci    EXPECT_EQ(test->name_, DEFAULT_THREAD_NAME);
1443f4cbf05Sopenharmony_ci
1453f4cbf05Sopenharmony_ci    // get stacksize of threa, may be different because of system memory align
1463f4cbf05Sopenharmony_ci    EXPECT_EQ(test->data_, 0);
1473f4cbf05Sopenharmony_ci    EXPECT_EQ(times, 0);
1483f4cbf05Sopenharmony_ci    test->NotifyExitSync();
1493f4cbf05Sopenharmony_ci    sleep(1);
1503f4cbf05Sopenharmony_ci    EXPECT_EQ(pthread_equal(test->GetThread(), -1) != 0, (test->IsRunning() ? false : true));
1513f4cbf05Sopenharmony_ci}
1523f4cbf05Sopenharmony_ci
1533f4cbf05Sopenharmony_ci/*
1543f4cbf05Sopenharmony_ci * @tc.name: testThread002
1553f4cbf05Sopenharmony_ci * @tc.desc: ThreadTest
1563f4cbf05Sopenharmony_ci */
1573f4cbf05Sopenharmony_ciHWTEST_F(UtilsThreadTest, testThread002, TestSize.Level0)
1583f4cbf05Sopenharmony_ci{
1593f4cbf05Sopenharmony_ci    times = 0;
1603f4cbf05Sopenharmony_ci    std::unique_ptr<TestThread> test = std::make_unique<TestThread>(0, true, TestRun01);
1613f4cbf05Sopenharmony_ci    ThreadStatus status = test->Start("test_thread_02", THREAD_PROI_LOW, 1024);
1623f4cbf05Sopenharmony_ci
1633f4cbf05Sopenharmony_ci    EXPECT_EQ(status == ThreadStatus::OK, true);
1643f4cbf05Sopenharmony_ci
1653f4cbf05Sopenharmony_ci    sleep(1); // let the new thread has chance to run
1663f4cbf05Sopenharmony_ci
1673f4cbf05Sopenharmony_ci    // pthread_equal return non-zero if equal, RUN return false,may exit already
1683f4cbf05Sopenharmony_ci    EXPECT_EQ(pthread_equal(test->GetThread(), -1) != 0, (test->IsRunning() ? false : true));
1693f4cbf05Sopenharmony_ci
1703f4cbf05Sopenharmony_ci    // ReadyToWork return true, RUN will be called!
1713f4cbf05Sopenharmony_ci    EXPECT_EQ(test->priority_, THREAD_PROI_LOW);
1723f4cbf05Sopenharmony_ci    EXPECT_EQ(test->name_, "test_thread_02");
1733f4cbf05Sopenharmony_ci
1743f4cbf05Sopenharmony_ci    EXPECT_EQ(test->data_, 1);
1753f4cbf05Sopenharmony_ci    EXPECT_EQ(times, 0);
1763f4cbf05Sopenharmony_ci    test->NotifyExitSync();
1773f4cbf05Sopenharmony_ci    sleep(1);
1783f4cbf05Sopenharmony_ci    EXPECT_EQ(pthread_equal(test->GetThread(), -1) != 0, (test->IsRunning() ? false : true));
1793f4cbf05Sopenharmony_ci}
1803f4cbf05Sopenharmony_ci
1813f4cbf05Sopenharmony_ci/*
1823f4cbf05Sopenharmony_ci * @tc.name: testThread003
1833f4cbf05Sopenharmony_ci * @tc.desc: ThreadTest
1843f4cbf05Sopenharmony_ci */
1853f4cbf05Sopenharmony_ciHWTEST_F(UtilsThreadTest, testThread003, TestSize.Level0)
1863f4cbf05Sopenharmony_ci{
1873f4cbf05Sopenharmony_ci    times = 0;
1883f4cbf05Sopenharmony_ci    std::unique_ptr<TestThread> test = std::make_unique<TestThread>(0, false, TestRun02);
1893f4cbf05Sopenharmony_ci    ThreadStatus status = test->Start("test_thread_03", THREAD_PROI_LOW, 1024);
1903f4cbf05Sopenharmony_ci    EXPECT_EQ(status == ThreadStatus::OK, true);
1913f4cbf05Sopenharmony_ci
1923f4cbf05Sopenharmony_ci    pthread_t thread = test->GetThread();
1933f4cbf05Sopenharmony_ci
1943f4cbf05Sopenharmony_ci    // pthread_equal return non-zero if equal
1953f4cbf05Sopenharmony_ci    EXPECT_EQ(pthread_equal(thread , -1) != 0, (test->IsRunning() ? false : true));
1963f4cbf05Sopenharmony_ci
1973f4cbf05Sopenharmony_ci    // ReadyToWork return false, RUN will not be called!
1983f4cbf05Sopenharmony_ci    EXPECT_EQ(test->priority_, DEFAULT_PRIO);
1993f4cbf05Sopenharmony_ci    EXPECT_EQ(test->name_, DEFAULT_THREAD_NAME);
2003f4cbf05Sopenharmony_ci
2013f4cbf05Sopenharmony_ci    EXPECT_EQ(test->data_, 0);
2023f4cbf05Sopenharmony_ci    EXPECT_EQ(times, 0);
2033f4cbf05Sopenharmony_ci    test->NotifyExitSync();
2043f4cbf05Sopenharmony_ci    sleep(1);
2053f4cbf05Sopenharmony_ci    EXPECT_EQ(pthread_equal(test->GetThread(), -1) != 0, (test->IsRunning() ? false : true));
2063f4cbf05Sopenharmony_ci}
2073f4cbf05Sopenharmony_ci
2083f4cbf05Sopenharmony_ci/*
2093f4cbf05Sopenharmony_ci * @tc.name: testThread004
2103f4cbf05Sopenharmony_ci * @tc.desc: ThreadTest
2113f4cbf05Sopenharmony_ci */
2123f4cbf05Sopenharmony_ciHWTEST_F(UtilsThreadTest, testThread004, TestSize.Level0)
2133f4cbf05Sopenharmony_ci{
2143f4cbf05Sopenharmony_ci    times = 0;
2153f4cbf05Sopenharmony_ci    std::unique_ptr<TestThread> test = std::make_unique<TestThread>(0, true, TestRun02);
2163f4cbf05Sopenharmony_ci    ThreadStatus status = test->Start("test_thread_04", THREAD_PROI_LOW, 1024);
2173f4cbf05Sopenharmony_ci
2183f4cbf05Sopenharmony_ci    EXPECT_EQ(status == ThreadStatus::OK, true);
2193f4cbf05Sopenharmony_ci
2203f4cbf05Sopenharmony_ci    sleep(1); // let the new thread has chance to run
2213f4cbf05Sopenharmony_ci
2223f4cbf05Sopenharmony_ci    // pthread_equal return non-zero if equal, RUN return false,may exit already
2233f4cbf05Sopenharmony_ci    EXPECT_EQ(pthread_equal(test->GetThread(), -1) != 0, (test->IsRunning() ? false : true));
2243f4cbf05Sopenharmony_ci
2253f4cbf05Sopenharmony_ci    // ReadyToWork return true, RUN will be called!
2263f4cbf05Sopenharmony_ci    EXPECT_EQ(test->priority_, THREAD_PROI_LOW);
2273f4cbf05Sopenharmony_ci    EXPECT_EQ(test->name_, "test_thread_04");
2283f4cbf05Sopenharmony_ci
2293f4cbf05Sopenharmony_ci    EXPECT_GT(test->data_, 1);
2303f4cbf05Sopenharmony_ci    EXPECT_EQ(times, 0);
2313f4cbf05Sopenharmony_ci    test->NotifyExitSync();
2323f4cbf05Sopenharmony_ci    sleep(1);
2333f4cbf05Sopenharmony_ci    EXPECT_EQ(pthread_equal(test->GetThread(), -1) != 0, (test->IsRunning() ? false : true));
2343f4cbf05Sopenharmony_ci}
2353f4cbf05Sopenharmony_ci
2363f4cbf05Sopenharmony_ci/*
2373f4cbf05Sopenharmony_ci * @tc.name: testThread005
2383f4cbf05Sopenharmony_ci * @tc.desc: ThreadTest
2393f4cbf05Sopenharmony_ci */
2403f4cbf05Sopenharmony_ciHWTEST_F(UtilsThreadTest, testThread005, TestSize.Level0)
2413f4cbf05Sopenharmony_ci{
2423f4cbf05Sopenharmony_ci    times = 0;
2433f4cbf05Sopenharmony_ci    std::unique_ptr<TestThread> test = std::make_unique<TestThread>(0, false, TestRun03);
2443f4cbf05Sopenharmony_ci    ThreadStatus status = test->Start("test_thread_05", THREAD_PROI_LOW, 1024);
2453f4cbf05Sopenharmony_ci    EXPECT_EQ(status == ThreadStatus::OK, true);
2463f4cbf05Sopenharmony_ci
2473f4cbf05Sopenharmony_ci    pthread_t thread = test->GetThread();
2483f4cbf05Sopenharmony_ci
2493f4cbf05Sopenharmony_ci    // pthread_equal return non-zero if equal
2503f4cbf05Sopenharmony_ci    EXPECT_EQ(pthread_equal(thread , -1) != 0, (test->IsRunning() ? false : true));
2513f4cbf05Sopenharmony_ci
2523f4cbf05Sopenharmony_ci    // ReadyToWork return false, RUN will not be called!
2533f4cbf05Sopenharmony_ci    EXPECT_EQ(test->priority_, DEFAULT_PRIO);
2543f4cbf05Sopenharmony_ci    EXPECT_EQ(test->name_, DEFAULT_THREAD_NAME);
2553f4cbf05Sopenharmony_ci
2563f4cbf05Sopenharmony_ci    EXPECT_EQ(test->data_, 0);
2573f4cbf05Sopenharmony_ci    EXPECT_EQ(times, 0);
2583f4cbf05Sopenharmony_ci    test->NotifyExitSync();
2593f4cbf05Sopenharmony_ci    sleep(1);
2603f4cbf05Sopenharmony_ci    EXPECT_EQ(pthread_equal(test->GetThread(), -1) != 0, (test->IsRunning() ? false : true));
2613f4cbf05Sopenharmony_ci}
2623f4cbf05Sopenharmony_ci
2633f4cbf05Sopenharmony_ci/*
2643f4cbf05Sopenharmony_ci * @tc.name: testThread006
2653f4cbf05Sopenharmony_ci * @tc.desc: ThreadTest
2663f4cbf05Sopenharmony_ci */
2673f4cbf05Sopenharmony_ciHWTEST_F(UtilsThreadTest, testThread006, TestSize.Level0)
2683f4cbf05Sopenharmony_ci{
2693f4cbf05Sopenharmony_ci    times = 0;
2703f4cbf05Sopenharmony_ci    std::unique_ptr<TestThread> test = std::make_unique<TestThread>(0, true, TestRun03);
2713f4cbf05Sopenharmony_ci    ThreadStatus status = test->Start("test_thread_06", THREAD_PROI_LOW, 1024);
2723f4cbf05Sopenharmony_ci
2733f4cbf05Sopenharmony_ci    EXPECT_EQ(status == ThreadStatus::OK, true);
2743f4cbf05Sopenharmony_ci
2753f4cbf05Sopenharmony_ci    sleep(1); // let the new thread has chance to run
2763f4cbf05Sopenharmony_ci
2773f4cbf05Sopenharmony_ci    // pthread_equal return non-zero if equal, RUN return false,may exit already
2783f4cbf05Sopenharmony_ci    EXPECT_EQ(pthread_equal(test->GetThread(), -1) != 0, (test->IsRunning() ? false : true));
2793f4cbf05Sopenharmony_ci
2803f4cbf05Sopenharmony_ci    // ReadyToWork return true, RUN will be called!
2813f4cbf05Sopenharmony_ci    EXPECT_EQ(test->priority_, THREAD_PROI_LOW);
2823f4cbf05Sopenharmony_ci    EXPECT_EQ(test->name_, "test_thread_06");
2833f4cbf05Sopenharmony_ci
2843f4cbf05Sopenharmony_ci    EXPECT_GT(test->data_, 10);
2853f4cbf05Sopenharmony_ci    EXPECT_EQ(times, 0);
2863f4cbf05Sopenharmony_ci
2873f4cbf05Sopenharmony_ci    times = 100;
2883f4cbf05Sopenharmony_ci    EXPECT_GT(test->data_, 10);
2893f4cbf05Sopenharmony_ci
2903f4cbf05Sopenharmony_ci    sleep(1); // let the new thread has chance to run
2913f4cbf05Sopenharmony_ci
2923f4cbf05Sopenharmony_ci    // times > 10, TestRun03 return false, thread exit
2933f4cbf05Sopenharmony_ci    EXPECT_EQ(pthread_equal(test->GetThread(), -1) != 0, (test->IsRunning() ? false : true));
2943f4cbf05Sopenharmony_ci}
2953f4cbf05Sopenharmony_ci
2963f4cbf05Sopenharmony_ci/*
2973f4cbf05Sopenharmony_ci * @tc.name: testThread007
2983f4cbf05Sopenharmony_ci * @tc.desc: ThreadTest
2993f4cbf05Sopenharmony_ci */
3003f4cbf05Sopenharmony_ciHWTEST_F(UtilsThreadTest, testThread007, TestSize.Level0)
3013f4cbf05Sopenharmony_ci{
3023f4cbf05Sopenharmony_ci    times = 0;
3033f4cbf05Sopenharmony_ci    std::unique_ptr<TestThread> test = std::make_unique<TestThread>(0, true, TestRun03);
3043f4cbf05Sopenharmony_ci    ThreadStatus status = test->Start("", THREAD_PROI_LOW, 0);
3053f4cbf05Sopenharmony_ci
3063f4cbf05Sopenharmony_ci    EXPECT_EQ(status == ThreadStatus::OK, true);
3073f4cbf05Sopenharmony_ci    if (test->IsRunning()) {
3083f4cbf05Sopenharmony_ci        status = test->Start("", THREAD_PROI_NORMAL, 1024);
3093f4cbf05Sopenharmony_ci        EXPECT_EQ(status == ThreadStatus::INVALID_OPERATION, true);
3103f4cbf05Sopenharmony_ci
3113f4cbf05Sopenharmony_ci        test->NotifyExitSync();
3123f4cbf05Sopenharmony_ci        EXPECT_EQ(pthread_equal(test->GetThread(), -1) != 0, (test->IsRunning() ? false : true));
3133f4cbf05Sopenharmony_ci    }
3143f4cbf05Sopenharmony_ci
3153f4cbf05Sopenharmony_ci    sleep(1); // let the new thread has chance to run
3163f4cbf05Sopenharmony_ci
3173f4cbf05Sopenharmony_ci    EXPECT_EQ(pthread_equal(test->GetThread(), -1) != 0, (test->IsRunning() ? false : true));
3183f4cbf05Sopenharmony_ci}
3193f4cbf05Sopenharmony_ci
3203f4cbf05Sopenharmony_ci/*
3213f4cbf05Sopenharmony_ci * @tc.name: testThread008
3223f4cbf05Sopenharmony_ci * @tc.desc: ThreadTest
3233f4cbf05Sopenharmony_ci */
3243f4cbf05Sopenharmony_ciHWTEST_F(UtilsThreadTest, testThread008, TestSize.Level0)
3253f4cbf05Sopenharmony_ci{
3263f4cbf05Sopenharmony_ci    times = 0;
3273f4cbf05Sopenharmony_ci    std::unique_ptr<TestThread> test = std::make_unique<TestThread>(0, true, TestRun03);
3283f4cbf05Sopenharmony_ci
3293f4cbf05Sopenharmony_ci    bool res = test->Thread::ReadyToWork();
3303f4cbf05Sopenharmony_ci    EXPECT_EQ(res, true);
3313f4cbf05Sopenharmony_ci
3323f4cbf05Sopenharmony_ci    ThreadStatus status = test->Start("", THREAD_PROI_NORMAL, 1024);
3333f4cbf05Sopenharmony_ci    EXPECT_EQ(status == ThreadStatus::OK, true);
3343f4cbf05Sopenharmony_ci
3353f4cbf05Sopenharmony_ci    sleep(1);
3363f4cbf05Sopenharmony_ci    test->NotifyExitAsync();
3373f4cbf05Sopenharmony_ci
3383f4cbf05Sopenharmony_ci    sleep(1); // let the new thread has chance to run
3393f4cbf05Sopenharmony_ci    EXPECT_EQ(pthread_equal(test->GetThread(), -1) != 0, (test->IsRunning() ? false : true));
3403f4cbf05Sopenharmony_ci}
3413f4cbf05Sopenharmony_ci
3423f4cbf05Sopenharmony_ciclass TestThread2 : public OHOS::Thread {
3433f4cbf05Sopenharmony_cipublic:
3443f4cbf05Sopenharmony_ci    TestThread2(const int data, ThreadRunFunc runFunc)
3453f4cbf05Sopenharmony_ci        : data_(data), priority_(DEFAULT_PRIO), name_(DEFAULT_THREAD_NAME), runFunc_(runFunc)
3463f4cbf05Sopenharmony_ci        {};
3473f4cbf05Sopenharmony_ci
3483f4cbf05Sopenharmony_ci    TestThread2() = delete;
3493f4cbf05Sopenharmony_ci    ~TestThread2() {}
3503f4cbf05Sopenharmony_ci
3513f4cbf05Sopenharmony_ci    int data_;
3523f4cbf05Sopenharmony_ci    int priority_;
3533f4cbf05Sopenharmony_ci    std::string name_;
3543f4cbf05Sopenharmony_ciprotected:
3553f4cbf05Sopenharmony_ci    bool Run() override;
3563f4cbf05Sopenharmony_ci
3573f4cbf05Sopenharmony_ciprivate:
3583f4cbf05Sopenharmony_ci    ThreadRunFunc runFunc_;
3593f4cbf05Sopenharmony_ci};
3603f4cbf05Sopenharmony_ci
3613f4cbf05Sopenharmony_cibool TestThread2::Run()
3623f4cbf05Sopenharmony_ci{
3633f4cbf05Sopenharmony_ci    priority_ = getpriority(PRIO_PROCESS, 0);
3643f4cbf05Sopenharmony_ci    char threadName[MAX_THREAD_NAME_LEN + 1] = {0};
3653f4cbf05Sopenharmony_ci    prctl(PR_GET_NAME, threadName, 0, 0);
3663f4cbf05Sopenharmony_ci    name_ = threadName;
3673f4cbf05Sopenharmony_ci
3683f4cbf05Sopenharmony_ci    if (runFunc_ != nullptr) {
3693f4cbf05Sopenharmony_ci        return (*runFunc_)(data_);
3703f4cbf05Sopenharmony_ci    }
3713f4cbf05Sopenharmony_ci
3723f4cbf05Sopenharmony_ci    return false;
3733f4cbf05Sopenharmony_ci}
3743f4cbf05Sopenharmony_ci
3753f4cbf05Sopenharmony_ci/*
3763f4cbf05Sopenharmony_ci * @tc.name: testThread009
3773f4cbf05Sopenharmony_ci * @tc.desc: ThreadTest
3783f4cbf05Sopenharmony_ci */
3793f4cbf05Sopenharmony_ciHWTEST_F(UtilsThreadTest, testThread009, TestSize.Level0)
3803f4cbf05Sopenharmony_ci{
3813f4cbf05Sopenharmony_ci    times = 0;
3823f4cbf05Sopenharmony_ci    std::unique_ptr<TestThread2> test = std::make_unique<TestThread2>(0, TestRun03);
3833f4cbf05Sopenharmony_ci
3843f4cbf05Sopenharmony_ci    bool res = test->ReadyToWork();
3853f4cbf05Sopenharmony_ci    EXPECT_EQ(res, true);
3863f4cbf05Sopenharmony_ci
3873f4cbf05Sopenharmony_ci    ThreadStatus status = test->Start("", THREAD_PROI_NORMAL, 1024);
3883f4cbf05Sopenharmony_ci    EXPECT_EQ(status == ThreadStatus::OK, true);
3893f4cbf05Sopenharmony_ci
3903f4cbf05Sopenharmony_ci    sleep(1);
3913f4cbf05Sopenharmony_ci    test->NotifyExitAsync();
3923f4cbf05Sopenharmony_ci
3933f4cbf05Sopenharmony_ci    sleep(1); // let the new thread has chance to run
3943f4cbf05Sopenharmony_ci    EXPECT_EQ(pthread_equal(test->GetThread(), -1) != 0, (test->IsRunning() ? false : true));
3953f4cbf05Sopenharmony_ci}
3963f4cbf05Sopenharmony_ci
3973f4cbf05Sopenharmony_ci}  // namespace
3983f4cbf05Sopenharmony_ci}  // namespace OHOS