1 /*
2 * Copyright (c) 2025 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 #include <gtest/gtest.h>
16 #include <string>
17 #include <thread>
18 #include <chrono>
19 #include <cstdio>
20 #include <fstream>
21 #include <iostream>
22 #include <algorithm>
23 #include "hpae_dfx_tree.h"
24 #include <locale>
25 using namespace testing::ext;
26 using namespace testing;
27
28 namespace OHOS {
29 namespace AudioStandard {
30 namespace HPAE {
31
32 constexpr uint32_t NUM_TWO = 2;
33 constexpr uint32_t NUM_THREE = 3;
34 constexpr uint32_t NUM_FOUR = 4;
35 constexpr uint32_t NODE_ID_100 = 100;
36 constexpr uint32_t NODE_ID_101 = 101;
37 constexpr uint32_t NODE_ID_102 = 102;
38 constexpr uint32_t NODE_ID_103 = 103;
39 constexpr uint32_t NODE_ID_123 = 123;
40 constexpr uint32_t NODE_ID_999 = 999;
41
42 class HpaeDfxTreeTest : public testing::Test {
43 public:
44 void SetUp();
45 void TearDown();
46 HpaeDfxTree CreateSampleTree();
FindNode(HpaeDfxTree & tree,uint32_t nodeId)47 DfxTreeNode *FindNode(HpaeDfxTree &tree, uint32_t nodeId)
48 {
49 return tree.FindDfxNode(tree.GetRoot(), nodeId);
50 }
51 };
52
SetUp()53 void HpaeDfxTreeTest::SetUp()
54 {
55 std::locale::global(std::locale(""));
56 std::wcout.imbue(std::locale());
57 }
58
TearDown()59 void HpaeDfxTreeTest::TearDown()
60 {}
61
CreateSampleTree()62 HpaeDfxTree HpaeDfxTreeTest::CreateSampleTree()
63 {
64 HpaeDfxTree hpaeDfxTree;
65 HpaeDfxNodeInfo info;
66 uint32_t nodeId = NODE_ID_100;
67 uint32_t sessionId = 1000; // 1000: session id
68
69 info.nodeId = nodeId;
70 info.sessionId = sessionId;
71 hpaeDfxTree.Insert(0, info);
72
73 info.nodeId = nodeId + 1;
74 info.sessionId = sessionId + 1;
75 hpaeDfxTree.Insert(nodeId, info);
76
77 info.nodeId = nodeId + NUM_TWO;
78 info.sessionId = sessionId + NUM_TWO;
79 hpaeDfxTree.Insert(nodeId + 1, info);
80
81 info.nodeId = nodeId + NUM_THREE;
82 info.sessionId = sessionId + NUM_THREE;
83 hpaeDfxTree.Insert(nodeId + 1, info);
84
85 info.nodeId = nodeId + NUM_FOUR;
86 info.sessionId = sessionId + NUM_FOUR;
87 hpaeDfxTree.Insert(nodeId, info);
88
89 return hpaeDfxTree;
90 }
91
92 HWTEST_F(HpaeDfxTreeTest, constructHpaeDfxTreeTest, TestSize.Level0)
93 {
94 HpaeDfxTree hpaeDfxTree;
95 HpaeNodeInfo info;
96 uint32_t nodeId = NODE_ID_123;
97 uint32_t sessionId = 12345; // 12345: session id
98 size_t frameLen = 960; // 960: frameLen
99 uint32_t preNodeId = 0;
100 int32_t testNum = 10; // 10: testNum
101 for (int32_t i = 0; i < testNum; i++) {
102 preNodeId = info.nodeId;
103 info.nodeId = nodeId + i;
104 info.sessionId = sessionId + i;
105 info.nodeName = "testNode1";
106 info.frameLen = frameLen;
107 info.channels = STEREO;
108 info.samplingRate = SAMPLE_RATE_48000;
109 info.format = SAMPLE_F32LE;
110 info.sceneType = HPAE_SCENE_DEFAULT;
111 EXPECT_EQ(hpaeDfxTree.Insert(preNodeId, info), true);
112 }
113 std::vector<std::vector<HpaeDfxNodeInfo>> result = hpaeDfxTree.LevelOrderTraversal();
114 std::string outStr;
115 hpaeDfxTree.PrintTree(outStr);
116 std::cout << outStr.c_str() << std::endl;
117 int32_t index = 0;
118 for (int32_t i = 0; i < result.size(); i++) {
119 for (int32_t j = 0; j < result[i].size(); j++) {
120 EXPECT_EQ(result[i][j].nodeId, index + nodeId);
121 EXPECT_EQ(result[i][j].sessionId, index + sessionId);
122 EXPECT_EQ(result[i][j].frameLen, frameLen);
123 EXPECT_EQ(result[i][j].samplingRate, SAMPLE_RATE_48000);
124 EXPECT_EQ(result[i][j].channels, STEREO);
125 EXPECT_EQ(result[i][j].format, SAMPLE_F32LE);
126 index++;
127 }
128 }
129 }
130
131 HWTEST_F(HpaeDfxTreeTest, removeDfxTreeTest, TestSize.Level0)
132 {
133 HpaeDfxTree hpaeDfxTree;
134 HpaeNodeInfo info;
135 uint32_t nodeId = NODE_ID_123;
136 uint32_t sessionId = 12345; // 12345: session id
137 size_t frameLen = 960; // 960: frameLen
138 uint32_t preNodeId = 0;
139 int32_t testNum = 10; // 10: testLen
140 for (int32_t i = 0; i < testNum; i++) {
141 preNodeId = info.nodeId;
142 info.nodeId = nodeId + i;
143 info.sessionId = sessionId + i;
144 info.nodeName = "testNode2";
145 info.frameLen = frameLen;
146 info.channels = MONO;
147 info.samplingRate = SAMPLE_RATE_16000;
148 info.format = SAMPLE_F32LE;
149 info.sceneType = HPAE_SCENE_MUSIC;
150 EXPECT_EQ(hpaeDfxTree.Insert(preNodeId, info), true);
151 }
152 std::vector<std::vector<HpaeDfxNodeInfo>> result = hpaeDfxTree.LevelOrderTraversal();
153 EXPECT_EQ(result.size(), testNum);
154 uint32_t removeNodeIndex = NUM_THREE;
155 EXPECT_EQ(hpaeDfxTree.Remove(nodeId + removeNodeIndex), true);
156 std::string outStr;
157 hpaeDfxTree.PrintTree(outStr);
158 std::cout << outStr.c_str() << std::endl;
159 result = hpaeDfxTree.LevelOrderTraversal();
160 EXPECT_EQ(result.size(), removeNodeIndex);
161 }
162
163 HWTEST_F(HpaeDfxTreeTest, constructHpaeDfxTreeTest_002, TestSize.Level0)
164 {
165 HpaeDfxTree hpaeDfxTree;
166 HpaeDfxNodeInfo info;
167 uint32_t nodeId = NODE_ID_123;
168 uint32_t sessionId = 12345; // 12345: session id
169 size_t frameLen = 960; // 960: frameLen
170 uint32_t preNodeId = 0;
171 int32_t testNum = 10; // 10: testLen
172 for (int32_t i = 0; i < testNum; i++) {
173 preNodeId = info.nodeId;
174 info.nodeId = nodeId + i;
175 info.sessionId = sessionId + i;
176 info.nodeName = "testNode1";
177 info.frameLen = frameLen;
178 info.channels = STEREO;
179 info.samplingRate = SAMPLE_RATE_48000;
180 info.format = SAMPLE_F32LE;
181 info.sceneType = HPAE_SCENE_DEFAULT;
182 EXPECT_EQ(hpaeDfxTree.Insert(preNodeId, info), true);
183 }
184 std::vector<std::vector<HpaeDfxNodeInfo>> result = hpaeDfxTree.LevelOrderTraversal();
185 std::string outStr;
186 hpaeDfxTree.PrintTree(outStr);
187 std::cout << outStr.c_str() << std::endl;
188 int32_t index = 0;
189 for (int32_t i = 0; i < result.size(); i++) {
190 for (int32_t j = 0; j < result[i].size(); j++) {
191 EXPECT_EQ(result[i][j].nodeId, index + nodeId);
192 EXPECT_EQ(result[i][j].sessionId, index + sessionId);
193 EXPECT_EQ(result[i][j].frameLen, frameLen);
194 EXPECT_EQ(result[i][j].samplingRate, SAMPLE_RATE_48000);
195 EXPECT_EQ(result[i][j].channels, STEREO);
196 EXPECT_EQ(result[i][j].format, SAMPLE_F32LE);
197 index++;
198 }
199 }
200 }
201
202 HWTEST_F(HpaeDfxTreeTest, removeDfxTreeTest_002, TestSize.Level0)
203 {
204 HpaeDfxTree hpaeDfxTree = CreateSampleTree();
205
206 auto result = hpaeDfxTree.LevelOrderTraversal();
207 EXPECT_EQ(result.size(), NUM_THREE);
208 EXPECT_EQ(result[0].size(), 1);
209 EXPECT_EQ(result[1].size(), NUM_TWO);
210 EXPECT_EQ(result[NUM_TWO].size(), NUM_TWO);
211
212 EXPECT_EQ(hpaeDfxTree.Remove(NODE_ID_102), true);
213 result = hpaeDfxTree.LevelOrderTraversal();
214 EXPECT_EQ(result.size(), NUM_THREE);
215 EXPECT_EQ(result[NUM_TWO].size(), 1);
216
217 EXPECT_EQ(hpaeDfxTree.Remove(NODE_ID_101), true);
218 result = hpaeDfxTree.LevelOrderTraversal();
219 EXPECT_EQ(result.size(), NUM_TWO);
220
221 EXPECT_EQ(hpaeDfxTree.Remove(NODE_ID_999), false);
222 }
223
224 HWTEST_F(HpaeDfxTreeTest, emptyTreeOperations, TestSize.Level0)
225 {
226 HpaeDfxTree hpaeDfxTree;
227
228 EXPECT_EQ(hpaeDfxTree.Remove(NODE_ID_100), false);
229
230 auto result = hpaeDfxTree.LevelOrderTraversal();
231 EXPECT_TRUE(result.empty());
232
233 std::string outStr;
234 hpaeDfxTree.PrintTree(outStr);
235 EXPECT_TRUE(outStr.empty());
236 }
237
238 HWTEST_F(HpaeDfxTreeTest, invalidInsertionTest, TestSize.Level0)
239 {
240 HpaeDfxTree hpaeDfxTree;
241 HpaeDfxNodeInfo info;
242
243 info.nodeId = NODE_ID_100;
244 EXPECT_EQ(hpaeDfxTree.Insert(NODE_ID_999, info), true);
245
246 EXPECT_EQ(hpaeDfxTree.Insert(0, info), false);
247
248 EXPECT_EQ(hpaeDfxTree.Insert(NODE_ID_100, info), true);
249 }
250
251 HWTEST_F(HpaeDfxTreeTest, updateNodeInfoTest, TestSize.Level0)
252 {
253 HpaeDfxTree hpaeDfxTree = CreateSampleTree();
254
255 HpaeDfxNodeInfo newInfo;
256 newInfo.nodeId = NODE_ID_102;
257 newInfo.sessionId = 2000; // 2000: session id
258 newInfo.nodeName = "UpdatedNode";
259 newInfo.frameLen = 512; // 512: frame length
260 newInfo.channels = MONO;
261 newInfo.samplingRate = SAMPLE_RATE_44100;
262 newInfo.format = SAMPLE_S16LE;
263 newInfo.sceneType = HPAE_SCENE_MOVIE;
264
265 hpaeDfxTree.UpdateNodeInfo(NODE_ID_102, newInfo);
266
267 auto result = hpaeDfxTree.LevelOrderTraversal();
268 bool found = false;
269 for (const auto& level : result) {
270 for (const auto& node : level) {
271 if (node.nodeId == NODE_ID_102) {
272 found = true;
273 EXPECT_EQ(node.sessionId, 2000); // 2000: session id
274 EXPECT_EQ(node.frameLen, 512); // 512: frame length
275 EXPECT_EQ(node.channels, MONO);
276 EXPECT_EQ(node.samplingRate, SAMPLE_RATE_44100);
277 EXPECT_EQ(node.format, SAMPLE_S16LE);
278 EXPECT_EQ(node.sceneType, HPAE_SCENE_MOVIE);
279 }
280 }
281 }
282 EXPECT_TRUE(found);
283
284 hpaeDfxTree.UpdateNodeInfo(NODE_ID_999, newInfo);
285 }
286
287 HWTEST_F(HpaeDfxTreeTest, rootNodeOperations, TestSize.Level0)
288 {
289 HpaeDfxTree hpaeDfxTree;
290 HpaeDfxNodeInfo info;
291 info.nodeId = NODE_ID_100;
292
293 EXPECT_EQ(hpaeDfxTree.Insert(0, info), true);
294
295 EXPECT_EQ(hpaeDfxTree.Remove(NODE_ID_100), true);
296
297 auto result = hpaeDfxTree.LevelOrderTraversal();
298 EXPECT_TRUE(result.empty());
299
300 EXPECT_EQ(hpaeDfxTree.Remove(NODE_ID_100), false);
301 }
302
303 HWTEST_F(HpaeDfxTreeTest, treeTraversalBoundaryTest, TestSize.Level0)
304 {
305 HpaeDfxTree hpaeDfxTree;
306
307 HpaeDfxNodeInfo info;
308 info.nodeId = NODE_ID_100;
309 hpaeDfxTree.Insert(0, info);
310
311 auto result = hpaeDfxTree.LevelOrderTraversal();
312 ASSERT_EQ(result.size(), 1);
313 EXPECT_EQ(result[0].size(), 1);
314 EXPECT_EQ(result[0][0].nodeId, NODE_ID_100);
315
316 info.nodeId = NODE_ID_101;
317 hpaeDfxTree.Insert(NODE_ID_100, info);
318
319 result = hpaeDfxTree.LevelOrderTraversal();
320 ASSERT_EQ(result.size(), NUM_TWO);
321 EXPECT_EQ(result[0].size(), 1);
322 EXPECT_EQ(result[1].size(), 1);
323 }
324
325 HWTEST_F(HpaeDfxTreeTest, findParentNodeTest, TestSize.Level0)
326 {
327 HpaeDfxTree hpaeDfxTree = CreateSampleTree();
328 DfxTreeNode *root = hpaeDfxTree.GetRoot();
329 ASSERT_NE(root, nullptr);
330 EXPECT_EQ(root->nodeInfo_.nodeId, NODE_ID_100);
331
332 DfxTreeNode *node101 = hpaeDfxTree.FindDfxNode(root, NODE_ID_101);
333 ASSERT_NE(node101, nullptr);
334 EXPECT_EQ(node101->nodeInfo_.nodeId, NODE_ID_101);
335
336 DfxTreeNode *node102 = hpaeDfxTree.FindDfxNode(root, NODE_ID_102);
337 ASSERT_NE(node102, nullptr);
338 EXPECT_EQ(node102->nodeInfo_.nodeId, NODE_ID_102);
339
340 DfxTreeNode *parent = hpaeDfxTree.FindDfxParent(node102);
341 ASSERT_NE(parent, nullptr);
342 EXPECT_EQ(parent->nodeInfo_.nodeId, NODE_ID_101);
343
344 DfxTreeNode *node103 = hpaeDfxTree.FindDfxNode(root, NODE_ID_103);
345 ASSERT_NE(node103, nullptr);
346 parent = hpaeDfxTree.FindDfxParent(node103);
347 ASSERT_NE(parent, nullptr);
348 EXPECT_EQ(parent->nodeInfo_.nodeId, NODE_ID_101);
349
350 parent = hpaeDfxTree.FindDfxParent(root);
351 EXPECT_EQ(parent, nullptr);
352
353 HpaeDfxNodeInfo dummyInfo;
354 dummyInfo.nodeId = NODE_ID_999;
355 dummyInfo.nodeName = "dummy";
356 dummyInfo.sessionId = 9999; // 9999: session id
357 DfxTreeNode dummyNode(dummyInfo);
358
359 parent = hpaeDfxTree.FindDfxParent(&dummyNode);
360 EXPECT_EQ(parent, nullptr);
361 ASSERT_TRUE(hpaeDfxTree.Remove(NODE_ID_102));
362 EXPECT_EQ(hpaeDfxTree.FindDfxNode(root, NODE_ID_102), nullptr);
363 }
364 } // HPAE
365 } // AudioStandard
366 } // OHOS