diff --git a/BUILD.gn b/BUILD.gn index 7a00f3610d603f6fc8d0156a6d2a75cbb42d1f84..d49b31d3db53fdb0a88df04ba0067169278ec78c 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -164,11 +164,15 @@ group("common_components_js_unittest") { "common_components/heap/barrier/tests:unittest", #"common_components/heap/collector/tests:unittest", + "common_components/heap/space/tests:unittest", "common_components/heap/w_collector/tests:unittest", + "common_components/heap/tests:unittest", "common_components/mutator/tests:unittest", "common_components/objects/tests:unittest", "common_components/thread/tests:unittest", "common_components/log/tests:unittest", + "common_components/platform/unix/tests:unittest", + "common_components/taskpool/tests:unittest", ] } } @@ -186,11 +190,15 @@ group("common_components_unittest") { "common_components/heap/barrier/tests:host_unittest", #"common_components/heap/collector/tests:host_unittest", + "common_components/heap/space/tests:host_unittest", "common_components/heap/w_collector/tests:host_unittest", + "common_components/heap/tests:host_unittest", "common_components/mutator/tests:host_unittest", "common_components/objects/tests:host_unittest", "common_components/thread/tests:host_unittest", "common_components/log/tests:host_unittest", + "common_components/platform/unix/tests:host_unittest", + "common_components/taskpool/tests:host_unittest", ] } } diff --git a/common_components/base/tests/BUILD.gn b/common_components/base/tests/BUILD.gn index 39e86f58d2ed0cbdc56ec3a7cdcd8f967e4197f8..2bd0f7144927801f471acd4e345601d45617a284 100755 --- a/common_components/base/tests/BUILD.gn +++ b/common_components/base/tests/BUILD.gn @@ -38,12 +38,60 @@ host_unittest_action("C_String_Test") { ] } +host_unittest_action("Mem_Utils_Test") { + module_out_path = module_output_path + + sources = [ + # test file + "mem_utils_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", + "runtime_core:libarkassembler_static", + ] +} + +host_unittest_action("Utf_Helper_Test") { + module_out_path = module_output_path + + sources = [ + # test file + "utf_helper_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", + "runtime_core:libarkassembler_static", + ] +} + group("unittest") { testonly = true # deps file deps = [ ":C_String_Test", + ":Mem_Utils_Test", + ":Utf_Helper_Test", ] } @@ -53,5 +101,7 @@ group("host_unittest") { # deps file deps = [ ":C_String_TestAction", + ":Mem_Utils_TestAction", + ":Utf_Helper_TestAction", ] } \ No newline at end of file diff --git a/common_components/base/tests/mem_utils_test.cpp b/common_components/base/tests/mem_utils_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..49c7f470777faef7612c761fe143eaa1fe88078b --- /dev/null +++ b/common_components/base/tests/mem_utils_test.cpp @@ -0,0 +1,50 @@ +/* +* 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 +#include + +#include "common_components/base/mem_utils.h" +#include "common_components/tests/test_helper.h" + +using namespace common; +namespace common::test { +class MemUtilsTest : public common::test::BaseTestWithScope { +}; + +HWTEST_F_L0(MemUtilsTest, CopyZeroBytes) +{ + char dest[100] = {}; + const char* src = "hello world"; + MemoryCopy(reinterpret_cast(dest), 0, + reinterpret_cast(src), strlen(src) + 1); + EXPECT_EQ(dest[0], '\0'); +} + +HWTEST_F_L0(MemUtilsTest, CopyTwoChunks) +{ + constexpr size_t totalSize = 100; + char dest[totalSize] = {}; + char src[totalSize] = {}; + for (size_t i = 0; i < totalSize; ++i) { + src[i] = static_cast('A' + (i % 26)); + } + + MemoryCopy(reinterpret_cast(dest), totalSize, + reinterpret_cast(src), totalSize); + + EXPECT_EQ(memcmp(dest, src, totalSize), 0); +} +} // namespace common::test \ No newline at end of file diff --git a/common_components/base/tests/utf_helper_test.cpp b/common_components/base/tests/utf_helper_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f01e8cafd3078726ddd03842561455906d8ddd10 --- /dev/null +++ b/common_components/base/tests/utf_helper_test.cpp @@ -0,0 +1,263 @@ +/* + * 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/base/utf_helper.h" +#include "common_components/tests/test_helper.h" + +using namespace common; +namespace common::test { +class UtfHelperTest : public common::test::BaseTestWithScope { +}; + +HWTEST_F_L0(UtfHelperTest, DecodeUTF16Test1) +{ + uint16_t utf16[] = {0xD7FF}; + size_t index = 0; + size_t len = 1; + uint32_t result = utf_helper::DecodeUTF16(utf16, len, &index, false); + EXPECT_EQ(result, 0xD7FF); + + uint16_t utf16In[] = {0xDC00}; + result = utf_helper::DecodeUTF16(utf16In, len, &index, false); + EXPECT_EQ(result, 0xDC00); + + uint16_t utf16In1[] = {0xD800}; + result = utf_helper::DecodeUTF16(utf16In1, len, &index, false); + EXPECT_EQ(result, 0xD800); + + uint16_t utf16In2[] = {0xD7FF}; + len = 2; + result = utf_helper::DecodeUTF16(utf16In2, len, &index, false); + EXPECT_EQ(result, 0xD7FF); + + len = 1; + result = utf_helper::DecodeUTF16(utf16In2, len, &index, false); + EXPECT_EQ(result, 0xD7FF); + + result = utf_helper::DecodeUTF16(utf16In, len, &index, false); + EXPECT_EQ(result, 0xDC00); +} + +HWTEST_F_L0(UtfHelperTest, DecodeUTF16Test2) +{ + size_t index = 0; + uint16_t utf16[] = {0xD800, 0xDC00}; + size_t len = 2; + utf16[1] = 0xFFFF; + uint32_t result = utf_helper::DecodeUTF16(utf16, len, &index, false); + EXPECT_EQ(result, 0xD800); +} + +HWTEST_F_L0(UtfHelperTest, DecodeUTF16Test3) +{ + size_t index = 0; + uint16_t utf16[] = {0xD800, 0xDC00}; + size_t len = 2; + uint32_t result = utf_helper::DecodeUTF16(utf16, len, &index, true); + EXPECT_EQ(result, 0xD800); + + uint16_t utf16In[] = {0xD800, 0x0041}; + result = utf_helper::DecodeUTF16(utf16In, len, &index, false); + EXPECT_EQ(result, 0xD800); +} + +HWTEST_F_L0(UtfHelperTest, HandleAndDecodeInvalidUTF16Test1) +{ + uint16_t input[] = {0xDC00}; + size_t index = 0; + size_t len = sizeof(input) / sizeof(input[0]); + uint32_t result = utf_helper::HandleAndDecodeInvalidUTF16(input, len, &index); + EXPECT_EQ(result, utf_helper::UTF16_REPLACEMENT_CHARACTER); +} + +HWTEST_F_L0(UtfHelperTest, HandleAndDecodeInvalidUTF16Test2) +{ + uint16_t input[] = {0xD800}; + size_t index = 0; + size_t len = sizeof(input) / sizeof(input[0]); + uint32_t result = utf_helper::HandleAndDecodeInvalidUTF16(input, len, &index); + EXPECT_EQ(result, utf_helper::UTF16_REPLACEMENT_CHARACTER); + + uint16_t input1[] = {0xD800, 0xD800}; + size_t len1 = sizeof(input1) / sizeof(input1[0]); + result = utf_helper::HandleAndDecodeInvalidUTF16(input1, len1, &index); + EXPECT_EQ(result, utf_helper::UTF16_REPLACEMENT_CHARACTER); + + uint16_t input2[] = {'A'}; + size_t len2 = sizeof(input2) / sizeof(input2[0]); + result = utf_helper::HandleAndDecodeInvalidUTF16(input2, len2, &index); + EXPECT_EQ(result, 'A'); + + uint16_t input3[] = {0xD800 ^ 0x01}; + size_t len3 = sizeof(input3) / sizeof(input3[0]); + result = utf_helper::HandleAndDecodeInvalidUTF16(input3, len3, &index); + EXPECT_EQ(result, utf_helper::UTF16_REPLACEMENT_CHARACTER); +} + +HWTEST_F_L0(UtfHelperTest, HandleAndDecodeInvalidUTF16Test3) +{ + uint16_t input[] = {0xDBFF, 0xDFFF}; + size_t index = 0; + size_t len = sizeof(input) / sizeof(input[0]); + uint32_t expected = ((0xDBFF - utf_helper::DECODE_LEAD_LOW) << utf_helper::UTF16_OFFSET) + + (0xDFFF - utf_helper::DECODE_TRAIL_LOW) + utf_helper::DECODE_SECOND_FACTOR; + uint32_t result = utf_helper::HandleAndDecodeInvalidUTF16(input, len, &index); + EXPECT_EQ(result, expected); +} + +HWTEST_F_L0(UtfHelperTest, HandleAndDecodeInvalidUTF16Test4) +{ + uint16_t input[] = {0xD800, 0xDC00}; + size_t index = 0; + size_t len = sizeof(input) / sizeof(input[0]); + uint32_t expected = ((0xD800 - utf_helper::DECODE_LEAD_LOW) << utf_helper::UTF16_OFFSET) + + (0xDC00 - utf_helper::DECODE_TRAIL_LOW) + utf_helper::DECODE_SECOND_FACTOR; + uint32_t result = utf_helper::HandleAndDecodeInvalidUTF16(input, len, &index); + EXPECT_EQ(result, expected); + EXPECT_EQ(index, 1); +} + +HWTEST_F_L0(UtfHelperTest, IsValidUTF8Test1) +{ + std::vector data = {0xED, 0xA0, 0x80}; + EXPECT_FALSE(utf_helper::IsValidUTF8(data)); + + std::vector data1 = {0xED, 0x90, 0x80}; + EXPECT_TRUE(utf_helper::IsValidUTF8(data1)); + + std::vector data2 = {0xED, 0xC0, 0x80}; + EXPECT_FALSE(utf_helper::IsValidUTF8(data2)); + + std::vector data3 = {0xED, 0x80, 0x80}; + EXPECT_TRUE(utf_helper::IsValidUTF8(data3)); + + std::vector data4 = {0xE0, 0xA0, 0x80}; + EXPECT_TRUE(utf_helper::IsValidUTF8(data4)); +} + +HWTEST_F_L0(UtfHelperTest, IsValidUTF8Test2) +{ + std::vector data = {0xF4, 0x90, 0x80, 0x80}; + EXPECT_FALSE(utf_helper::IsValidUTF8(data)); + + std::vector data1 = {0xF5, 0x80, 0x80, 0x80}; + EXPECT_FALSE(utf_helper::IsValidUTF8(data1)); + + std::vector data2 = {0xF0, 0x90, 0x80, 0x80}; + EXPECT_TRUE(utf_helper::IsValidUTF8(data2)); + + std::vector data3 = {0xF1, 0x80, 0x80, 0x80}; + EXPECT_TRUE(utf_helper::IsValidUTF8(data3)); + + std::vector data4 = {0xF4, 0x80, 0x80, 0x80}; + EXPECT_TRUE(utf_helper::IsValidUTF8(data4)); +} + +HWTEST_F_L0(UtfHelperTest, ConvertRegionUtf16ToUtf8Test3) +{ + uint8_t utf8Out[10]; + size_t result = utf_helper::ConvertRegionUtf16ToUtf8(nullptr, utf8Out, 5, 10, 0, false, false, false); + EXPECT_EQ(result, 0); + + uint16_t utf16In[] = {0x0041}; + result = utf_helper::ConvertRegionUtf16ToUtf8(utf16In, nullptr, 1, sizeof(utf16In), 0, false, false, false); + EXPECT_EQ(result, 0); + + result = utf_helper::ConvertRegionUtf16ToUtf8(utf16In, utf8Out, 1, 0, 0, false, false, false); + EXPECT_EQ(result, 0); + + result = utf_helper::ConvertRegionUtf16ToUtf8(nullptr, utf8Out, 1, 0, 0, false, false, false); + EXPECT_EQ(result, 0); + + result = utf_helper::ConvertRegionUtf16ToUtf8(utf16In, nullptr, 1, 0, 0, false, false, false); + EXPECT_EQ(result, 0); + + result = utf_helper::ConvertRegionUtf16ToUtf8(nullptr, nullptr, 1, sizeof(utf8Out), 0, false, false, false); + EXPECT_EQ(result, 0); + + result = utf_helper::ConvertRegionUtf16ToUtf8(nullptr, nullptr, 1, 0, 0, false, false, false); + EXPECT_EQ(result, 0); + + result = utf_helper::ConvertRegionUtf16ToUtf8(utf16In, utf8Out, 1, sizeof(utf8Out), 0, false, false, false); + EXPECT_EQ(result, 1); +} + +HWTEST_F_L0(UtfHelperTest, ConvertRegionUtf16ToLatin1Test) +{ + uint8_t utf8Out[10]; + size_t result = utf_helper::ConvertRegionUtf16ToLatin1(nullptr, utf8Out, 5, 10); + EXPECT_EQ(result, 0); + + uint16_t utf16In[] = {0x0041}; + result = utf_helper::ConvertRegionUtf16ToLatin1(utf16In, nullptr, 1, sizeof(utf16In)); + EXPECT_EQ(result, 0); + + result = utf_helper::ConvertRegionUtf16ToLatin1(utf16In, utf8Out, 1, 0); + EXPECT_EQ(result, 0); + + result = utf_helper::ConvertRegionUtf16ToLatin1(nullptr, utf8Out, 1, 0); + EXPECT_EQ(result, 0); + + result = utf_helper::ConvertRegionUtf16ToLatin1(utf16In, nullptr, 1, 0); + EXPECT_EQ(result, 0); + + result = utf_helper::ConvertRegionUtf16ToLatin1(nullptr, nullptr, 1, sizeof(utf8Out)); + EXPECT_EQ(result, 0); + + result = utf_helper::ConvertRegionUtf16ToLatin1(nullptr, nullptr, 1, 0); + EXPECT_EQ(result, 0); + + result = utf_helper::ConvertRegionUtf16ToLatin1(utf16In, utf8Out, 1, sizeof(utf8Out)); + EXPECT_EQ(result, 1); + + const uint16_t input[] = {0x0041, 0x0042, 0x0043}; + uint8_t output[2] = {0}; + result = utf_helper::ConvertRegionUtf16ToLatin1(input, output, 3, 2); + EXPECT_EQ(result, 2); +} + +HWTEST_F_L0(UtfHelperTest, DebuggerConvertRegionUtf16ToUtf8Test) +{ + uint8_t utf8Out[10]; + size_t result = utf_helper::DebuggerConvertRegionUtf16ToUtf8(nullptr, utf8Out, 5, sizeof(utf8Out), 0, false, false); + EXPECT_EQ(result, 0); + + uint16_t utf16In[] = {0x0041}; + result = utf_helper::DebuggerConvertRegionUtf16ToUtf8(utf16In, nullptr, 1, sizeof(utf16In), 0, false, false); + EXPECT_EQ(result, 0); + + result = utf_helper::DebuggerConvertRegionUtf16ToUtf8(nullptr, nullptr, 1, sizeof(utf8Out), 0, false, false); + EXPECT_EQ(result, 0); + + result = utf_helper::DebuggerConvertRegionUtf16ToUtf8(nullptr, utf8Out, 1, 0, 0, false, false); + EXPECT_EQ(result, 0); + + result = utf_helper::DebuggerConvertRegionUtf16ToUtf8(nullptr, utf8Out, 1, 0, 0, false, false); + EXPECT_EQ(result, 0); + + result = utf_helper::DebuggerConvertRegionUtf16ToUtf8(nullptr, nullptr, 1, 0, 0, false, false); + EXPECT_EQ(result, 0); + + result = utf_helper::DebuggerConvertRegionUtf16ToUtf8(utf16In, utf8Out, 1, 0, 0, false, false); + EXPECT_EQ(result, 0); + + result = utf_helper::DebuggerConvertRegionUtf16ToUtf8(utf16In, utf8Out, 1, sizeof(utf8Out), 0, false, false); + EXPECT_EQ(result, 1); + + uint16_t utf16In1[] = {0x0041, 0x0042, 0x0043}; + result = utf_helper::DebuggerConvertRegionUtf16ToUtf8(utf16In1, nullptr, 3, 0, 0, false, false); + EXPECT_EQ(result, 0); +} +} // namespace common::test \ 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 20a34d4289709824629fe2663dcf71b8349d9011..b84b68b7880bb21a4210e6dea3397105142a2a9b 100755 --- a/common_components/heap/collector/tests/BUILD.gn +++ b/common_components/heap/collector/tests/BUILD.gn @@ -39,6 +39,29 @@ host_unittest_action("Collector_Test") { ] } +host_unittest_action("Heuristic_Gc_Policy_Test") { + module_out_path = module_output_path + + sources = [ + # test file + "heuristic_gc_policy_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", + "runtime_core:libarkassembler_static", + ] +} + host_unittest_action("Trace_Collector_Test") { module_out_path = module_output_path @@ -114,6 +137,7 @@ group("unittest") { # deps file deps = [ ":Collector_Test", + ":Heuristic_Gc_Policy_Test", ":Trace_Collector_Test", ":Task_Queue_Test", ":Gc_Request_Test", @@ -126,6 +150,7 @@ group("host_unittest") { # deps file deps = [ ":Collector_TestAction", + ":Heuristic_Gc_Policy_TestAction", ":Trace_Collector_TestAction", ":Task_Queue_TestAction", ":Gc_Request_TestAction", diff --git a/common_components/heap/collector/tests/heuristic_gc_policy_test.cpp b/common_components/heap/collector/tests/heuristic_gc_policy_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0281724f8e4362aacb27adcee05191f4f085cf33 --- /dev/null +++ b/common_components/heap/collector/tests/heuristic_gc_policy_test.cpp @@ -0,0 +1,62 @@ +/* +* 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/heuristic_gc_policy.h" +#include "common_components/tests/test_helper.h" + +using namespace common; +namespace common::test { +class HeuristicGCPolicyTest : public common::test::BaseTestWithScope { +}; + +HWTEST_F_L0(HeuristicGCPolicyTest, ShouldRestrainGCOnStartup) +{ + HeuristicGCPolicy gcPolicy; + StartupStatusManager::SetStartupStatus(StartupStatus::COLD_STARTUP); + EXPECT_TRUE(gcPolicy.ShouldRestrainGCOnStartup()); + gcPolicy.TryHeuristicGC(); + + StartupStatusManager::SetStartupStatus(StartupStatus::COLD_STARTUP_FINISH); + EXPECT_FALSE(gcPolicy.ShouldRestrainGCOnStartup()); + + gcPolicy.Init(); + EXPECT_FALSE(gcPolicy.ShouldRestrainGCOnStartup()); + StartupStatusManager::SetStartupStatus(StartupStatus::COLD_STARTUP_PARTIALLY_FINISH); + EXPECT_FALSE(gcPolicy.ShouldRestrainGCOnStartup()); +} + +HWTEST_F_L0(HeuristicGCPolicyTest, NotifyNativeAllocation) +{ + HeuristicGCPolicy gcPolicy; + size_t initialNotified = gcPolicy.GetNotifiedNativeSize(); + size_t initialObjects = gcPolicy.GetNativeHeapThreshold(); + + gcPolicy.NotifyNativeAllocation(NATIVE_IMMEDIATE_THRESHOLD / 2); + + EXPECT_EQ(gcPolicy.GetNotifiedNativeSize(), initialNotified + NATIVE_IMMEDIATE_THRESHOLD / 2); + EXPECT_NE(gcPolicy.GetNativeHeapThreshold(), initialObjects + 1); +} + +HWTEST_F_L0(HeuristicGCPolicyTest, NotifyNativeAllocation_TriggerByBytes) { + HeuristicGCPolicy gcPolicy; + size_t initialNotified = gcPolicy.GetNotifiedNativeSize(); + size_t initialObjects = gcPolicy.GetNativeHeapThreshold(); + + gcPolicy.NotifyNativeAllocation(NATIVE_IMMEDIATE_THRESHOLD + 1); + + EXPECT_EQ(gcPolicy.GetNotifiedNativeSize(), initialNotified + NATIVE_IMMEDIATE_THRESHOLD + 1); + EXPECT_NE(gcPolicy.GetNativeHeapThreshold(), initialObjects + 1); +} +} // namespace common::test \ No newline at end of file diff --git a/common_components/heap/collector/tests/trace_collector_test.cpp b/common_components/heap/collector/tests/trace_collector_test.cpp index 5b579b4ff2eeda1a74ce2debc4d0a29c4837d92d..2c5782d9104d8a613ea9ca47961dd37f5c276b27 100755 --- a/common_components/heap/collector/tests/trace_collector_test.cpp +++ b/common_components/heap/collector/tests/trace_collector_test.cpp @@ -63,4 +63,15 @@ std::unique_ptr GetWCollector() return std::make_unique(allocator, resources); } +HWTEST_F_L0(TraceCollectorTest, RunGarbageCollection) +{ + TraceCollector& collector = reinterpret_cast(Heap::GetHeap().GetCollector()); + Heap::GetHeap().SetGCReason(GCReason::GC_REASON_YOUNG); + collector.RunGarbageCollection(0, GCReason::GC_REASON_USER); + ASSERT_FALSE(Heap::GetHeap().GetCollector().GetGCStats().isYoungGC()); + + Heap::GetHeap().SetGCReason(GCReason::GC_REASON_BACKUP); + collector.RunGarbageCollection(0, GCReason::GC_REASON_OOM); + ASSERT_FALSE(Heap::GetHeap().GetCollector().GetGCStats().isYoungGC()); +} } \ No newline at end of file diff --git a/common_components/heap/space/tests/BUILD.gn b/common_components/heap/space/tests/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..150821d3248eadfbdee8b5a014c596bd92893778 --- /dev/null +++ b/common_components/heap/space/tests/BUILD.gn @@ -0,0 +1,57 @@ +# 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. + +import("//arkcompiler/ets_runtime/common_components/tests/test_helper.gni") + +module_output_path = "ets_runtime" + +host_unittest_action("From_Space_Test") { + module_out_path = module_output_path + + sources = [ + # test file + "from_space_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 = [ + ":From_Space_Test", + ] +} + +group("host_unittest") { + testonly = true + + # deps file + deps = [ + ":From_Space_TestAction", + ] +} \ No newline at end of file diff --git a/common_components/heap/space/tests/from_space_test.cpp b/common_components/heap/space/tests/from_space_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0cd023fa811f0a676d4957feb354e2d9f35c512b --- /dev/null +++ b/common_components/heap/space/tests/from_space_test.cpp @@ -0,0 +1,35 @@ +/* +* 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/allocator/region_space.h" +#include "common_components/heap/space/from_space.h" +#include "common_components/mutator/thread_local.h" +#include "common_components/tests/test_helper.h" + +using namespace common; +namespace common::test { +class FromSpaceTest : public common::test::BaseTestWithScope { +}; + +HWTEST_F_L0(FromSpaceTest, CopyFromRegions) +{ + RegionManager regionManager; + RegionSpace heap; + FromSpace fromSpace(regionManager, heap); + ThreadLocal::SetAllocBuffer(nullptr); + fromSpace.CopyFromRegions(nullptr); + ASSERT_FALSE(fromSpace.GetFromRegionList().GetHeadRegion() != nullptr); +} +} // namespace common::test \ No newline at end of file diff --git a/common_components/heap/tests/BUILD.gn b/common_components/heap/tests/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..7b144861f07cbe7dfdc27e650fd493a77877483d --- /dev/null +++ b/common_components/heap/tests/BUILD.gn @@ -0,0 +1,84 @@ +# 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. + +import("//arkcompiler/ets_runtime/common_components/tests/test_helper.gni") + +module_output_path = "ets_runtime" + +host_unittest_action("Heap_Manager_Test") { + module_out_path = module_output_path + + sources = [ + # test file + "heap_manager_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", + ] +} + +host_unittest_action("Verification_Test") { + module_out_path = module_output_path + + sources = [ + # test file + "verification_test.cpp", + ] + + include_dirs = [ "//arkcompiler/ets_runtime/common_components/" ] + + 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 = [ + ":Heap_Manager_Test", + ":Verification_Test", + ] +} + +group("host_unittest") { + testonly = true + + # deps file + deps = [ + ":Heap_Manager_TestAction", + ":Verification_TestAction", + ] +} \ No newline at end of file diff --git a/common_components/heap/tests/heap_manager_test.cpp b/common_components/heap/tests/heap_manager_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..63ed0aade932525664b4e868bc13cb6d812e4042 --- /dev/null +++ b/common_components/heap/tests/heap_manager_test.cpp @@ -0,0 +1,41 @@ +/* +* 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/heap.h" +#include "common_components/heap/heap_manager.h" +#include "common_components/tests/test_helper.h" + +using namespace common; +namespace common::test { +class HeapManagerTest : public common::test::BaseTestWithScope { +protected: + static void SetUpTestCase() + { + BaseRuntime::GetInstance()->Init(); + } +}; + +HWTEST_F_L0(HeapManagerTest, RequestGC) +{ + HeapManager manager; + Heap::GetHeap().EnableGC(false); + manager.RequestGC(GCReason::GC_REASON_USER, true); + ASSERT_FALSE(Heap::GetHeap().IsGCEnabled()); + + Heap::GetHeap().EnableGC(true); + manager.RequestGC(GCReason::GC_REASON_USER, true); + ASSERT_TRUE(Heap::GetHeap().IsGCEnabled()); +} +} // namespace common::test \ No newline at end of file diff --git a/common_components/heap/tests/verification_test.cpp b/common_components/heap/tests/verification_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..20a285f74420e2ab0838bb35e19cd38039c1e1ef --- /dev/null +++ b/common_components/heap/tests/verification_test.cpp @@ -0,0 +1,187 @@ +/* +* 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/verification.cpp" +#include "common_components/heap/heap_manager.h" +#include "common_components/heap/w_collector/w_collector.h" +#include "common_components/tests/test_helper.h" + +using namespace common; +namespace common::test { +class VerificationTest : public common::test::BaseTestWithScope { +protected: + static void SetUpTestCase() + { + BaseRuntime::GetInstance()->Init(); + } + + static void TearDownTestCase() + {} + + void SetUp() override + { + MutatorManager::Instance().CreateRuntimeMutator(ThreadType::GC_THREAD); + } + + void TearDown() override + { + MutatorManager::Instance().DestroyRuntimeMutator(ThreadType::GC_THREAD); + } +}; + +HWTEST_F_L0(VerificationTest, GetObjectInfoTest) +{ + BaseObject* obj = nullptr; + std::string result = GetObjectInfo(obj); + + EXPECT_NE(result.find("address: 0x0"), std::string::npos); + EXPECT_NE(result.find("Skip: nullptr"), std::string::npos); + EXPECT_NE(result.find("Skip: Object is not in heap range"), std::string::npos); +} + +HWTEST_F_L0(VerificationTest, GetObjectInfoTest2) +{ + BaseObject obj; + std::string result = GetObjectInfo(&obj); + EXPECT_NE(result.find("address: 0x"), std::string::npos); + EXPECT_NE(result.find("Skip: Object is not in heap range"), std::string::npos); +} + +HWTEST_F_L0(VerificationTest, GetRefInfoTest) +{ + BaseObject oldObj; + RefField oldField(&oldObj); + MAddress oldAddress = oldField.GetFieldValue(); + std::string result = GetRefInfo(oldField); + EXPECT_NE(result.find("address: 0x"), std::string::npos); + EXPECT_NE(result.find("Skip: Object is not in heap range"), std::string::npos); +} + +HWTEST_F_L0(VerificationTest, VerifyRefImplTest2) +{ + RegionSpace& theAllocator = reinterpret_cast(Heap::GetHeap().GetAllocator()); + uintptr_t addr = theAllocator.AllocRegion(); + ASSERT_NE(addr, 0U); + BaseObject* obj = reinterpret_cast(addr); + RegionDesc* region = RegionDesc::GetRegionDescAt(reinterpret_cast(obj)); + ASSERT_NE(region, nullptr); + region->SetRegionType(RegionDesc::RegionType::FROM_REGION); + RefField field(obj); + + auto refObj = field.GetTargetObject(); + + AfterForwardVisitor visitor; + visitor.VerifyRefImpl(obj, field); + ASSERT_FALSE(RegionSpace::IsMarkedObject(refObj)); + ASSERT_FALSE(RegionSpace::IsResurrectedObject(refObj)); +} + +HWTEST_F_L0(VerificationTest, VerifyRefImplTest3) +{ + RegionSpace& theAllocator = reinterpret_cast(Heap::GetHeap().GetAllocator()); + uintptr_t addr = theAllocator.AllocRegion(); + ASSERT_NE(addr, 0U); + BaseObject* obj = reinterpret_cast(addr); + RegionDesc* region = RegionDesc::GetRegionDescAt(reinterpret_cast(obj)); + ASSERT_NE(region, nullptr); + region->SetRegionType(RegionDesc::RegionType::FULL_PINNED_REGION); + RefField field(obj); + + auto refObj = field.GetTargetObject(); + + ReadBarrierSetter visitor; + visitor.VerifyRefImpl(nullptr, field); + visitor.VerifyRefImpl(obj, field); + EXPECT_EQ(RegionDesc::RegionType::FULL_PINNED_REGION, + RegionDesc::GetRegionDescAt(reinterpret_cast(field.GetTargetObject()))->GetRegionType()); + + region->SetRegionType(RegionDesc::RegionType::RECENT_PINNED_REGION); + visitor.VerifyRefImpl(obj, field); + EXPECT_EQ(RegionDesc::RegionType::RECENT_PINNED_REGION, + RegionDesc::GetRegionDescAt(reinterpret_cast(field.GetTargetObject()))->GetRegionType()); + + region->SetRegionType(RegionDesc::RegionType::FIXED_PINNED_REGION); + visitor.VerifyRefImpl(obj, field); + EXPECT_EQ(RegionDesc::RegionType::FIXED_PINNED_REGION, + RegionDesc::GetRegionDescAt(reinterpret_cast(field.GetTargetObject()))->GetRegionType()); + + region->SetRegionType(RegionDesc::RegionType::FULL_FIXED_PINNED_REGION); + visitor.VerifyRefImpl(obj, field); + EXPECT_EQ(RegionDesc::RegionType::FULL_FIXED_PINNED_REGION, + RegionDesc::GetRegionDescAt(reinterpret_cast(field.GetTargetObject()))->GetRegionType()); + + region->SetRegionType(RegionDesc::RegionType::READ_ONLY_REGION); + auto oldRefValue = field.GetFieldValue(); + visitor.VerifyRefImpl(obj, field); + auto newRefValue = field.GetFieldValue(); + EXPECT_NE(oldRefValue, newRefValue); +} + +std::unique_ptr GetWCollector() +{ + CollectorResources &resources = Heap::GetHeap().GetCollectorResources(); + Allocator &allocator = Heap::GetHeap().GetAllocator(); + + return std::make_unique(allocator, resources); +} + +HWTEST_F_L0(VerificationTest, VerifyAfterMarkTest1) +{ + Heap::GetHeap().SetGCPhase(GCPhase::GC_PHASE_POST_MARK); + std::unique_ptr wcollector = GetWCollector(); + ASSERT_TRUE(wcollector != nullptr); + WVerify verify; + verify.VerifyAfterMark(*wcollector); + ASSERT_FALSE(MutatorManager::Instance().WorldStopped()); +} + +HWTEST_F_L0(VerificationTest, VerifyAfterForwardTest1) +{ + Heap::GetHeap().SetGCPhase(GCPhase::GC_PHASE_COPY); + std::unique_ptr wcollector = GetWCollector(); + ASSERT_TRUE(wcollector != nullptr); + WVerify verify; + verify.VerifyAfterForward(*wcollector); + ASSERT_FALSE(MutatorManager::Instance().WorldStopped()); +} + +HWTEST_F_L0(VerificationTest, VerifyAfterFixTest1) +{ + Heap::GetHeap().SetGCPhase(GCPhase::GC_PHASE_FIX); + std::unique_ptr wcollector = GetWCollector(); + ASSERT_TRUE(wcollector != nullptr); + WVerify verify; + verify.VerifyAfterFix(*wcollector); + ASSERT_FALSE(MutatorManager::Instance().WorldStopped()); +} + +HWTEST_F_L0(VerificationTest, EnableReadBarrierDFXTest1) +{ + std::unique_ptr wcollector = GetWCollector(); + ASSERT_TRUE(wcollector != nullptr); + WVerify verify; + verify.EnableReadBarrierDFX(*wcollector); + ASSERT_FALSE(MutatorManager::Instance().WorldStopped()); +} + +HWTEST_F_L0(VerificationTest, DisableReadBarrierDFXTest1) +{ + std::unique_ptr wcollector = GetWCollector(); + ASSERT_TRUE(wcollector != nullptr); + WVerify verify; + verify.DisableReadBarrierDFX(*wcollector); + ASSERT_FALSE(MutatorManager::Instance().WorldStopped()); +} +} // namespace common::test diff --git a/common_components/heap/w_collector/tests/copy_barrier_test.cpp b/common_components/heap/w_collector/tests/copy_barrier_test.cpp index df5e3a24dea4816effd3c3f0fb1fb093cf933d7e..95f3aae4c2313444a75f657f9720fcf677ad31a8 100755 --- a/common_components/heap/w_collector/tests/copy_barrier_test.cpp +++ b/common_components/heap/w_collector/tests/copy_barrier_test.cpp @@ -178,6 +178,36 @@ HWTEST_F_L0(CopyBarrierTest, ReadStringTableStaticRef_TEST1) ASSERT_TRUE(resultObj == nullptr); } +HWTEST_F_L0(CopyBarrierTest, ReadStringTableStaticRef_TEST2) +{ + MockCollector collector; + auto copyBarrier = std::make_unique(collector); + ASSERT_TRUE(copyBarrier != nullptr); + + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); + RefField field(obj); + + BaseObject* resultObj = copyBarrier->ReadStringTableStaticRef(field); + ASSERT_TRUE(resultObj != nullptr); +} + +HWTEST_F_L0(CopyBarrierTest, ReadStringTableStaticRef_TEST3) +{ + MockCollector collector; + auto copyBarrier = std::make_unique(collector); + ASSERT_TRUE(copyBarrier != nullptr); + + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); + RegionDesc *regionInfo = RegionDesc::GetRegionDescAt(addr); + regionInfo->SetRegionType(RegionDesc::RegionType::FREE_REGION); + RefField field(obj); + + BaseObject* resultObj = copyBarrier->ReadStringTableStaticRef(field); + ASSERT_TRUE(resultObj == nullptr); +} + HWTEST_F_L0(CopyBarrierTest, ReadStruct_TEST1) { MockCollector collector; diff --git a/common_components/heap/w_collector/tests/enum_barrier_test.cpp b/common_components/heap/w_collector/tests/enum_barrier_test.cpp index 045895b21834cd55723de20df84cb0ea91beac80..910b86a74e6eec4caf6464b9d266feff62f4b5f5 100755 --- a/common_components/heap/w_collector/tests/enum_barrier_test.cpp +++ b/common_components/heap/w_collector/tests/enum_barrier_test.cpp @@ -184,6 +184,28 @@ HWTEST_F_L0(EnumBarrierTest, WriteBarrier_TEST2) #endif } +HWTEST_F_L0(EnumBarrierTest, WriteBarrier_TEST3) +{ + MockCollector collector; + auto enumBarrier = std::make_unique(collector); + ASSERT_TRUE(enumBarrier != nullptr); + +#ifndef ARK_USE_SATB_BARRIER + constexpr uint64_t TAG_BITS_SHIFT = 48; + constexpr uint64_t TAG_MARK = 0xFFFFULL << TAG_BITS_SHIFT; + constexpr uint64_t TAG_SPECIAL = 0x02ULL; + constexpr uint64_t TAG_BOOLEAN = 0x04ULL; + constexpr uint64_t TAG_HEAP_OBJECT_MASK = TAG_MARK | TAG_SPECIAL | TAG_BOOLEAN; + + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); + RefField<> field(obj); + Heap::GetHeap().SetGCReason(GC_REASON_YOUNG); + enumBarrier->WriteBarrier(obj, field, obj); + EXPECT_TRUE(obj != nullptr); +#endif +} + HWTEST_F_L0(EnumBarrierTest, ReadStruct_TEST1) { MockCollector collector; diff --git a/common_components/heap/w_collector/tests/idle_barrier_test.cpp b/common_components/heap/w_collector/tests/idle_barrier_test.cpp index a799ead11920d542bf820bf6333fe35745031a5c..4f34f859cbfe38e909b19fc44afb6188eb22e36c 100755 --- a/common_components/heap/w_collector/tests/idle_barrier_test.cpp +++ b/common_components/heap/w_collector/tests/idle_barrier_test.cpp @@ -217,6 +217,55 @@ HWTEST_F_L0(IdleBarrierTest, WriteRefField_TEST0) EXPECT_EQ(oldField.GetFieldValue(), neWAddress); } +HWTEST_F_L0(IdleBarrierTest, WriteRefField_TEST1) +{ + MockCollector collector; + auto idleBarrier = std::make_unique(collector); + ASSERT_TRUE(idleBarrier != nullptr); + + constexpr uint64_t TAG_BITS_SHIFT = 48; + constexpr uint64_t TAG_MARK = 0xFFFFULL << TAG_BITS_SHIFT; + constexpr uint64_t TAG_SPECIAL = 0x02ULL; + constexpr uint64_t TAG_BOOLEAN = 0x04ULL; + constexpr uint64_t TAG_HEAP_OBJECT_MASK = TAG_MARK | TAG_SPECIAL | TAG_BOOLEAN; + + RefField<> field(MAddress(0)); + BaseObject *obj = reinterpret_cast(TAG_HEAP_OBJECT_MASK); + idleBarrier->WriteRefField(obj, field, obj); + EXPECT_TRUE(obj != nullptr); +} + +HWTEST_F_L0(IdleBarrierTest, WriteBarrier_TEST1) +{ + MockCollector collector; + auto idleBarrier = std::make_unique(collector); + ASSERT_TRUE(idleBarrier != nullptr); + + constexpr uint64_t TAG_BITS_SHIFT = 48; + constexpr uint64_t TAG_MARK = 0xFFFFULL << TAG_BITS_SHIFT; + constexpr uint64_t TAG_SPECIAL = 0x02ULL; + constexpr uint64_t TAG_BOOLEAN = 0x04ULL; + constexpr uint64_t TAG_HEAP_OBJECT_MASK = TAG_MARK | TAG_SPECIAL | TAG_BOOLEAN; + + RefField<> field(MAddress(0)); + BaseObject *obj = reinterpret_cast(TAG_HEAP_OBJECT_MASK); + idleBarrier->WriteBarrier(obj, field, obj); + EXPECT_TRUE(obj != nullptr); +} + +HWTEST_F_L0(IdleBarrierTest, WriteBarrier_TEST2) +{ + MockCollector collector; + auto idleBarrier = std::make_unique(collector); + ASSERT_TRUE(idleBarrier != nullptr); + + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); + RefField<> field(obj); + idleBarrier->WriteBarrier(obj, field, obj); + EXPECT_TRUE(obj != nullptr); +} + HWTEST_F_L0(IdleBarrierTest, WriteStruct_TEST0) { MockCollector collector; diff --git a/common_components/heap/w_collector/tests/post_trace_barrier_test.cpp b/common_components/heap/w_collector/tests/post_trace_barrier_test.cpp index 7b7eb4221a98491ac2dfb94db2af7835ca385437..b5f8f0d46b1280e6271e0f6c824f5e7c93eed990 100755 --- a/common_components/heap/w_collector/tests/post_trace_barrier_test.cpp +++ b/common_components/heap/w_collector/tests/post_trace_barrier_test.cpp @@ -100,6 +100,39 @@ HWTEST_F_L0(PostTraceBarrierTest, ReadStringTableStaticRef_TEST1) ASSERT_TRUE(resultObj == nullptr); } +HWTEST_F_L0(PostTraceBarrierTest, ReadStringTableStaticRef_TEST2) +{ + MockCollector collector; + auto postTraceBarrier = std::make_unique(collector); + ASSERT_TRUE(postTraceBarrier != nullptr); + + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); + RegionDesc *regionInfo = RegionDesc::GetRegionDescAt(addr); + regionInfo->SetRegionAllocPtr(addr - 1); + regionInfo->SetTraceLine(); + RefField field(obj); + + BaseObject* resultObj = postTraceBarrier->ReadStringTableStaticRef(field); + ASSERT_TRUE(resultObj != nullptr); +} + +HWTEST_F_L0(PostTraceBarrierTest, ReadStringTableStaticRef_TEST3) +{ + MockCollector collector; + auto postTraceBarrier = std::make_unique(collector); + ASSERT_TRUE(postTraceBarrier != nullptr); + + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); + RegionDesc *regionInfo = RegionDesc::GetRegionDescAt(addr); + regionInfo->SetRegionType(RegionDesc::RegionType::FREE_REGION); + RefField field(obj); + + BaseObject* resultObj = postTraceBarrier->ReadStringTableStaticRef(field); + ASSERT_TRUE(resultObj == nullptr); +} + HWTEST_F_L0(PostTraceBarrierTest, WriteRefField_TEST1) { MockCollector collector; @@ -120,6 +153,33 @@ HWTEST_F_L0(PostTraceBarrierTest, WriteRefField_TEST1) EXPECT_EQ(newAddr, reinterpret_cast(newObj)); } +HWTEST_F_L0(PostTraceBarrierTest, WriteBarrier_TEST1) +{ + MockCollector collector; + auto postTraceBarrier = std::make_unique(collector); + ASSERT_TRUE(postTraceBarrier != nullptr); + + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); + RefField<> field(obj); + postTraceBarrier->WriteBarrier(obj, field, obj); + EXPECT_TRUE(obj != nullptr); +} + +HWTEST_F_L0(PostTraceBarrierTest, WriteBarrier_TEST2) +{ + MockCollector collector; + auto postTraceBarrier = std::make_unique(collector); + ASSERT_TRUE(postTraceBarrier != nullptr); + + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); + RefField<> field(obj); + Heap::GetHeap().SetGCReason(GC_REASON_YOUNG); + postTraceBarrier->WriteBarrier(obj, field, obj); + EXPECT_TRUE(obj != nullptr); +} + HWTEST_F_L0(PostTraceBarrierTest, ReadStruct_TEST1) { MockCollector collector; diff --git a/common_components/heap/w_collector/tests/preforward_barrier_test.cpp b/common_components/heap/w_collector/tests/preforward_barrier_test.cpp index 5fc7972ce2a8ae8887b4590102fed241f098cc28..cfb93cb24903d1fbe836ed9e8a05e128b89c990e 100755 --- a/common_components/heap/w_collector/tests/preforward_barrier_test.cpp +++ b/common_components/heap/w_collector/tests/preforward_barrier_test.cpp @@ -178,6 +178,36 @@ HWTEST_F_L0(PreforwardBarrierTest, ReadStringTableStaticRef_TEST1) ASSERT_TRUE(resultObj == nullptr); } +HWTEST_F_L0(PreforwardBarrierTest, ReadStringTableStaticRef_TEST2) +{ + MockCollector collector; + auto preforwardBarrier = std::make_unique(collector); + ASSERT_TRUE(preforwardBarrier != nullptr); + + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); + RefField field(obj); + + BaseObject* resultObj = preforwardBarrier->ReadStringTableStaticRef(field); + ASSERT_TRUE(resultObj != nullptr); +} + +HWTEST_F_L0(PreforwardBarrierTest, ReadStringTableStaticRef_TEST3) +{ + MockCollector collector; + auto preforwardBarrier = std::make_unique(collector); + ASSERT_TRUE(preforwardBarrier != nullptr); + + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); + RegionDesc *regionInfo = RegionDesc::GetRegionDescAt(addr); + regionInfo->SetRegionType(RegionDesc::RegionType::FREE_REGION); + RefField field(obj); + + BaseObject* resultObj = preforwardBarrier->ReadStringTableStaticRef(field); + ASSERT_TRUE(resultObj == nullptr); +} + HWTEST_F_L0(PreforwardBarrierTest, ReadStruct_TEST1) { MockCollector collector; diff --git a/common_components/heap/w_collector/tests/remark_barrier_test.cpp b/common_components/heap/w_collector/tests/remark_barrier_test.cpp index 22c13b4f95753e4442982392472ed59c3778f443..eb52d4fab675e9fb31194104364ff160e854df9b 100755 --- a/common_components/heap/w_collector/tests/remark_barrier_test.cpp +++ b/common_components/heap/w_collector/tests/remark_barrier_test.cpp @@ -97,6 +97,39 @@ HWTEST_F_L0(RemarkBarrierTest, ReadStringTableStaticRef_TEST1) ASSERT_TRUE(resultObj == nullptr); } +HWTEST_F_L0(RemarkBarrierTest, ReadStringTableStaticRef_TEST2) +{ + MockCollector collector; + auto remarkBarrier = std::make_unique(collector); + ASSERT_TRUE(remarkBarrier != nullptr); + + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); + RegionDesc *regionInfo = RegionDesc::GetRegionDescAt(addr); + regionInfo->SetRegionAllocPtr(addr - 1); + regionInfo->SetTraceLine(); + RefField field(obj); + + BaseObject* resultObj = remarkBarrier->ReadStringTableStaticRef(field); + ASSERT_TRUE(resultObj != nullptr); +} + +HWTEST_F_L0(RemarkBarrierTest, ReadStringTableStaticRef_TEST3) +{ + MockCollector collector; + auto remarkBarrier = std::make_unique(collector); + ASSERT_TRUE(remarkBarrier != nullptr); + + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); + RegionDesc *regionInfo = RegionDesc::GetRegionDescAt(addr); + regionInfo->SetRegionType(RegionDesc::RegionType::FREE_REGION); + RefField field(obj); + + BaseObject* resultObj = remarkBarrier->ReadStringTableStaticRef(field); + ASSERT_TRUE(resultObj == nullptr); +} + HWTEST_F_L0(RemarkBarrierTest, ReadStruct_TEST1) { MockCollector collector; @@ -221,6 +254,21 @@ HWTEST_F_L0(RemarkBarrierTest, WriteBarrier_TEST2) #endif } +HWTEST_F_L0(RemarkBarrierTest, WriteBarrier_TEST3) +{ + MockCollector collector; + auto remarkBarrier = std::make_unique(collector); + ASSERT_TRUE(remarkBarrier != nullptr); + +#ifndef ARK_USE_SATB_BARRIER + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); + RefField<> field(obj); + remarkBarrier->WriteBarrier(obj, field, obj); + EXPECT_TRUE(obj != nullptr); +#endif +} + HWTEST_F_L0(RemarkBarrierTest, WriteStruct_TEST1) { MockCollector collector; @@ -239,6 +287,27 @@ HWTEST_F_L0(RemarkBarrierTest, WriteStruct_TEST1) EXPECT_EQ(srcBuffer[0], dstBuffer[0]); } +HWTEST_F_L0(RemarkBarrierTest, WriteStruct_TEST2) +{ + MockCollector collector; + auto remarkBarrier = std::make_unique(collector); + ASSERT_TRUE(remarkBarrier != nullptr); + + auto objPtr = std::make_unique(); + constexpr size_t size = 16; + auto srcBuffer = std::make_unique(size); + auto dstBuffer = std::make_unique(size); + srcBuffer[0] = 1; + HeapAddress src = reinterpret_cast(srcBuffer.get()); + HeapAddress dst = reinterpret_cast(dstBuffer.get()); + auto mutator = ThreadLocal::GetMutator(); + ThreadLocal::SetMutator(nullptr); + remarkBarrier->WriteStruct(objPtr.get(), dst, size, src, size); + ThreadLocal::SetMutator(mutator); + EXPECT_EQ(dstBuffer[0], 1); + EXPECT_EQ(srcBuffer[0], dstBuffer[0]); +} + HWTEST_F_L0(RemarkBarrierTest, AtomicReadRefField_TEST1) { MockCollector collector; diff --git a/common_components/heap/w_collector/tests/trace_barrier_test.cpp b/common_components/heap/w_collector/tests/trace_barrier_test.cpp index 4ae48b653905e126afdc6c600d298a53786b4998..e1ad449e9b71a2ebd42b5862c6ac7d556e7f87f7 100755 --- a/common_components/heap/w_collector/tests/trace_barrier_test.cpp +++ b/common_components/heap/w_collector/tests/trace_barrier_test.cpp @@ -208,6 +208,61 @@ HWTEST_F_L0(TraceBarrierTest, WriteBarrier_TEST2) #endif } +HWTEST_F_L0(TraceBarrierTest, WriteBarrier_TEST3) +{ + MockCollector collector; + auto traceBarrier = std::make_unique(collector); + ASSERT_TRUE(traceBarrier != nullptr); + +#ifndef ARK_USE_SATB_BARRIER + HeapAddress addr = HeapManager::Allocate(sizeof(BaseObject), AllocType::MOVEABLE_OBJECT, true); + BaseObject* obj = reinterpret_cast(addr); + RefField<> field(obj); + Heap::GetHeap().SetGCReason(GC_REASON_YOUNG); + traceBarrier->WriteBarrier(obj, field, obj); + EXPECT_TRUE(obj != nullptr); +#endif +} + +HWTEST_F_L0(TraceBarrierTest, WriteStruct_TEST1) +{ + MockCollector collector; + auto traceBarrier = std::make_unique(collector); + ASSERT_TRUE(traceBarrier != nullptr); + + auto objPtr = std::make_unique(); + constexpr size_t size = 16; + auto srcBuffer = std::make_unique(size); + auto dstBuffer = std::make_unique(size); + srcBuffer[0] = 1; + HeapAddress src = reinterpret_cast(srcBuffer.get()); + HeapAddress dst = reinterpret_cast(dstBuffer.get()); + traceBarrier->WriteStruct(objPtr.get(), dst, size, src, size); + EXPECT_EQ(dstBuffer[0], 1); + EXPECT_EQ(srcBuffer[0], dstBuffer[0]); +} + +HWTEST_F_L0(TraceBarrierTest, WriteStruct_TEST2) +{ + MockCollector collector; + auto traceBarrier = std::make_unique(collector); + ASSERT_TRUE(traceBarrier != nullptr); + + auto objPtr = std::make_unique(); + constexpr size_t size = 16; + auto srcBuffer = std::make_unique(size); + auto dstBuffer = std::make_unique(size); + srcBuffer[0] = 1; + HeapAddress src = reinterpret_cast(srcBuffer.get()); + HeapAddress dst = reinterpret_cast(dstBuffer.get()); + auto mutator = ThreadLocal::GetMutator(); + ThreadLocal::SetMutator(nullptr); + traceBarrier->WriteStruct(objPtr.get(), dst, size, src, size); + ThreadLocal::SetMutator(mutator); + EXPECT_EQ(dstBuffer[0], 1); + EXPECT_EQ(srcBuffer[0], dstBuffer[0]); +} + HWTEST_F_L0(TraceBarrierTest, AtomicReadRefField_TEST1) { MockCollector collector; diff --git a/common_components/mutator/tests/BUILD.gn b/common_components/mutator/tests/BUILD.gn index 442f3c15abc184ea51473ab9318871c1cf0c895c..3dab850414454edd80e1a889edf55e8b6b2e3495 100755 --- a/common_components/mutator/tests/BUILD.gn +++ b/common_components/mutator/tests/BUILD.gn @@ -61,12 +61,36 @@ host_unittest_action("Satb_Buffer_Test") { ] } +host_unittest_action("Thread_Local_Test") { + module_out_path = module_output_path + + sources = [ + # test file + "thread_local_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 = [ ":Mutator_Manager_Test", + ":Thread_Local_Test", ] } @@ -76,5 +100,6 @@ group("host_unittest") { # deps file deps = [ ":Mutator_Manager_TestAction", + ":Thread_Local_TestAction", ] } diff --git a/common_components/mutator/tests/thread_local_test.cpp b/common_components/mutator/tests/thread_local_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8ee8f5cbf99655b60e50f1742febd376fd28d4a1 --- /dev/null +++ b/common_components/mutator/tests/thread_local_test.cpp @@ -0,0 +1,31 @@ +/* + * 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/mutator/thread_local.h" +#include "common_components/tests/test_helper.h" + +namespace common { + +class ThreadLocalTest : public common::test::BaseTestWithScope { +protected: + void SetUp() override {} + void TearDown() override {} +}; + +HWTEST_F_L0(ThreadLocalTest, GetThreadLocalData_ReturnsNonNull) { + ThreadLocalData* data = ThreadLocal::GetThreadLocalData(); + EXPECT_NE(data, nullptr); +} +} \ No newline at end of file diff --git a/common_components/objects/tests/BUILD.gn b/common_components/objects/tests/BUILD.gn index e6d55ad7b48d80040124371fc808a3d69a2713c7..f6d6aef286200b053228b029438d395273870142 100755 --- a/common_components/objects/tests/BUILD.gn +++ b/common_components/objects/tests/BUILD.gn @@ -40,12 +40,64 @@ host_unittest_action("Base_String_Test") { ] } +host_unittest_action("Base_String_Table_Test") { + module_out_path = module_output_path + + sources = [ + # test file + "base_string_table_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", + ] +} + +host_unittest_action("Composite_Base_Class_Test") { + module_out_path = module_output_path + + sources = [ + # test file + "composite_base_class_test.cpp", + "//arkcompiler/ets_runtime/common_components/objects/base_string.cpp", + "//arkcompiler/ets_runtime/common_components/base/utf_helper.cpp", + "base_string_table_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 = [ ":Base_String_Test", + ":Base_String_Table_Test", + ":Composite_Base_Class_Test", ] } @@ -55,5 +107,7 @@ group("host_unittest") { # deps file deps = [ ":Base_String_TestAction", + ":Base_String_Table_TestAction", + ":Composite_Base_Class_TestAction", ] } diff --git a/common_components/objects/tests/base_string_table_test.cpp b/common_components/objects/tests/base_string_table_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..aa165055f1b83685b0faa961d924c2bb8705d48a --- /dev/null +++ b/common_components/objects/tests/base_string_table_test.cpp @@ -0,0 +1,112 @@ +/* + * 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/tests/test_helper.h" +#include "common_interfaces/objects/base_string_table.h" +#include "common_components/objects/string_table_internal.h" +#include "common_interfaces/thread/mutator_base.h" +#include "common_interfaces/objects/base_string.h" +#include "common_interfaces/thread/thread_holder.h" +#include "common_interfaces/base_runtime.h" +#include "common_interfaces/heap/heap_allocator.h" +#include "common_interfaces/objects/string/base_string-inl2.h" + + +namespace common { + +struct DummyMutator : public MutatorBase { + explicit DummyMutator(LanguageType lang) : lang_(lang) {} + LanguageType lang_; +}; + +class BaseStringTableTest : public common::test::BaseTestWithScope { +protected: + using TableType = BaseStringTableInternal; + BaseRuntime* runtime_; + std::unique_ptr mutator_; + std::unique_ptr table_; + ThreadHolder* threadHolder_; + + void SetUp() override + { + mutator_ = std::make_unique(LanguageType::DYNAMIC); + threadHolder_ = new ThreadHolder(mutator_.get()); + + runtime_ = BaseRuntime::GetInstance(); + ASSERT_TRUE(runtime_ != nullptr); + + runtime_->Init(); + + table_ = std::make_unique(); + } + + void TearDown() override + { + table_.reset(); + + if (runtime_) { + runtime_->Fini(); + } + + mutator_.reset(); + threadHolder_ = nullptr; + } + + BaseString* CreateUtf8String(const char* utf8Data, uint32_t length, bool canBeCompress) + { + auto allocator = [](size_t size, CommonType type) -> BaseString* { + void* mem = reinterpret_cast(HeapAllocator::AllocateInOldOrHuge(size, LanguageType::DYNAMIC)); + if (mem == nullptr) { + return nullptr; + } + return reinterpret_cast(mem); + }; + + BaseString* str = BaseString::CreateFromUtf8(allocator, + reinterpret_cast(utf8Data), length, canBeCompress); + + if (str == nullptr) { + return nullptr; + } + return str; + } + + static ReadOnlyHandle MockHandleCreator(ThreadHolder* holder, BaseString* str) + { + uintptr_t handleValue = reinterpret_cast(str); + return ReadOnlyHandle(handleValue); + } +}; + +HWTEST_F_L0(BaseStringTableTest, SweepWeakRef) +{ + WeakRefFieldVisitor mockVisitor = [](RefField& field) { + return true; + }; + + table_->GetHashTrieMap().StartSweeping(); + table_->SweepWeakRef(mockVisitor); + table_->GetHashTrieMap().FinishSweeping(); + + EXPECT_TRUE(true); +} + +HWTEST_F_L0(BaseStringTableTest, CleanUp) +{ + table_->GetHashTrieMap().Clear(); + EXPECT_TRUE(true); +} + +} \ No newline at end of file diff --git a/common_components/objects/tests/composite_base_class_test.cpp b/common_components/objects/tests/composite_base_class_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d5a1c91b7f19b1f4c39b001150f8cdc4a4e6a2b7 --- /dev/null +++ b/common_components/objects/tests/composite_base_class_test.cpp @@ -0,0 +1,114 @@ +/* +* 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/tests/test_helper.h" +#include "common_interfaces/objects/composite_base_class.h" +#include "common_interfaces/objects/base_object.h" + +#include +#include +#include + +namespace common { +class CompositeBaseClassTest : public test::BaseTestWithScope { +protected: + static CompositeBaseClass* MockAllocator() + { + void* memory = ::operator new(sizeof(uint64_t) * 16); + + auto* baseClass = reinterpret_cast(memory); + baseClass->SetObjectType(CommonType::LINE_STRING); + baseClass->ClearBitField(); + + return reinterpret_cast(baseClass); + } + + void SetUp() override + { + roots_ = std::make_unique(); + } + + void TearDown() override + { + roots_.reset(); + } + + std::unique_ptr roots_; +}; + +HWTEST_F_L0(CompositeBaseClassTest, InitializeOnce) +{ + auto allocator = []() -> CompositeBaseClass* { + return CompositeBaseClassTest::MockAllocator(); + }; + + roots_->InitializeCompositeBaseClass(allocator); + roots_->InitializeCompositeBaseClass(allocator); + + EXPECT_TRUE(true); +} + +HWTEST_F_L0(CompositeBaseClassTest, CreateAndGetType) +{ + auto allocator = []() -> CompositeBaseClass* { + return CompositeBaseClassTest::MockAllocator(); + }; + + roots_->InitializeCompositeBaseClass(allocator); + + auto* baseClass = roots_->GetBaseClass(CommonType::LINE_STRING); + ASSERT_NE(baseClass, nullptr); + EXPECT_EQ(baseClass->GetObjectType(), CommonType::LINE_STRING); +} + +HWTEST_F_L0(CompositeBaseClassTest, GetBaseClassReturnsCorrectType) +{ + auto allocator = []() -> CompositeBaseClass* { + return CompositeBaseClassTest::MockAllocator(); + }; + + roots_->InitializeCompositeBaseClass(allocator); + + auto* lineString = roots_->GetBaseClass(CommonType::LINE_STRING); + auto* slicedString = roots_->GetBaseClass(CommonType::SLICED_STRING); + auto* treeString = roots_->GetBaseClass(CommonType::TREE_STRING); + + ASSERT_NE(lineString, nullptr); + ASSERT_NE(slicedString, nullptr); + ASSERT_NE(treeString, nullptr); + + EXPECT_EQ(lineString->GetObjectType(), CommonType::LINE_STRING); + EXPECT_EQ(slicedString->GetObjectType(), CommonType::SLICED_STRING); + EXPECT_EQ(treeString->GetObjectType(), CommonType::TREE_STRING); +} + +HWTEST_F_L0(CompositeBaseClassTest, IterateCompositeBaseClass) +{ + auto allocator = []() -> CompositeBaseClass* { + return CompositeBaseClassTest::MockAllocator(); + }; + + roots_->InitializeCompositeBaseClass(allocator); + + std::vector visited; + + roots_->IterateCompositeBaseClass([&visited](RefField<>& field) { + auto* ptr = reinterpret_cast(const_cast(static_cast(&field))); + visited.push_back(ptr); + }); + + EXPECT_EQ(visited.size(), 3); +} +} \ No newline at end of file diff --git a/common_components/platform/unix/tests/BUILD.gn b/common_components/platform/unix/tests/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..645bc239e757bdcf47648a53405ed36f343d7c4d --- /dev/null +++ b/common_components/platform/unix/tests/BUILD.gn @@ -0,0 +1,57 @@ +# 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. + +import("//arkcompiler/ets_runtime/common_components/tests/test_helper.gni") + +module_output_path = "ets_runtime" + +host_unittest_action("Map_Test") { + module_out_path = module_output_path + + sources = [ + # test file + "map_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 = [ + ":Map_Test", + ] +} + +group("host_unittest") { + testonly = true + + # deps file + deps = [ + ":Map_TestAction", + ] +} \ No newline at end of file diff --git a/common_components/platform/unix/tests/map_test.cpp b/common_components/platform/unix/tests/map_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4032e3a1862d42c446a7d20af79775776adced52 --- /dev/null +++ b/common_components/platform/unix/tests/map_test.cpp @@ -0,0 +1,44 @@ +/* + * 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/tests/test_helper.h" +#include "common_components/platform/map.h" + +#include +#include + +class PageProtectTest : public common::test::BaseTestWithScope { +protected: + void SetUp() override {} + void TearDown() override {} +}; + +HWTEST_F_L0(PageProtectTest, TestPageProtect) +{ + size_t pageSize = getpagesize(); + void* mem = mmap(nullptr, pageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + ASSERT_NE(mem, MAP_FAILED); + + bool success = common::PageProtect(mem, pageSize, PROT_READ); + EXPECT_TRUE(success); + + munmap(mem, pageSize); +} + +HWTEST_F_L0(PageProtectTest, TestNullptrMemory) +{ + bool success = common::PageProtect(nullptr, getpagesize(), PROT_READ); + EXPECT_FALSE(success); +} \ No newline at end of file diff --git a/common_components/taskpool/tests/BUILD.gn b/common_components/taskpool/tests/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..08785eb844818da61db9f568acbc374d8aff04b2 --- /dev/null +++ b/common_components/taskpool/tests/BUILD.gn @@ -0,0 +1,82 @@ +# 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. + +import("//arkcompiler/ets_runtime/common_components/tests/test_helper.gni") + +module_output_path = "ets_runtime" + +host_unittest_action("Runner_Test") { + module_out_path = module_output_path + + sources = [ + # test file + "runner_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", + ] +} + +host_unittest_action("Taskpool_Test") { + module_out_path = module_output_path + + sources = [ + # test file + "taskpool_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 = [ + ":Runner_Test", + ":Taskpool_Test", + ] +} + +group("host_unittest") { + testonly = true + + # deps file + deps = [ + ":Runner_TestAction", + ":Taskpool_TestAction", + ] +} \ No newline at end of file diff --git a/common_components/taskpool/tests/runner_test.cpp b/common_components/taskpool/tests/runner_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4e005bdccb77c35977e50caa47511aa4166e141a --- /dev/null +++ b/common_components/taskpool/tests/runner_test.cpp @@ -0,0 +1,65 @@ +/* + * 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/tests/test_helper.h" +#include "common_components/taskpool/runner.h" + +#include +#include +#include +#include + +namespace common { +class RunnerTest : public common::test::BaseTestWithScope { +protected: + void SetUp() override {} + void TearDown() override {} + + static std::function CreateMockPrologueHook() + { + return [](native_handle_type handle) {}; + } + + static std::function CreateMockEpilogueHook() + { + return [](native_handle_type handle) {}; + } +}; + +class MockTask : public Task { +public: + explicit MockTask(int32_t id) + : Task(id), executed_(false) {} + + bool Run(uint32_t threadId) override + { + executed_ = true; + return true; + } + + bool IsExecuted() const { return executed_; } + +private: + std::atomic executed_; +}; + +HWTEST_F_L0(RunnerTest, InitializeRunnerWithThreads) { + constexpr uint32_t threadNum = 4; + Runner runner(threadNum, RunnerTest::CreateMockPrologueHook(), RunnerTest::CreateMockEpilogueHook()); + EXPECT_EQ(runner.GetTotalThreadNum(), threadNum); + + runner.TerminateThread(); +} +} \ No newline at end of file diff --git a/common_components/taskpool/tests/taskpool_test.cpp b/common_components/taskpool/tests/taskpool_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5e22daf35ca5fd008ed0fa8790af9d2b405a2dbc --- /dev/null +++ b/common_components/taskpool/tests/taskpool_test.cpp @@ -0,0 +1,92 @@ +/* + * 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/tests/test_helper.h" +#include "common_components/taskpool/taskpool.h" +#include "common_components/taskpool/task.h" + +#include +#include +#include + +namespace common { + +class MockTask : public Task { +public: + explicit MockTask(int32_t id) + : Task(id), executed_(false) {} + + bool Run(uint32_t threadId) override + { + executed_ = true; + return true; + } + + bool IsExecuted() const { return executed_; } + +private: + std::atomic executed_; +}; + +class TaskpoolTest : public common::test::BaseTestWithScope { +protected: + void SetUp() override {} + void TearDown() override {} + + class ScopedTaskpool { + public: + explicit ScopedTaskpool(int threadNum = DEFAULT_TASKPOOL_THREAD_NUM) + : isInitialized_(false) + { + isInitialized_ = true; + pool_.Initialize(threadNum); + } + + Taskpool* Get() + { + return &pool_; + } + + private: + Taskpool pool_; + bool isInitialized_; + }; +}; + +HWTEST_F_L0(TaskpoolTest, InitializeAndDestroy) { + TaskpoolTest::ScopedTaskpool pool(2); + EXPECT_NE(pool.Get(), nullptr); + EXPECT_GT(pool.Get()->GetTotalThreadNum(), 0U); +} + +HWTEST_F_L0(TaskpoolTest, SetQosPriority) { + TaskpoolTest::ScopedTaskpool pool(1); + pool.Get()->SetThreadPriority(PriorityMode::BACKGROUND); +} + +HWTEST_F_L0(TaskpoolTest, ForEachTask) { + TaskpoolTest::ScopedTaskpool pool(1); + + auto task = std::make_unique(1); + pool.Get()->PostTask(std::move(task)); + + std::atomic count(0); + pool.Get()->ForEachTask([&count](Task* t) { + count++; + }); + + EXPECT_EQ(count.load(), 1); +} +} \ No newline at end of file diff --git a/common_components/tests/ohos_test.xml b/common_components/tests/ohos_test.xml index a9332b249edfadefb88244a85a60ce144a938823..972245bcf7873b60b39b819a93280e1dd5273f54 100644 --- a/common_components/tests/ohos_test.xml +++ b/common_components/tests/ohos_test.xml @@ -43,6 +43,11 @@