From fefb33d559943cd0a0d58c461a86d67aa3d3f6f5 Mon Sep 17 00:00:00 2001 From: yp9522 Date: Sat, 28 Jun 2025 19:02:01 +0800 Subject: [PATCH] add common_components tdd Signed-off-by: yp9522 --- BUILD.gn | 3 +- .../heap/barrier/tests/barrier_test.cpp | 102 ++++++++++++++- .../heap/collector/tests/BUILD.gn | 25 ++++ .../heap/collector/tests/task_queue_test.cpp | 120 ++++++++++++++++++ common_components/tests/ohos_test.xml | 5 + 5 files changed, 249 insertions(+), 6 deletions(-) create mode 100644 common_components/heap/collector/tests/task_queue_test.cpp diff --git a/BUILD.gn b/BUILD.gn index ed3568825d..0d5c47a4f5 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -238,7 +238,8 @@ group("ark_unittest") { "common_components/base/tests:host_unittest", "common_components/heap/allocator/tests:host_unittest", "common_components/mutator/tests:host_unittest", - "common_components/heap/barrier/tests:unittest", + "common_components/heap/barrier/tests:host_unittest", + "common_components/heap/collector/tests:host_unittest", ] } } diff --git a/common_components/heap/barrier/tests/barrier_test.cpp b/common_components/heap/barrier/tests/barrier_test.cpp index d78a62b39b..bcb291292f 100644 --- a/common_components/heap/barrier/tests/barrier_test.cpp +++ b/common_components/heap/barrier/tests/barrier_test.cpp @@ -106,7 +106,6 @@ protected: } }; - HWTEST_F_L0(BarrierTest, ReadRefField_ReturnsExpectedValue) { uint64_t value = reinterpret_cast(dummyObj.get()); RefField field(value); @@ -115,7 +114,6 @@ HWTEST_F_L0(BarrierTest, ReadRefField_ReturnsExpectedValue) { EXPECT_EQ(result, dummyObj.get()); } - HWTEST_F_L0(BarrierTest, WriteRefField_SetsTargetObject) { uint64_t initValue = 0; RefField field(initValue); @@ -125,7 +123,6 @@ HWTEST_F_L0(BarrierTest, WriteRefField_SetsTargetObject) { EXPECT_EQ(field.GetTargetObject(), newRef); } - HWTEST_F_L0(BarrierTest, WriteStaticRef_SetsTargetObject) { uint64_t initValue = 0; RefField field(initValue); @@ -135,7 +132,6 @@ HWTEST_F_L0(BarrierTest, WriteStaticRef_SetsTargetObject) { EXPECT_EQ(field.GetTargetObject(), newRef); } - HWTEST_F_L0(BarrierTest, AtomicWriteRefField_UpdatesWithMemoryOrder) { uint64_t initValue = 0; RefField field(initValue); @@ -145,7 +141,6 @@ HWTEST_F_L0(BarrierTest, AtomicWriteRefField_UpdatesWithMemoryOrder) { EXPECT_EQ(field.GetTargetObject(std::memory_order_relaxed), newRef); } - HWTEST_F_L0(BarrierTest, CompareAndSwapRefField_WorksWithSuccessAndFailure) { uint64_t initValue = 0; RefField field(initValue); @@ -156,4 +151,101 @@ HWTEST_F_L0(BarrierTest, CompareAndSwapRefField_WorksWithSuccessAndFailure) { std::memory_order_seq_cst, std::memory_order_relaxed); EXPECT_TRUE(result); EXPECT_EQ(field.GetTargetObject(std::memory_order_relaxed), newRef); +} + +HWTEST_F_L0(BarrierTest, WriteStruct_HandlesDifferentLengths) { + size_t srcBufferSize = 512; + size_t dstBufferSize = 1024; + char* srcBuffer = new char[srcBufferSize]; + char* dstBuffer = new char[dstBufferSize]; + + for (size_t i = 0; i < srcBufferSize; ++i) { + srcBuffer[i] = static_cast(i % 256); + } + + barrier.WriteStruct(nullptr, reinterpret_cast(dstBuffer), dstBufferSize, + reinterpret_cast(srcBuffer), srcBufferSize); + + EXPECT_EQ(memcmp(dstBuffer, srcBuffer, srcBufferSize), 0); + + for (size_t i = srcBufferSize; i < dstBufferSize; ++i) { + EXPECT_EQ(dstBuffer[i], 0); + } + + delete[] srcBuffer; + delete[] dstBuffer; +} + +HWTEST_F_L0(BarrierTest, ReadStaticRef_ReturnsExpectedValue) { + uint64_t value = reinterpret_cast(dummyObj.get()); + RefField field(value); + + BaseObject* result = barrier.ReadStaticRef(field); + EXPECT_EQ(result, dummyObj.get()); +} + +HWTEST_F_L0(BarrierTest, AtomicSwapRefField_ExchangesCorrectly) { + uint64_t initValue = reinterpret_cast(dummyObj.get()); + RefField field(initValue); + BaseObject* newRef = reinterpret_cast(0x1234567890); + BaseObject* oldValue = barrier.AtomicSwapRefField(nullptr, field, newRef, std::memory_order_seq_cst); + + EXPECT_EQ(oldValue, dummyObj.get()); + EXPECT_EQ(field.GetTargetObject(std::memory_order_relaxed), newRef); +} + +HWTEST_F_L0(BarrierTest, AtomicReadRefField_ReadsCorrectly) { + uint64_t initValue = reinterpret_cast(dummyObj.get()); + RefField field(initValue); + + BaseObject* value = barrier.AtomicReadRefField(nullptr, field, std::memory_order_seq_cst); + + EXPECT_EQ(value, dummyObj.get()); +} + +HWTEST_F_L0(BarrierTest, CopyStructArray_CopiesDataCorrectly) { + constexpr size_t arraySize = 100; + char* srcBuffer = new char[arraySize]; + char* dstBuffer = new char[arraySize]; + + for (size_t i = 0; i < arraySize; ++i) { + srcBuffer[i] = static_cast(i % 256); + } + + BaseObject srcObj; + BaseObject dstObj; + + HeapAddress srcFieldAddr = reinterpret_cast(srcBuffer); + HeapAddress dstFieldAddr = reinterpret_cast(dstBuffer); + + barrier.CopyStructArray(&dstObj, dstFieldAddr, arraySize, &srcObj, srcFieldAddr, arraySize); + + EXPECT_EQ(memcmp(dstBuffer, srcBuffer, arraySize), 0); + + delete[] srcBuffer; + delete[] dstBuffer; +} + +HWTEST_F_L0(BarrierTest, ReadStruct_ReadsCorrectly) { + struct TestStruct { + int a; + double b; + }; + + TestStruct* initValue = new TestStruct{42, 3.14}; + RefField field(reinterpret_cast(initValue)); + + char dstBuffer[sizeof(TestStruct)]; + HeapAddress dstAddr = reinterpret_cast(dstBuffer); + + BaseObject dummyObj; + HeapAddress srcAddr = reinterpret_cast(field.GetTargetObject()); + + barrier.ReadStruct(dstAddr, &dummyObj, srcAddr, sizeof(TestStruct)); + + TestStruct* result = reinterpret_cast(dstBuffer); + EXPECT_EQ(result->a, initValue->a); + EXPECT_EQ(result->b, initValue->b); + + delete initValue; } \ No newline at end of file diff --git a/common_components/heap/collector/tests/BUILD.gn b/common_components/heap/collector/tests/BUILD.gn index db91881225..77222dd29d 100755 --- a/common_components/heap/collector/tests/BUILD.gn +++ b/common_components/heap/collector/tests/BUILD.gn @@ -39,12 +39,36 @@ host_unittest_action("Collector_Test") { ] } +host_unittest_action("Task_Queue_Test") { + module_out_path = module_output_path + + sources = [ + # test file + "task_queue_test.cpp", + ] + + configs = [ + "//arkcompiler/ets_runtime/common_components:common_components_test_config", + "//arkcompiler/ets_runtime:icu_path_test_config", + ] + + deps = [ "//arkcompiler/ets_runtime/common_components:libark_common_components_test" ] + + # hiviewdfx libraries + external_deps = [ + "icu:shared_icui18n", + "icu:shared_icuuc", + "zlib:libz", + ] +} + group("unittest") { testonly = true # deps file deps = [ ":Collector_Test", + ":Task_Queue_Test", ] } @@ -54,5 +78,6 @@ group("host_unittest") { # deps file deps = [ ":Collector_TestAction", + ":Task_Queue_TestAction", ] } diff --git a/common_components/heap/collector/tests/task_queue_test.cpp b/common_components/heap/collector/tests/task_queue_test.cpp new file mode 100644 index 0000000000..976ec8b168 --- /dev/null +++ b/common_components/heap/collector/tests/task_queue_test.cpp @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2025 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 "common_components/heap/collector/task_queue.h" +#include "common_components/heap/collector/collector_proxy.h" +#include "common_components/heap/collector/gc_request.h" +#include "common_components/tests/test_helper.h" + +namespace common { +class StubAllocator : public Allocator { +public: + HeapAddress Allocate(size_t size, AllocType allocType) override { return 0; } + HeapAddress AllocateNoGC(size_t size, AllocType allocType) override { return 0; } + bool ForEachObject(const std::function&, bool safe) const override { return true; } + size_t ReclaimGarbageMemory(bool releaseAll) override { return 0; } + void FeedHungryBuffers() override {} + size_t LargeObjectSize() const override { return 0; } + size_t GetAllocatedBytes() const override { return 0; } + void Init(const RuntimeParam& param) override {} + size_t GetMaxCapacity() const override { return 0; } + size_t GetCurrentCapacity() const override { return 0; } + size_t GetUsedPageSize() const override { return 0; } + HeapAddress GetSpaceStartAddress() const override { return 0; } + HeapAddress GetSpaceEndAddress() const override { return 0; } +#ifndef NDEBUG + bool IsHeapObject(HeapAddress) const override { return false; } +#endif +}; + +class StubCollectorProxy : public CollectorProxy { +public: + explicit StubCollectorProxy(Allocator& allocator, CollectorResources& resources) + : CollectorProxy(allocator, resources) {} + + void RunGarbageCollection(uint64_t gcIndex, GCReason reason) override {} +}; +} + +namespace common { +class DummyCollectorProxy : public CollectorProxy { +public: + explicit DummyCollectorProxy(Allocator& alloc, CollectorResources& res) + : CollectorProxy(alloc, res) {} + void RunGarbageCollection(uint64_t gcIndex, GCReason reason) override {} +}; + +class DummyCollectorResources : public CollectorResources { +private: + DummyCollectorProxy proxy_; + +public: + explicit DummyCollectorResources(Allocator& alloc) + : CollectorResources(proxy_), + proxy_(alloc, *this) {} +}; +} + +namespace common::test { +class GCRunnerTest : public common::test::BaseTestWithScope { +protected: + void SetUp() override + { + allocator_ = std::make_unique(); + dummyResources_ = std::make_unique(*allocator_); + proxy_ = std::make_unique(*allocator_, *dummyResources_); + proxyStorage_ = std::make_unique(*allocator_, *dummyResources_); + } + + void TearDown() override + { + proxyStorage_.reset(); + dummyResources_.reset(); + proxy_.reset(); + allocator_.reset(); + } + + std::unique_ptr allocator_; + std::unique_ptr proxy_; + std::unique_ptr proxyStorage_; + std::unique_ptr dummyResources_; +}; + +HWTEST_F_L0(GCRunnerTest, Execute_TerminateGC) { + common::GCRunner runner(common::GCTask::GCTaskType::GC_TASK_TERMINATE_GC); + bool result = runner.Execute(proxyStorage_.get()); + EXPECT_FALSE(result); +} + +HWTEST_F_L0(GCRunnerTest, Execute_TimeoutGC) { + common::GCStats::SetPrevGCStartTime(common::TimeUtil::NanoSeconds() - 1000000000); + common::GCRunner runner(common::GCTask::GCTaskType::GC_TASK_TIMEOUT_GC); + bool result = runner.Execute(proxyStorage_.get()); + EXPECT_TRUE(result); +} + +HWTEST_F_L0(GCRunnerTest, Execute_InvokeGC) { + common::GCRunner runner(common::GCTask::GCTaskType::GC_TASK_INVOKE_GC, GC_REASON_BACKUP); + bool result = runner.Execute(proxyStorage_.get()); + EXPECT_TRUE(result); +} + +HWTEST_F_L0(GCRunnerTest, Execute_InvalidTaskType) { + common::GCRunner runner(static_cast( + static_cast(common::GCTask::GCTaskType::GC_TASK_DUMP_HEAP_IDE) + 1)); + bool result = runner.Execute(proxyStorage_.get()); + EXPECT_TRUE(result); +} +} // namespace common::test \ No newline at end of file diff --git a/common_components/tests/ohos_test.xml b/common_components/tests/ohos_test.xml index 40236aa557..f2f014b777 100644 --- a/common_components/tests/ohos_test.xml +++ b/common_components/tests/ohos_test.xml @@ -63,4 +63,9 @@