diff --git a/frameworks/base/test/mock/mock_task_executor.h b/frameworks/base/test/mock/mock_task_executor.h index a1237584eb3..86b3e23d4fd 100644 --- a/frameworks/base/test/mock/mock_task_executor.h +++ b/frameworks/base/test/mock/mock_task_executor.h @@ -45,6 +45,19 @@ public: { return std::move(task); } + uint32_t GetTotalTaskNum(TaskType type) override + { + switch (type) { + case TaskType::PLATFORM: + case TaskType::UI: + case TaskType::IO: + case TaskType::GPU: + case TaskType::JS: + case TaskType::BACKGROUND: + default: + return 10; + } + } private: bool OnPostTask(Task&& task, TaskType type, uint32_t delayTime) const final diff --git a/frameworks/core/common/watch_dog.cpp b/frameworks/core/common/watch_dog.cpp index f2612be56c0..a5f1cb9b3a4 100644 --- a/frameworks/core/common/watch_dog.cpp +++ b/frameworks/core/common/watch_dog.cpp @@ -44,8 +44,6 @@ constexpr uint64_t ANR_INPUT_FREEZE_TIME = 5000; constexpr int32_t IMMEDIATELY_PERIOD = 0; constexpr int32_t ANR_DIALOG_BLOCK_TIME = 20; -enum class State { NORMAL, WARNING, FREEZE }; - #if defined(OHOS_PLATFORM) || defined(ANDROID_PLATFORM) constexpr int32_t SIGNAL_FOR_GC = 60; constexpr int32_t GC_CHECK_PERIOD = 1; @@ -115,47 +113,6 @@ void InitializeGcTrigger() } // namespace -class ThreadWatcher final : public Referenced { -public: - ThreadWatcher(int32_t instanceId, TaskExecutor::TaskType type, bool useUIAsJSThread = false); - ~ThreadWatcher() override; - - void SetTaskExecutor(const RefPtr& taskExecutor); - - void BuriedBomb(uint64_t bombId); - void DefusingBomb(); - -private: - void InitThreadName(); - void CheckAndResetIfNeeded(); - bool IsThreadStuck(); - void HiviewReport() const; - void RawReport(RawEventType type) const; - void PostCheckTask(); - void TagIncrease(); - void Check(); - void ShowDialog() const; - void DefusingTopBomb(); - void DetonatedBomb(); - - mutable std::shared_mutex mutex_; - int32_t instanceId_ = 0; - TaskExecutor::TaskType type_; - std::string threadName_; - int32_t loopTime_ = 0; - int32_t threadTag_ = 0; - int32_t lastLoopTime_ = 0; - int32_t lastThreadTag_ = 0; - int32_t freezeCount_ = 0; - int64_t lastTaskId_ = -1; - State state_ = State::NORMAL; - WeakPtr taskExecutor_; - std::queue inputTaskIds_; - bool canShowDialog_ = true; - int32_t showDialogCount_ = 0; - bool useUIAsJSThread_ = false; -}; - ThreadWatcher::ThreadWatcher(int32_t instanceId, TaskExecutor::TaskType type, bool useUIAsJSThread) : instanceId_(instanceId), type_(type), useUIAsJSThread_(useUIAsJSThread) { @@ -493,4 +450,4 @@ void WatchDog::DefusingBomb(int32_t instanceId) IMMEDIATELY_PERIOD); } -} // namespace OHOS::Ace \ No newline at end of file +} // namespace OHOS::Ace diff --git a/test/mock/bridge/common/utils/mock_engine_helper.cpp b/test/mock/bridge/common/utils/mock_engine_helper.cpp new file mode 100644 index 00000000000..0ed0763a2ed --- /dev/null +++ b/test/mock/bridge/common/utils/mock_engine_helper.cpp @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include +#include +#include + +#include "bridge/common/utils/engine_helper.h" +#include "test/mock/core/common/mock_container.h" + +namespace OHOS::Ace { +namespace { +const int32_t INSTANCE_ID = 1000; +} + +std::shared_mutex EngineHelper::mutex_; +std::unordered_map> EngineHelper::engineWeakMap_; + +ScopedDelegate::ScopedDelegate(Framework::FrontendDelegate* delegate, int32_t id) + : delegate_(delegate), scope_(new ContainerScope(id)) +{} + +ScopedDelegate::~ScopedDelegate() {} + +void EngineHelper::AddEngine(int32_t id, WeakPtr engine) {} + +RefPtr EngineHelper::GetEngine(int32_t id) +{ + return nullptr; +} + +void EngineHelper::RemoveEngine(int32_t id) {} + +RefPtr EngineHelper::GetCurrentEngine() +{ + return GetEngine(Container::CurrentId()); +} + +ScopedDelegate EngineHelper::GetCurrentDelegate() +{ + return { nullptr, INSTANCE_ID }; +} + +} // namespace OHOS::Ace diff --git a/test/mock/core/common/mock_ace_engine.cpp b/test/mock/core/common/mock_ace_engine.cpp new file mode 100644 index 00000000000..eaac78f8e69 --- /dev/null +++ b/test/mock/core/common/mock_ace_engine.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "core/common/ace_engine.h" + +namespace OHOS::Ace { + +AceEngine::AceEngine() {} + +AceEngine::~AceEngine() {} +AceEngine& AceEngine::Get() +{ + static AceEngine engine; + return engine; +} + +void AceEngine::InitJsDumpHeadSignal() {} + +void AceEngine::AddContainer(int32_t instanceId, const RefPtr& container) {} + +void AceEngine::RemoveContainer(int32_t instanceId) {} + +RefPtr AceEngine::GetContainer(int32_t instanceId) +{ + return nullptr; +} + +void AceEngine::RegisterToWatchDog(int32_t instanceId, const RefPtr& taskExecutor, bool useUIAsJSThread) +{} + +void AceEngine::UnRegisterFromWatchDog(int32_t instanceId) {} + +void AceEngine::BuriedBomb(int32_t instanceId, uint64_t bombId) {} + +void AceEngine::DefusingBomb(int32_t instanceId) {} + +void AceEngine::TriggerGarbageCollection() {} + +void AceEngine::NotifyContainers(const std::function&)>& callback) {} + +void AceEngine::DumpJsHeap(bool isPrivate) const {} + +} // namespace OHOS::Ace diff --git a/test/mock/core/common/mock_anr_thread.cpp b/test/mock/core/common/mock_anr_thread.cpp new file mode 100644 index 00000000000..21c067454d9 --- /dev/null +++ b/test/mock/core/common/mock_anr_thread.cpp @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "core/common/anr_thread.h" + +namespace OHOS::Ace { + +void AnrThread::Start() {} + +void AnrThread::Stop() {} + +bool AnrThread::PostTaskToTaskRunner(Task&& task, uint32_t delayTime) +{ + return true; +} +} // namespace OHOS::Ace diff --git a/test/unittest/core/common/ace_engine/ace_engine_test.cpp b/test/unittest/core/common/ace_engine/ace_engine_test.cpp index c3f2f295a04..89faf10cbe7 100644 --- a/test/unittest/core/common/ace_engine/ace_engine_test.cpp +++ b/test/unittest/core/common/ace_engine/ace_engine_test.cpp @@ -57,20 +57,51 @@ void AceEngineTest::TearDownTestCase() MockContainer::TearDown(); } +/** + * @tc.name: AddContainer01 + * @tc.desc: Verify the AddContainer Interface of AceEngine work correctly. + * @tc.type: FUNC + */ HWTEST_F(AceEngineTest, AddContainer01, TestSize.Level1) { + /** + * @tc.steps: step1. Build an AceEngine. + */ AceEngine& aceEngine = AceEngine::Get(); + /** + * @tc.steps: step2. Add Container. + * @tc.expected: step2. Add Container success. + */ aceEngine.AddContainer(CONTAINER_INSTANCE_ID, MockContainer::container_); - EXPECT_TRUE(aceEngine.GetContainer(CONTAINER_INSTANCE_ID) != nullptr); + EXPECT_NE(aceEngine.GetContainer(CONTAINER_INSTANCE_ID), nullptr); + + /** + * @tc.steps: step3. Remove Container. + * @tc.expected: step3. Remove Container success. + */ aceEngine.RemoveContainer(CONTAINER_INSTANCE_ID); - EXPECT_TRUE(aceEngine.GetContainer(CONTAINER_INSTANCE_ID) == nullptr); + EXPECT_EQ(aceEngine.GetContainer(CONTAINER_INSTANCE_ID), nullptr); } +/** + * @tc.name: InitJsDumpHeadSignal01 + * @tc.desc: Verify the InitJsDumpHeadSignal Interface of AceEngine work correctly. + * @tc.type: FUNC + */ HWTEST_F(AceEngineTest, InitJsDumpHeadSignal01, TestSize.Level1) { + /** + * @tc.steps: step1. Build an AceEngine. + */ AceEngine& aceEngine = AceEngine::Get(); + /** + * @tc.steps: step2. Add Container. + * @tc.expected: call DumpHeapSnapshot 2 times. + * @tc.steps: step2. InitJsDumpHeadSignal. + * @tc.steps: step2. Raise two signals. + */ aceEngine.AddContainer(CONTAINER_INSTANCE_ID, MockContainer::container_); EXPECT_CALL(*(MockContainer::container_), DumpHeapSnapshot(_)) .Times(2); @@ -79,11 +110,24 @@ HWTEST_F(AceEngineTest, InitJsDumpHeadSignal01, TestSize.Level1) raise(40); } +/** + * @tc.name: TriggerGarbageCollection01 + * @tc.desc: Verify the TriggerGarbageCollection Interface of AceEngine work correctly. + * @tc.type: FUNC + */ HWTEST_F(AceEngineTest, TriggerGarbageCollection01, TestSize.Level1) { + /** + * @tc.steps: step1. Build an AceEngine. + */ AceEngine& aceEngine = AceEngine::Get(); + + /** + * @tc.steps: step2. Add Container. + * @tc.expected: call GetTaskExecutor and TriggerGarbageCollection once; + * @tc.steps: step2. TriggerGarbageCollection. + */ aceEngine.AddContainer(CONTAINER_INSTANCE_ID, MockContainer::container_); - EXPECT_CALL(*(MockContainer::container_), GetTaskExecutor()) .Times(1) .WillRepeatedly(Return(MOCK_TASK_EXECUTOR)); diff --git a/test/unittest/core/common/watch_dog/BUILD.gn b/test/unittest/core/common/watch_dog/BUILD.gn new file mode 100644 index 00000000000..47d53c303a2 --- /dev/null +++ b/test/unittest/core/common/watch_dog/BUILD.gn @@ -0,0 +1,40 @@ +# Copyright (c) 2023 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/test.gni") +import("//foundation/arkui/ace_engine/test/unittest/ace_unittest.gni") + +ohos_unittest("watch_dog_test") { + module_out_path = "$basic_test_output_path/common" + + sources = [ + "$ace_root/test/mock/core/common/mock_ace_engine.cpp", + "$ace_root/frameworks/core/common/watch_dog.cpp", + "$ace_root/test/mock/core/common/mock_anr_thread.cpp", + "$ace_root/test/mock/base/mock_event_report.cpp", + "$ace_root/test/mock/core/common/mock_container.cpp", + "$ace_root/test/mock/bridge/common/utils/mock_engine_helper.cpp", + "$ace_root/frameworks/core/common/test/mock/mock_ace_application_info.cpp", + "$ace_root/frameworks/base/test/mock/mock_background_task_executor.cpp", + "watch_dog_test.cpp", + "thread_watcher_test.cpp", + ] + + deps = [ + "$ace_root/frameworks/base:ace_memory_monitor_ohos", + "$ace_root/test/unittest:ace_unittest_log", + "//third_party/googletest:gmock_main", + ] + + configs = [ "$ace_root/test/unittest:ace_unittest_config" ] +} diff --git a/test/unittest/core/common/watch_dog/thread_watcher_test.cpp b/test/unittest/core/common/watch_dog/thread_watcher_test.cpp new file mode 100644 index 00000000000..e65826b6b55 --- /dev/null +++ b/test/unittest/core/common/watch_dog/thread_watcher_test.cpp @@ -0,0 +1,381 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "gtest/gtest.h" +#define private public +#define protected public +#include "base/memory/ace_type.h" +#include "base/test/mock/mock_task_executor.h" +#include "base/thread/task_executor.h" +#include "core/common/watch_dog.h" +#include "base/memory/referenced.h" +using namespace testing; +using namespace testing::ext; + +namespace OHOS::Ace { +namespace { +const int32_t INSTANCE_ID = 777; +const TaskExecutor::TaskType TASK_TYPE1 = TaskExecutor::TaskType::JS; +const TaskExecutor::TaskType TASK_TYPE2 = TaskExecutor::TaskType::UI; +const TaskExecutor::TaskType TASK_TYPE = TaskExecutor::TaskType::UNKNOWN; +constexpr char JS_THREAD_NAME[] = "JS"; +constexpr char UI_THREAD_NAME[] = "UI"; +constexpr char UNKNOWN_THREAD_NAME[] = "unknown thread"; +const uint64_t BOMB_ID = 10000; +RefPtr MOCK_TASK_EXECUTOR; +} // namespace + +class ThreadWatcherTest : public testing::Test { +public: +static void SetUpTestCase(); +static void TearDownTestCase(){} +void SetUp() {} +void TearDown() {} +}; +void ThreadWatcherTest::SetUpTestCase(){ + MOCK_TASK_EXECUTOR = AceType::MakeRefPtr(); +}; + +/** + * @tc.name: SetTaskExecutor01 + * @tc.desc: Verify the SetTaskExecutor Interface of ThreadWatcher work correctly. + * @tc.type: FUNC + */ +HWTEST_F(ThreadWatcherTest, SetTaskExecutor01, TestSize.Level1) +{ + /** + * @tc.steps: step1. Build a ThreadWatcher. + */ + ThreadWatcher threadWatcher_(INSTANCE_ID, TASK_TYPE, false); + + /** + * @tc.steps: step2. SetTaskExecutor. + * @tc.expected: SetTaskExecutor success. + */ + threadWatcher_.SetTaskExecutor(MOCK_TASK_EXECUTOR); + EXPECT_EQ(threadWatcher_.taskExecutor_, MOCK_TASK_EXECUTOR); +} + +/** + * @tc.name: BuriedBomb01 + * @tc.desc: Verify the BuriedBomb Interface of ThreadWatcher work correctly. + * @tc.type: FUNC + */ +HWTEST_F(ThreadWatcherTest, BuriedBomb01, TestSize.Level1) +{ + /** + * @tc.steps: step1. Build a ThreadWatcher. + */ + ThreadWatcher threadWatcher_(INSTANCE_ID, TASK_TYPE, false); + + /** + * @tc.steps: step2. BuriedBomb. + * @tc.expected: BuriedBomb success. + */ + threadWatcher_.BuriedBomb(BOMB_ID); + EXPECT_EQ(threadWatcher_.inputTaskIds_.back(), BOMB_ID); + + /** + * @tc.steps: step3. DefusingTopBomb. + * @tc.expected: DefusingTopBomb success. + */ + threadWatcher_.DefusingTopBomb(); + EXPECT_TRUE(threadWatcher_.inputTaskIds_.empty()); +} + +/** + * @tc.name: InitThreadName01 + * @tc.desc: Verify the InitThreadName Interface of ThreadWatcher work correctly. + * @tc.type: FUNC + */ +HWTEST_F(ThreadWatcherTest, InitThreadName01, TestSize.Level1) +{ + /** + * @tc.steps: step1. Build a ThreadWatcher. + */ + ThreadWatcher threadWatcher_1(INSTANCE_ID, TASK_TYPE, false); + + /** + * @tc.steps: step2. InitThreadName. + * @tc.expected: InitThreadName success. + */ + threadWatcher_1.InitThreadName(); + EXPECT_EQ(threadWatcher_1.threadName_, UNKNOWN_THREAD_NAME); + + /** + * @tc.steps: step3. Build a ThreadWatcher. + */ + ThreadWatcher threadWatcher_2(INSTANCE_ID, TASK_TYPE1, false); + + /** + * @tc.steps: step4. InitThreadName. + * @tc.expected: InitThreadName success. + */ + threadWatcher_2.InitThreadName(); + EXPECT_EQ(threadWatcher_2.threadName_, JS_THREAD_NAME); + + /** + * @tc.steps: step5. Build a ThreadWatcher. + */ + ThreadWatcher threadWatcher_3(INSTANCE_ID, TASK_TYPE2, false); + + /** + * @tc.steps: step6. InitThreadName. + * @tc.expected: InitThreadName success. + */ + threadWatcher_3.InitThreadName(); + EXPECT_EQ(threadWatcher_3.threadName_, UI_THREAD_NAME); +} + +/** + * @tc.name: CheckAndResetIfNeeded01 + * @tc.desc: Verify the CheckAndResetIfNeeded Interface of ThreadWatcher work correctly. + * @tc.type: FUNC + */ +HWTEST_F(ThreadWatcherTest, CheckAndResetIfNeeded01, TestSize.Level1) +{ + /** + * @tc.steps: step1. Build a ThreadWatcher. + */ + ThreadWatcher threadWatcher_(INSTANCE_ID, TASK_TYPE, false); + threadWatcher_.loopTime_ = 10; + + /** + * @tc.steps: step2. CheckAndResetIfNeeded. + * @tc.expected: CheckAndResetIfNeeded success. + */ + threadWatcher_.CheckAndResetIfNeeded(); + EXPECT_EQ(threadWatcher_.loopTime_, 10); + + /** + * @tc.steps: step3. Set loopTime_ with INT32_MAX. + * @tc.steps: step3. CheckAndResetIfNeeded. + * @tc.expected: CheckAndResetIfNeeded success. + */ + threadWatcher_.loopTime_ = INT32_MAX; + threadWatcher_.CheckAndResetIfNeeded(); + EXPECT_EQ(threadWatcher_.loopTime_, 0); +} + +/** + * @tc.name: IsThreadStuck01 + * @tc.desc: Verify the IsThreadStuck Interface of ThreadWatcher work correctly. + * @tc.type: FUNC + */ +HWTEST_F(ThreadWatcherTest, IsThreadStuck01, TestSize.Level1) +{ + /** + * @tc.steps: step1. Build a ThreadWatcher. + */ + ThreadWatcher threadWatcher_(INSTANCE_ID, TASK_TYPE, false); + + /** + * @tc.steps: step2. SetTaskExecutor. + * @tc.steps: step2. IsThreadStuck. + * @tc.expected: step2 return true. + */ + threadWatcher_.SetTaskExecutor(MOCK_TASK_EXECUTOR); + threadWatcher_.loopTime_ = 10; + threadWatcher_.threadTag_ = 8; + threadWatcher_.lastLoopTime_ = 9; + threadWatcher_.lastThreadTag_ = 8; + threadWatcher_.lastTaskId_ = 10; + EXPECT_TRUE(threadWatcher_.IsThreadStuck()); + + /** + * @tc.steps: step2. Change lastTaskId. + * @tc.steps: step2. IsThreadStuck. + * @tc.expected: step2 return false. + */ + threadWatcher_.loopTime_ = 10; + threadWatcher_.threadTag_ = 8; + threadWatcher_.lastLoopTime_ = 9; + threadWatcher_.lastThreadTag_ = 8; + threadWatcher_.lastTaskId_ = 15; + EXPECT_FALSE(threadWatcher_.IsThreadStuck()); +} + +/** + * @tc.name: TagIncrease01 + * @tc.desc: Verify the TagIncrease Interface of ThreadWatcher work correctly. + * @tc.type: FUNC + */ +HWTEST_F(ThreadWatcherTest, TagIncrease01, TestSize.Level1) +{ + /** + * @tc.steps: step1. Build a ThreadWatcher. + */ + ThreadWatcher threadWatcher_(INSTANCE_ID, TASK_TYPE, false); + + /** + * @tc.steps: step2. TagIncrease. + * @tc.expected: TagIncrease success. + */ + threadWatcher_.threadTag_ = 10; + threadWatcher_.TagIncrease(); + EXPECT_EQ(threadWatcher_.threadTag_, 11); +} + +/** + * @tc.name: Check01 + * @tc.desc: Verify the Check Interface of ThreadWatcher work correctly. + * @tc.type: FUNC + */ +HWTEST_F(ThreadWatcherTest, Check01, TestSize.Level1) +{ + /** + * @tc.steps: step1. Build a ThreadWatcher. + */ + ThreadWatcher threadWatcher_(INSTANCE_ID, TASK_TYPE, false); + + /** + * @tc.steps: step2. SetTaskExecutor. + * @tc.steps: step2. Check. + * @tc.expected: Check success. + */ + threadWatcher_.SetTaskExecutor(MOCK_TASK_EXECUTOR); + threadWatcher_.loopTime_ = 10; + threadWatcher_.threadTag_ = 8; + threadWatcher_.lastLoopTime_ = 9; + threadWatcher_.lastThreadTag_ = 8; + threadWatcher_.lastTaskId_ = 15; + threadWatcher_.Check(); + EXPECT_EQ(threadWatcher_.freezeCount_, 0); + EXPECT_EQ(threadWatcher_.state_, State::NORMAL); + EXPECT_TRUE(threadWatcher_.canShowDialog_); + EXPECT_EQ(threadWatcher_.showDialogCount_, 0); +} + +/** + * @tc.name: Check02 + * @tc.desc: Verify the Check Interface of ThreadWatcher work correctly. + * @tc.type: FUNC + */ +HWTEST_F(ThreadWatcherTest, Check02, TestSize.Level1) +{ + /** + * @tc.steps: step1. Build a ThreadWatcher. + */ + ThreadWatcher threadWatcher_(INSTANCE_ID, TASK_TYPE, false); + + /** + * @tc.steps: step2. SetTaskExecutor. + * @tc.steps: step2. Check. + * @tc.expected: Check success. + */ + threadWatcher_.SetTaskExecutor(MOCK_TASK_EXECUTOR); + threadWatcher_.loopTime_ = 10; + threadWatcher_.threadTag_ = 8; + threadWatcher_.lastLoopTime_ = 9; + threadWatcher_.lastThreadTag_ = 8; + threadWatcher_.lastTaskId_ = 10; + threadWatcher_.state_ = State::NORMAL; + threadWatcher_.Check(); + EXPECT_EQ(threadWatcher_.state_, State::WARNING); +} + +/** + * @tc.name: Check03 + * @tc.desc: Verify the Check Interface of ThreadWatcher work correctly. + * @tc.type: FUNC + */ +HWTEST_F(ThreadWatcherTest, Check03, TestSize.Level1) +{ + /** + * @tc.steps: step1. Build a ThreadWatcher. + */ + ThreadWatcher threadWatcher_(INSTANCE_ID, TASK_TYPE, false); + + /** + * @tc.steps: step2. SetTaskExecutor. + * @tc.steps: step2. Check. + * @tc.expected: Check success. + */ + threadWatcher_.SetTaskExecutor(MOCK_TASK_EXECUTOR); + threadWatcher_.loopTime_ = 10; + threadWatcher_.threadTag_ = 8; + threadWatcher_.lastLoopTime_ = 9; + threadWatcher_.lastThreadTag_ = 8; + threadWatcher_.lastTaskId_ = 10; + threadWatcher_.state_ = State::WARNING; + threadWatcher_.Check(); + EXPECT_EQ(threadWatcher_.state_, State::FREEZE); +} + +/** + * @tc.name: Check04 + * @tc.desc: Verify the Check Interface of ThreadWatcher work correctly. + * @tc.type: FUNC + */ +HWTEST_F(ThreadWatcherTest, Check04, TestSize.Level1) +{ + /** + * @tc.steps: step1. Build a ThreadWatcher. + */ + ThreadWatcher threadWatcher_(INSTANCE_ID, TASK_TYPE, false); + + /** + * @tc.steps: step2. SetTaskExecutor. + * @tc.steps: step2. Check. + * @tc.expected: Check success. + */ + threadWatcher_.SetTaskExecutor(MOCK_TASK_EXECUTOR); + threadWatcher_.loopTime_ = 10; + threadWatcher_.threadTag_ = 8; + threadWatcher_.lastLoopTime_ = 9; + threadWatcher_.lastThreadTag_ = 8; + threadWatcher_.lastTaskId_ = 10; + threadWatcher_.state_ = State::FREEZE; + threadWatcher_.canShowDialog_ = false; + threadWatcher_.showDialogCount_ = 5; + threadWatcher_.freezeCount_ = 10; + threadWatcher_.Check(); + EXPECT_EQ(threadWatcher_.showDialogCount_, 6); + EXPECT_EQ(threadWatcher_.freezeCount_, 0); +} + +/** + * @tc.name: Check05 + * @tc.desc: Verify the Check Interface of ThreadWatcher work correctly. + * @tc.type: FUNC + */ +HWTEST_F(ThreadWatcherTest, Check05, TestSize.Level1) +{ + /** + * @tc.steps: step1. Build a ThreadWatcher. + */ + ThreadWatcher threadWatcher_(INSTANCE_ID, TASK_TYPE, false); + + /** + * @tc.steps: step2. SetTaskExecutor. + * @tc.steps: step2. Check. + * @tc.expected: Check success. + */ + threadWatcher_.SetTaskExecutor(MOCK_TASK_EXECUTOR); + threadWatcher_.loopTime_ = 10; + threadWatcher_.threadTag_ = 8; + threadWatcher_.lastLoopTime_ = 9; + threadWatcher_.lastThreadTag_ = 8; + threadWatcher_.lastTaskId_ = 10; + threadWatcher_.state_ = State::FREEZE; + threadWatcher_.canShowDialog_ = false; + threadWatcher_.showDialogCount_ = 20; + threadWatcher_.Check(); + EXPECT_EQ(threadWatcher_.showDialogCount_, 0); + EXPECT_TRUE(threadWatcher_.canShowDialog_); +} + + +} // namespace OHOS::Ace diff --git a/test/unittest/core/common/watch_dog/watch_dog_test.cpp b/test/unittest/core/common/watch_dog/watch_dog_test.cpp new file mode 100644 index 00000000000..f648ab560a8 --- /dev/null +++ b/test/unittest/core/common/watch_dog/watch_dog_test.cpp @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "gtest/gtest.h" +#define private public +#define protected public +#include "base/memory/ace_type.h" +#include "core/common/watch_dog.h" +#include "base/test/mock/mock_task_executor.h" +#include "base/thread/task_executor.h" +#include "base/memory/referenced.h" +using namespace testing; +using namespace testing::ext; + +namespace OHOS::Ace { +namespace { +const int32_t INSTANCE_ID = 777; +RefPtr MOCK_TASK_EXECUTOR; +} // namespace + +class WatchDogTest : public testing::Test { +public: +static void SetUpTestCase(); +static void TearDownTestCase(){} +void SetUp() {} +void TearDown() {} +}; +void WatchDogTest::SetUpTestCase(){ + MOCK_TASK_EXECUTOR = AceType::MakeRefPtr(); +} + +/** + * @tc.name: Register01 + * @tc.desc: Verify the Register Interface of WatchDog work correctly. + * @tc.type: FUNC + */ +HWTEST_F(WatchDogTest, Register01, TestSize.Level1) +{ + /** + * @tc.steps: step1. Build an WatchDog. + */ + WatchDog watchDog_; + + /** + * @tc.steps: step2. Register Executor. + * @tc.expected: Register Executor success; + * @tc.steps: step2. Unregister Executor. + * @tc.expected: Unregister Executor success; + */ + watchDog_.Register(INSTANCE_ID, MOCK_TASK_EXECUTOR, true); + EXPECT_EQ(watchDog_.watchMap_[INSTANCE_ID].jsWatcher, nullptr); + watchDog_.Unregister(INSTANCE_ID); + watchDog_.Unregister(INSTANCE_ID); + EXPECT_TRUE(watchDog_.watchMap_.empty()); + + /** + * @tc.steps: step2. Register Executor with useUIAsJSThread = false. + * @tc.expected: Register Executor success; + */ + watchDog_.Register(INSTANCE_ID, MOCK_TASK_EXECUTOR, false); + watchDog_.Register(INSTANCE_ID, MOCK_TASK_EXECUTOR, false); + EXPECT_NE(watchDog_.watchMap_[INSTANCE_ID].jsWatcher, nullptr); +} + +} // namespace OHOS::Ace