1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "ecmascript/tests/test_helper.h"
17 #include "ecmascript/dfx/hprof/rawheap_translate/metadata_parse.h"
18 #include "ecmascript/dfx/hprof/rawheap_translate/utils.h"
19
20 using namespace panda::ecmascript;
21
22 namespace panda::test {
23 class RawHeapTranslateTest : public testing::Test {
24 public:
SetUpTestCase()25 static void SetUpTestCase()
26 {
27 GTEST_LOG_(INFO) << "SetUpTestCase";
28 }
29
TearDownTestCase()30 static void TearDownTestCase()
31 {
32 GTEST_LOG_(INFO) << "TearDownCase";
33 }
34
SetUp()35 void SetUp() override
36 {
37 meta = std::make_unique<rawheap_translate::Meta>();
38 }
39
TearDown()40 void TearDown() override
41 {
42 }
43
44 std::unique_ptr<rawheap_translate::Meta> meta {nullptr};
45 };
46
HWTEST_F_L0(RawHeapTranslateTest,MetaDataParse)47 HWTEST_F_L0(RawHeapTranslateTest, MetaDataParse)
48 {
49 /*
50 metadataJson a json is similar to the following example
51 {
52 "type_enum": {"INVALID": 8},
53 "type_list": [
54 {
55 "name": "JS_OBJECT",
56 "offsets": [
57 {
58 "name": "Properties",
59 "offset": 0,
60 "size": 8
61 },
62 {
63 "name": "Elements",
64 "offset": 8,
65 "size": 8
66 }
67 ],
68 "end_offset": 16,
69 "parents": [
70 "ECMA_OBJECT"
71 ]
72 },
73 {
74 "name": "ECMA_OBJECT",
75 "offsets": [],
76 "end_offset": 8,
77 "parents": [
78 "TAGGED_OBJECT"
79 ]
80 },
81 {
82 "name": "TAGGED_OBJECT",
83 "offsets": [],
84 "end_offset": 8,
85 "parents": []
86 }
87 ],
88 "type_layout": {
89 "Dictionary_layout": {
90 "name": "Dictionary",
91 "key_index": 0,
92 "value_index": 1,
93 "detail_index": 2,
94 "entry_size": 3,
95 "header_size": 4
96 },
97 "Type_range": {
98 "string_first": "LINE_STRING",
99 "string_last": "TREE_STRING",
100 "js_object_first": "JS_OBJECT",
101 "js_object_last": "JS_GLOBAL_OBJECT"
102 }
103 },
104 "version": "1.0.0"
105 }
106 */
107 std::string metadataJson =
108 "{\"type_enum\": {\"INVALID\": 8}, \"type_list\": [{\"name\": \"JS_OBJECT\","
109 "\"offsets\": [{\"name\": \"Properties\", \"offset\": 0, \"size\": 8}, "
110 "{\"name\": \"Elements\", \"offset\": 8, \"size\": 8}], \"end_offset\": 16, "
111 "\"parents\": [\"ECMA_OBJECT\"]}, {\"name\": \"ECMA_OBJECT\", \"offsets\": [], "
112 "\"end_offset\": 8, \"parents\": [\"TAGGED_OBJECT\"]}, {\"name\": \"TAGGED_OBJECT\", "
113 "\"offsets\": [], \"end_offset\": 8, \"parents\": []}], \"type_layout\": {\"Dictionary_layout\": {"
114 "\"name\": \"Dictionary\", \"key_index\": 0, \"value_index\": 1, \"detail_index\": 2, "
115 "\"entry_size\": 3, \"header_size\": 4}, \"Type_range\": {\"string_first\": \"LINE_STRING\", "
116 "\"string_last\": \"TREE_STRING\", \"js_object_first\": \"JS_OBJECT\", \"js_object_last\": "
117 "\"JS_GLOBAL_OBJECT\"}}, \"version\": \"1.0.0\"}";
118
119 cJSON *metadataCJson = cJSON_ParseWithOpts(metadataJson.c_str(), nullptr, true);
120 ASSERT_TRUE(metadataCJson != nullptr);
121
122 bool result = meta->Parse(metadataCJson);
123 cJSON_Delete(metadataCJson);
124 ASSERT_TRUE(result);
125
126 auto visit = [] ([[maybe_unused]]std::shared_ptr<rawheap_translate::MetaData> &metadata,
127 [[maybe_unused]]int offset) {};
128 uint32_t baseOffset = 0;
129 meta->VisitObjectBody("JS_OBJECT", visit, baseOffset);
130 ASSERT_TRUE(baseOffset == 32); // 32: 16 + 8 + 8 = 32, all parent endOffset count total
131 }
132
HWTEST_F_L0(RawHeapTranslateTest,BytesToNumber)133 HWTEST_F_L0(RawHeapTranslateTest, BytesToNumber)
134 {
135 char bytes[4] = {0x78, 0x56, 0x34, 0x12}; // write by little endian
136
137 uint32_t u32 = rawheap_translate::ByteToU32(bytes);
138 if (rawheap_translate::IsLittleEndian()) {
139 ASSERT_TRUE(u32 == 0x12345678);
140 } else {
141 ASSERT_TRUE(u32 == 0x78563412);
142 }
143 }
144 } // namespace panda::test
145