1 /*
2  * Copyright (c) 2021 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 "hitrace/hitracechain.h"
17 
18 #include <cstdint>
19 #include <gtest/gtest.h>
20 #include <sys/time.h>
21 
22 #include "gtest/gtest-message.h"
23 #include "gtest/gtest-test-part.h"
24 #include "gtest/gtest_pred_impl.h"
25 #include "gtest/hwext/gtest-tag.h"
26 #include "hitrace/hitracechainc.h"
27 #include "hitrace/hitraceid.h"
28 #include "hitrace_meter.h"
29 #include "hitrace_meter_c.h"
30 
31 #define ARRAY_FIRST_INDEX 0
32 #define ARRAY_SECOND_INDEX 1
33 #define ARRAY_THIRD_INDEX 2
34 #define HASH_DATA_LENGTH 3
35 
36 #define DEVICE_CLIENT_SEND 12
37 #define PROCESS_CLIENT_SEND 22
38 #define THREAD_CLIENT_SEND 32
39 #define DEFAULT_CLIENT_SEND 42
40 
HashFunc(const void * pData,uint32_t dataLen)41 static uint64_t HashFunc(const void* pData, uint32_t dataLen)
42 {
43     const uint64_t seed = 131;
44     if ((!pData) || dataLen == 0) {
45         return 0;
46     }
47     uint64_t hash = 0;
48     uint64_t len = dataLen;
49     const char* p = static_cast<const char*>(pData);
50     for (; len > 0; --len) {
51         hash = (hash * seed) + (*p++);
52     }
53     return hash;
54 }
55 
GenerateChainId()56 static uint64_t GenerateChainId()
57 {
58     const uint64_t randomNum = 269;
59     uint64_t hashData[HASH_DATA_LENGTH];
60     struct timeval tv;
61     gettimeofday(&tv, nullptr);
62     srand(tv.tv_sec);
63     hashData[ARRAY_FIRST_INDEX] = tv.tv_sec;
64     hashData[ARRAY_SECOND_INDEX] = tv.tv_usec;
65     hashData[ARRAY_THIRD_INDEX] = randomNum;
66     uint64_t hash = HashFunc(hashData, HASH_DATA_LENGTH * sizeof(uint64_t));
67     return hash;
68 }
69 
70 
GenerateSpanId()71 static uint64_t GenerateSpanId()
72 {
73     const uint64_t randomNum = 269;
74     uint64_t hashData[HASH_DATA_LENGTH];
75     struct timeval tv;
76     gettimeofday(&tv, nullptr);
77     srand(tv.tv_sec);
78     hashData[ARRAY_FIRST_INDEX] = randomNum;
79     hashData[ARRAY_SECOND_INDEX] = tv.tv_sec;
80     hashData[ARRAY_THIRD_INDEX] = tv.tv_usec;
81     uint64_t hash = HashFunc(hashData, HASH_DATA_LENGTH * sizeof(uint64_t));
82     return hash;
83 }
84 
GenerateParentSpanId()85 static uint64_t GenerateParentSpanId()
86 {
87     const uint64_t randomNum = 269;
88     uint64_t hashData[HASH_DATA_LENGTH];
89     struct timeval tv;
90     gettimeofday(&tv, nullptr);
91     srand(tv.tv_sec);
92     hashData[ARRAY_FIRST_INDEX] = tv.tv_usec;
93     hashData[ARRAY_SECOND_INDEX] = randomNum;
94     hashData[ARRAY_THIRD_INDEX] = tv.tv_sec;
95     uint64_t hash = HashFunc(hashData, HASH_DATA_LENGTH * sizeof(uint64_t));
96     return hash;
97 }
98 
99 namespace OHOS {
100 namespace HiviewDFX {
101 using namespace testing::ext;
102 
103 class HiTraceChainCppTest : public testing::Test {
104 public:
105     static void SetUpTestCase();
106     static void TearDownTestCase();
107     void SetUp();
108     void TearDown();
109 };
110 
SetUpTestCase()111 void HiTraceChainCppTest::SetUpTestCase()
112 {}
113 
TearDownTestCase()114 void HiTraceChainCppTest::TearDownTestCase()
115 {}
116 
SetUp()117 void HiTraceChainCppTest::SetUp()
118 {
119     HiTraceChain::ClearId();
120 }
121 
TearDown()122 void HiTraceChainCppTest::TearDown()
123 {}
124 
125 /**
126  * @tc.name: Dfx_HiTraceChainCppTest_IdTest_001
127  * @tc.desc: Get, set and clear trace id
128  * @tc.type: FUNC
129  * @tc.require: AR000CQV9U
130  */
131 HWTEST_F(HiTraceChainCppTest, IdTest_001, TestSize.Level1)
132 {
133     /**
134      * @tc.steps: step1. get and validate trace id.
135      * @tc.expected: step1. trace id is invalid.
136      * @tc.steps: step2. construct trace id with chain id, span id, parent span id
137      *     and flags and set it into context, then get and validate it.
138      * @tc.expected: step2. trace id is valid with same chain id, span id, parent
139      *     span id and flags.
140      * @tc.steps: step3. construct invalid trace id and set into context, then get
141      *     and validate it.
142      * @tc.expected: step3. trace id is the same with step2.
143      * @tc.steps: step4. clear trace id, then get and validate it.
144      * @tc.expected: step4. trace id is invalid.
145      */
146     HiTraceId initId = HiTraceChain::GetId();
147     EXPECT_EQ(0, initId.IsValid());
148     /* set thread id */
149     constexpr uint64_t CHAIN_ID = 0xABCDEF;
150     constexpr uint64_t SPAN_ID = 0x12345;
151     constexpr uint64_t PARENT_SPAN_ID = 0x67890;
152 
153     initId.SetChainId(CHAIN_ID);
154     initId.EnableFlag(HITRACE_FLAG_INCLUDE_ASYNC);
155     initId.EnableFlag(HITRACE_FLAG_DONOT_CREATE_SPAN);
156     initId.SetSpanId(SPAN_ID);
157     initId.SetParentSpanId(PARENT_SPAN_ID);
158 
159     EXPECT_EQ(1, initId.IsValid());
160     EXPECT_EQ(CHAIN_ID, initId.GetChainId());
161     EXPECT_EQ(HITRACE_FLAG_INCLUDE_ASYNC | HITRACE_FLAG_DONOT_CREATE_SPAN, initId.GetFlags());
162     EXPECT_EQ(SPAN_ID, initId.GetSpanId());
163     EXPECT_EQ(PARENT_SPAN_ID, initId.GetParentSpanId());
164 
165     HiTraceChain::SetId(initId);
166 
167     HiTraceId getId = HiTraceChain::GetId();
168     EXPECT_EQ(1, getId.IsValid());
169     EXPECT_EQ(CHAIN_ID, getId.GetChainId());
170     EXPECT_EQ(HITRACE_FLAG_INCLUDE_ASYNC | HITRACE_FLAG_DONOT_CREATE_SPAN, getId.GetFlags());
171     EXPECT_EQ(SPAN_ID, getId.GetSpanId());
172     EXPECT_EQ(PARENT_SPAN_ID, getId.GetParentSpanId());
173 
174     HiTraceId invalidId;
175     HiTraceChain::SetId(invalidId);
176 
177     getId = HiTraceChain::GetId();
178     EXPECT_EQ(1, getId.IsValid());
179     EXPECT_EQ(CHAIN_ID, getId.GetChainId());
180     EXPECT_EQ(HITRACE_FLAG_INCLUDE_ASYNC | HITRACE_FLAG_DONOT_CREATE_SPAN, getId.GetFlags());
181     EXPECT_EQ(SPAN_ID, getId.GetSpanId());
182     EXPECT_EQ(PARENT_SPAN_ID, getId.GetParentSpanId());
183 
184     HiTraceChain::ClearId();
185     HiTraceId clearId = HiTraceChain::GetId();
186     EXPECT_EQ(0, clearId.IsValid());
187 }
188 
189 /**
190  * @tc.name: Dfx_HiTraceChainCppTest_IntfTest_001
191  * @tc.desc: Interconversion between trace id and bytes array.
192  * @tc.type: FUNC
193  * @tc.require: AR000CQV9U
194  */
195 HWTEST_F(HiTraceChainCppTest, IntfTest_001, TestSize.Level1)
196 {
197     /**
198      * @tc.steps: step1. get trace id and validate it.
199      * @tc.expected: step1. trace id is invalid.
200      * @tc.steps: step2. construct trace id and validate it.
201      * @tc.expected: step2. trace id is valid.
202      * @tc.steps: step3. convert trace id to bytes array.
203      * @tc.expected: step3. convert success when array size >= id length.
204      * @tc.steps: step4. convert bytes array to trace id.
205      * @tc.expected: step4. convert success only when array size == id length.
206      * @tc.steps: step5. convert invalid id to bytes array.
207      * @tc.expected: step5. convert fail.
208      * @tc.steps: step6. convert invalid bytes array to id.
209      * @tc.expected: step6. convert fail.
210      */
211     HiTraceId initId = HiTraceChain::GetId();
212     EXPECT_EQ(0, initId.IsValid());
213     constexpr uint64_t CHAIN_ID = 0xABCDEF;
214     constexpr uint64_t SPAN_ID = 0x12345;
215     constexpr uint64_t PARENT_SPAN_ID = 0x67890;
216     constexpr int FLAGS = HITRACE_FLAG_INCLUDE_ASYNC | HITRACE_FLAG_DONOT_CREATE_SPAN;
217 
218     initId.SetChainId(CHAIN_ID);
219     initId.SetFlags(FLAGS);
220     initId.SetSpanId(SPAN_ID);
221     initId.SetParentSpanId(PARENT_SPAN_ID);
222     EXPECT_EQ(1, initId.IsValid());
223     constexpr int ID_LEN = sizeof(HiTraceIdStruct);
224 
225     uint8_t bytes[ID_LEN + 1];
226     int len = initId.ToBytes(bytes, ID_LEN - 1);
227     EXPECT_EQ(0, len);
228     len = initId.ToBytes(bytes, ID_LEN + 1);
229     EXPECT_EQ(ID_LEN, len);
230     len = initId.ToBytes(bytes, ID_LEN);
231     EXPECT_EQ(ID_LEN, len);
232 
233     /* bytes to id */
234     HiTraceId bytesToId = HiTraceId(bytes, ID_LEN - 1);
235     EXPECT_EQ(0, bytesToId.IsValid());
236     bytesToId = HiTraceId(bytes, ID_LEN + 1);
237     EXPECT_EQ(0, bytesToId.IsValid());
238     bytesToId = HiTraceId(bytes, ID_LEN);
239     EXPECT_EQ(1, bytesToId.IsValid());
240     EXPECT_EQ(CHAIN_ID, bytesToId.GetChainId());
241     EXPECT_EQ(HITRACE_FLAG_INCLUDE_ASYNC | HITRACE_FLAG_DONOT_CREATE_SPAN, bytesToId.GetFlags());
242     EXPECT_EQ(SPAN_ID, bytesToId.GetSpanId());
243     EXPECT_EQ(PARENT_SPAN_ID, bytesToId.GetParentSpanId());
244 
245     /* set invalid id */
246     HiTraceId invalidId;
247     EXPECT_EQ(0, invalidId.ToBytes(bytes, ID_LEN));
248     invalidId = HiTraceId(nullptr, ID_LEN);
249     EXPECT_EQ(0, invalidId.IsValid());
250 }
251 
252 /**
253  * @tc.name: Dfx_HiTraceChainCppTest_IntfTest_002
254  * @tc.desc: Start and stop trace.
255  * @tc.type: FUNC
256  * @tc.require: AR000CQV9U
257  */
258 HWTEST_F(HiTraceChainCppTest, IntfTest_002, TestSize.Level1)
259 {
260     /**
261      * @tc.steps: step1. start trace with flags, get trace id and validit it.
262      * @tc.expected: step1. trace id and flags is valid.
263      * @tc.steps: step2. stop trace, get trace id and validit it.
264      * @tc.expected: step2. trace id is invalid.
265      */
266     HiTraceId beginId = HiTraceChain::Begin("test", HITRACE_FLAG_INCLUDE_ASYNC | HITRACE_FLAG_NO_BE_INFO);
267     EXPECT_EQ(1, beginId.IsValid());
268     EXPECT_EQ(1, beginId.IsFlagEnabled(HITRACE_FLAG_INCLUDE_ASYNC));
269     EXPECT_EQ(1, beginId.IsFlagEnabled(HITRACE_FLAG_NO_BE_INFO));
270 
271     HiTraceChain::End(beginId);
272 
273     HiTraceId endId = HiTraceChain::GetId();
274     EXPECT_EQ(0, endId.IsValid());
275 }
276 
277 /**
278  * @tc.name: Dfx_HiTraceChainCppTest_IntfTest_003
279  * @tc.desc: Start and stop trace with reentered.
280  * @tc.type: FUNC
281  * @tc.require: AR000CQV9U
282  */
283 HWTEST_F(HiTraceChainCppTest, IntfTest_003, TestSize.Level1)
284 {
285     /**
286      * @tc.steps: step1. start trace twice and get 2nd trace id.
287      * @tc.expected: step1. 2nd trace is invalid.
288      * @tc.steps: step2. get trace id and check.
289      * @tc.expected: step2. trace id is valid and same with 1st id.
290      * @tc.steps: step3. set chain id with wrong id and get trace id.
291      * @tc.expected: step3. trace id is valid and same with 1st id.
292      * @tc.steps: step4. stop trace twice and get trace id.
293      * @tc.expected: step4. trace id is invalid.
294      */
295     /* begin */
296     HiTraceId beginId = HiTraceChain::Begin("begin", HITRACE_FLAG_INCLUDE_ASYNC);
297     /* reenter begin */
298     HiTraceId reBeginId = HiTraceChain::Begin("reenter begin", HITRACE_FLAG_TP_INFO);
299     EXPECT_EQ(0, reBeginId.IsValid());
300     EXPECT_NE(reBeginId.GetChainId(), beginId.GetChainId());
301     EXPECT_EQ(0, reBeginId.IsFlagEnabled(HITRACE_FLAG_INCLUDE_ASYNC));
302     EXPECT_EQ(0, reBeginId.IsFlagEnabled(HITRACE_FLAG_TP_INFO));
303 
304     /* reenter end */
305     HiTraceChain::End(reBeginId);
306 
307     HiTraceId endId = HiTraceChain::GetId();
308     EXPECT_EQ(1, endId.IsValid());
309     EXPECT_EQ(endId.GetChainId(), beginId.GetChainId());
310     EXPECT_EQ(1, endId.IsFlagEnabled(HITRACE_FLAG_INCLUDE_ASYNC));
311     EXPECT_EQ(0, endId.IsFlagEnabled(HITRACE_FLAG_TP_INFO));
312 
313     /* end with wrong chainId */
314     HiTraceId wrongBeginId = beginId;
315     wrongBeginId.SetChainId(beginId.GetChainId() + 1);
316     HiTraceChain::End(wrongBeginId);
317 
318     HiTraceId wrongEndId = HiTraceChain::GetId();
319     EXPECT_EQ(1, wrongEndId.IsValid());
320     EXPECT_EQ(wrongEndId.GetChainId(), beginId.GetChainId());
321     EXPECT_EQ(1, wrongEndId.IsFlagEnabled(HITRACE_FLAG_INCLUDE_ASYNC));
322 
323     /* end */
324     HiTraceChain::End(beginId);
325 
326     HiTraceId reEndId = HiTraceChain::GetId();
327     EXPECT_EQ(0, reEndId.IsValid());
328 
329     /* end with invalid thread id */
330     HiTraceChain::End(beginId);
331 
332     HiTraceId endInvalidId = HiTraceChain::GetId();
333     EXPECT_EQ(0, endInvalidId.IsValid());
334 }
335 
336 /**
337  * @tc.name: Dfx_HiTraceChainCppTest_SpanTest_001
338  * @tc.desc: Create child and grand child span.
339  * @tc.type: FUNC
340  * @tc.require: AR000CQV9U
341  */
342 HWTEST_F(HiTraceChainCppTest, SpanTest_001, TestSize.Level1)
343 {
344     /**
345      * @tc.steps: step1. start trace without HITRACE_FLAG_DONOT_CREATE_SPAN,
346      *     get and check flags.
347      * @tc.expected: step1. flags is same with set and span id is 0.
348      * @tc.steps: step2. create child id.
349      * @tc.expected: step2. child id has same span id with parent.
350      * @tc.steps: step3. set child id into context.
351      * @tc.steps: step4. create grand child id.
352      * @tc.expected: step4. grand child id has same span id with parent and child.
353      */
354     /* begin with span flag */
355     HiTraceId id = HiTraceChain::Begin("test", 0);
356     EXPECT_EQ(0, id.GetFlags());
357     EXPECT_EQ(0UL, id.GetSpanId());
358     EXPECT_EQ(0UL, id.GetParentSpanId());
359 
360     /* create child span */
361     HiTraceId childId = HiTraceChain::CreateSpan();
362     EXPECT_EQ(1, childId.IsValid());
363     EXPECT_EQ(childId.GetFlags(), id.GetFlags());
364     EXPECT_EQ(childId.GetChainId(), id.GetChainId());
365     EXPECT_EQ(childId.GetParentSpanId(), id.GetSpanId());
366 
367     /* set child id to thread id */
368     HiTraceChain::SetId(childId);
369 
370     /* continue to create child span */
371     HiTraceId grandChildId = HiTraceChain::CreateSpan();
372     EXPECT_EQ(1, grandChildId.IsValid());
373     EXPECT_EQ(grandChildId.GetFlags(), id.GetFlags());
374     EXPECT_EQ(grandChildId.GetChainId(), id.GetChainId());
375     EXPECT_EQ(grandChildId.GetParentSpanId(), childId.GetSpanId());
376 
377     /* end */
378     HiTraceChain::End(id);
379 }
380 
381 /**
382  * @tc.name: Dfx_HiTraceChainCppTest_SpanTest_002
383  * @tc.desc: Start and stop trace with reentered.
384  * @tc.type: FUNC
385  * @tc.require: AR000CQV9U
386  */
387 HWTEST_F(HiTraceChainCppTest, SpanTest_002, TestSize.Level1)
388 {
389     /**
390      * @tc.steps: step1. start trace with HITRACE_FLAG_DONOT_CREATE_SPAN,
391      *     get and check flags.
392      * @tc.expected: step1. HITRACE_FLAG_DONOT_CREATE_SPAN is enabled.
393      * @tc.steps: step2. create child id.
394      * @tc.expected: step2. child id is same with parent id.
395      */
396     /* begin with "donot create span" flag */
397     HiTraceId id = HiTraceChain::Begin("test", HITRACE_FLAG_DONOT_CREATE_SPAN);
398     EXPECT_EQ(1, id.IsFlagEnabled(HITRACE_FLAG_DONOT_CREATE_SPAN));
399 
400     /* create child span */
401     HiTraceId childId = HiTraceChain::CreateSpan();
402     EXPECT_EQ(1, childId.IsValid());
403     EXPECT_EQ(childId.GetFlags(), id.GetFlags());
404     EXPECT_EQ(childId.GetChainId(), id.GetChainId());
405     EXPECT_EQ(childId.GetSpanId(), id.GetSpanId());
406     EXPECT_EQ(childId.GetParentSpanId(), id.GetParentSpanId());
407 
408     /* end */
409     HiTraceChain::End(id);
410 }
411 
412 /**
413  * @tc.name: Dfx_HiTraceChainCppTest_TracepointTest_001
414  * @tc.desc: Start trace with HITRACE_FLAG_TP_INFO flag.
415  * @tc.type: FUNC
416  * @tc.require: AR000CQVA3
417  */
418 HWTEST_F(HiTraceChainCppTest, TracepointTest_001, TestSize.Level1)
419 {
420     /**
421      * @tc.steps: step1. start trace with HITRACE_FLAG_TP_INFO,
422      *     get and check flags.
423      * @tc.expected: step1. HITRACE_FLAG_TP_INFO is enabled.
424      * @tc.steps: step2. add trace point info with id and check logs.
425      * @tc.expected: step2. trace point can be found in logs.
426      * @tc.steps: step3. add trace point info with null and check logs.
427      * @tc.expected: step3. trace point cannot be found in logs.
428      */
429     /* begin with tp flag */
430     HiTraceId invalidId;
431     HiTraceId id = HiTraceChain::Begin("test tp flag", HITRACE_FLAG_TP_INFO);
432     EXPECT_EQ(1, id.IsFlagEnabled(HITRACE_FLAG_TP_INFO));
433     HiTraceChain::Tracepoint(HITRACE_TP_CS, id, "client send msg content %d", 12);
434     HiTraceChain::Tracepoint(HITRACE_TP_CS, invalidId, "client send msg content %d", 12);
435     HiTraceChain::End(id);
436 }
437 
438 /**
439  * @tc.name: Dfx_HiTraceChainCppTest_TracepointTest_002
440  * @tc.desc: Start trace without HITRACE_FLAG_TP_INFO flag.
441  * @tc.type: FUNC
442  * @tc.require: AR000CQVA3
443  */
444 HWTEST_F(HiTraceChainCppTest, TracepointTest_002, TestSize.Level1)
445 {
446     /**
447      * @tc.steps: step1. start trace without HITRACE_FLAG_TP_INFO flag.
448      *     get and check flags.
449      * @tc.expected: step1. HITRACE_FLAG_TP_INFO is not enabled.
450      * @tc.steps: step2. add trace point info with id and check logs.
451      * @tc.expected: step2. trace point cannot be found in logs.
452      */
453     /* begin with tp flag */
454     HiTraceId id = HiTraceChain::Begin("test no tp flag", HITRACE_FLAG_INCLUDE_ASYNC);
455     EXPECT_EQ(0, id.IsFlagEnabled(HITRACE_FLAG_TP_INFO));
456     HiTraceChain::Tracepoint(HITRACE_TP_CS, id, "client send msg content %d", 12);
457 
458     HiTraceChain::End(id);
459 }
460 
461 /**
462  * @tc.name: Dfx_HiTraceChainCppTest_TracepointTest_003
463  * @tc.desc: Start trace with HITRACE_FLAG_D2D_TP_INFO flag.
464  * @tc.type: FUNC
465  * @tc.require: AR000CQVA3
466  */
467 HWTEST_F(HiTraceChainCppTest, TracepointTest_003, TestSize.Level1)
468 {
469     /**
470      * @tc.steps: step1. start trace with HITRACE_FLAG_D2D_TP_INFO,
471      *     get and check flags.
472      * @tc.expected: step1. HITRACE_FLAG_D2D_TP_INFO is enabled.
473      * @tc.steps: step2. add D2D trace point info with id and check logs.
474      * @tc.expected: step2. trace point can be found in logs.
475      * @tc.steps: step2. add D2D trace point info with null and check logs.
476      * @tc.expected: step2. trace point cannot be found in logs.
477      * @tc.steps: step3. add trace point info with id and check logs.
478      * @tc.expected: step3. trace point cannot be found in logs.
479      */
480     HiTraceId id = HiTraceChain::Begin("test D2D tp flag", HITRACE_FLAG_D2D_TP_INFO);
481     EXPECT_EQ(1, id.IsFlagEnabled(HITRACE_FLAG_D2D_TP_INFO));
482     HiTraceChain::Tracepoint(HITRACE_CM_DEVICE, HITRACE_TP_CS, id, "client send msg content %d", 12);
483     HiTraceChain::Tracepoint(HITRACE_CM_PROCESS, HITRACE_TP_CS, id, "cannot be found %d", 22);
484     HiTraceChain::Tracepoint(HITRACE_CM_THREAD, HITRACE_TP_CS, id, "cannot be found %d", 32);
485     HiTraceChain::Tracepoint(HITRACE_CM_DEFAULT, HITRACE_TP_CS, id, "cannot be found %d", 42);
486 
487     HiTraceId invalidId;
488     HiTraceChain::Tracepoint(HITRACE_CM_DEVICE, HITRACE_TP_CS, invalidId, "cannot be found %d", 13);
489 
490     HiTraceChain::Tracepoint(HITRACE_TP_CS, id, "cannot be found %d", 14);
491 
492     HiTraceChain::End(id);
493 }
494 
495 /**
496  * @tc.name: Dfx_HiTraceChainCppTest_TracepointTest_004
497  * @tc.desc: Start trace without HITRACE_FLAG_D2D_TP_INFO flag.
498  * @tc.type: FUNC
499  * @tc.require: AR000CQVA3
500  */
501 HWTEST_F(HiTraceChainCppTest, TracepointTest_004, TestSize.Level1)
502 {
503     /**
504      * @tc.steps: step1. start trace without HITRACE_FLAG_D2D_TP_INFO flag.
505      *     get and check flags.
506      * @tc.expected: step1. HITRACE_FLAG_D2D_TP_INFO is not enabled.
507      * @tc.steps: step2. add D2D trace point info with id and check logs.
508      * @tc.expected: step2. trace point cannot be found in logs.
509      */
510     HiTraceId id = HiTraceChain::Begin("test no D2D tp flag", HITRACE_FLAG_INCLUDE_ASYNC);
511     EXPECT_EQ(0, id.IsFlagEnabled(HITRACE_FLAG_D2D_TP_INFO));
512     HiTraceChain::Tracepoint(HITRACE_CM_DEVICE, HITRACE_TP_CS, id, "cannot be found %d", 12);
513     HiTraceChain::Tracepoint(HITRACE_CM_PROCESS, HITRACE_TP_CS, id, "cannot be found %d", 22);
514     HiTraceChain::Tracepoint(HITRACE_CM_THREAD, HITRACE_TP_CS, id, "cannot be found %d", 32);
515     HiTraceChain::Tracepoint(HITRACE_CM_DEFAULT, HITRACE_TP_CS, id, "cannot be found %d", 42);
516 
517     HiTraceChain::End(id);
518 }
519 
520 /**
521  * @tc.name: Dfx_HiTraceChainCppTest_TracepointTest_005
522  * @tc.desc: Start trace with HITRACE_FLAG_D2D_TP_INFO and HITRACE_FLAG_TP_INFO flag.
523  * @tc.type: FUNC
524  * @tc.require: AR000CQVA3
525  */
526 HWTEST_F(HiTraceChainCppTest, TracepointTest_005, TestSize.Level1)
527 {
528     /**
529      * @tc.steps: step1. start trace with HITRACE_FLAG_D2D_TP_INFO | HITRACE_FLAG_TP_INFO,
530      *     get and check flags.
531      * @tc.expected: step1. HITRACE_FLAG_D2D_TP_INFO is enabled.
532      * @tc.expected: step1. HITRACE_FLAG_TP_INFO is enabled.
533      * @tc.steps: step2. add D2D trace point info with id and check logs.
534      * @tc.expected: step2. trace point can be found in logs.
535      * @tc.steps: step3. add trace point info with id and check logs.
536      * @tc.expected: step3. trace point can be found in logs.
537      */
538     HiTraceId id = HiTraceChain::Begin("test D2D | TP tp flag", HITRACE_FLAG_D2D_TP_INFO | HITRACE_FLAG_TP_INFO);
539     EXPECT_EQ(1, id.IsFlagEnabled(HITRACE_FLAG_D2D_TP_INFO));
540     EXPECT_EQ(1, id.IsFlagEnabled(HITRACE_FLAG_TP_INFO));
541     HiTraceChain::Tracepoint(HITRACE_CM_DEVICE, HITRACE_TP_CS, id, "client send msg content %d", 12);
542     HiTraceChain::Tracepoint(HITRACE_CM_PROCESS, HITRACE_TP_CS, id, "client send msg content %d", 22);
543     HiTraceChain::Tracepoint(HITRACE_CM_THREAD, HITRACE_TP_CS, id, "client send msg content %d", 32);
544     HiTraceChain::Tracepoint(HITRACE_CM_DEFAULT, HITRACE_TP_CS, id, "client send msg content %d", 42);
545 
546     HiTraceChain::Tracepoint(HITRACE_TP_CS, id, "client send msg content %d", 13);
547 
548     HiTraceChain::End(id);
549 }
550 
551 /**
552  * @tc.name: Dfx_HiTraceChainCppTest_TracepointTest_006
553  * @tc.desc: Start trace without HITRACE_FLAG_D2D_TP_INFO, but with HITRACE_FLAG_TP_INFO flag.
554  * @tc.type: FUNC
555  * @tc.require: AR000CQVA3
556  */
557 HWTEST_F(HiTraceChainCppTest, TracepointTest_006, TestSize.Level1)
558 {
559     /**
560      * @tc.steps: step1. start trace with HITRACE_FLAG_TP_INFO flag.
561      *     get and check flags.
562      * @tc.expected: step1. HITRACE_FLAG_D2D_TP_INFO is not enabled.
563      * * @tc.expected: step1. HITRACE_FLAG_TP_INFO is enabled.
564      * @tc.steps: step2. add D2D trace point info with id and check logs.
565      * @tc.expected: step2. trace point can be found in logs.
566      * @tc.steps: step2. add trace point info with id and check logs.
567      * @tc.expected: step2. trace point can be found in logs.
568      */
569     HiTraceId id = HiTraceChain::Begin("test no D2D, but tp flag", HITRACE_FLAG_TP_INFO);
570     EXPECT_EQ(0, id.IsFlagEnabled(HITRACE_FLAG_D2D_TP_INFO));
571     EXPECT_EQ(1, id.IsFlagEnabled(HITRACE_FLAG_TP_INFO));
572     HiTraceChain::Tracepoint(HITRACE_CM_DEVICE, HITRACE_TP_CS, id, "client send msg content %d", 12);
573     HiTraceChain::Tracepoint(HITRACE_CM_PROCESS, HITRACE_TP_CS, id, "client send msg content %d", 22);
574     HiTraceChain::Tracepoint(HITRACE_CM_THREAD, HITRACE_TP_CS, id, "client send msg content %d", 32);
575     HiTraceChain::Tracepoint(HITRACE_CM_DEFAULT, HITRACE_TP_CS, id, "client send msg content %d", 42);
576 
577     HiTraceChain::Tracepoint(HITRACE_TP_CS, id, "client send msg content %d", 13);
578 
579     HiTraceChain::End(id);
580 }
581 
582 /**
583  * @tc.name: Dfx_HiTraceChainCppTest_TracepointTest_007
584  * @tc.desc: Start trace without HITRACE_FLAG_D2D_TP_INFO, but with HITRACE_FLAG_TP_INFO flag.
585  * @tc.type: FUNC
586  * @tc.require: AR000CQVA3
587  */
588 HWTEST_F(HiTraceChainCppTest, TracepointTest_007, TestSize.Level1)
589 {
590     /**
591      * @tc.steps: step1. start trace with HITRACE_FLAG_TP_INFO flag.
592      *     get and check flags.
593      * @tc.expected: step1. HITRACE_FLAG_D2D_TP_INFO is not enabled.
594      * * @tc.expected: step1. HITRACE_FLAG_TP_INFO is enabled.
595      * @tc.steps: step2. add D2D trace point info with id and check logs.
596      * @tc.expected: step2. trace point can be found in logs.
597      * @tc.steps: step2. add trace point info with id and check logs.
598      * @tc.expected: step2. trace point can be found in logs.
599      */
600     HiTraceId id = HiTraceChain::Begin("test no D2D, but tp flag", HITRACE_FLAG_TP_INFO);
601     EXPECT_EQ(0, id.IsFlagEnabled(HITRACE_FLAG_D2D_TP_INFO));
602     EXPECT_EQ(1, id.IsFlagEnabled(HITRACE_FLAG_TP_INFO));
603     HiTraceChain::Tracepoint(HITRACE_TP_CS, id, "client send msg content %d", 12);
604     HiTraceChain::Tracepoint(HITRACE_TP_CS, id, "client send msg content %d", 22);
605     HiTraceChain::Tracepoint(HITRACE_TP_CS, id, "client send msg content %d", 32);
606     HiTraceChain::Tracepoint(HITRACE_TP_CS, id, "client send msg content %d", 42);
607 
608     HiTraceChain::Tracepoint(HITRACE_TP_CS, id, "client send msg content %d", 13);
609 
610     HiTraceChain::End(id);
611 }
612 
613 /**
614  * @tc.name: Dfx_HiTraceChainCppTest_SyncAsyncTest_001
615  * @tc.desc: Start trace with SYNC or ASYNC.
616  * @tc.type: FUNC
617  * @tc.require: AR000CQ0G7
618  */
619 HWTEST_F(HiTraceChainCppTest, SyncAsyncTest_001, TestSize.Level1)
620 {
621     /**
622      * @tc.steps: step1. start trace without HITRACE_FLAG_INCLUDE_ASYNC flag.
623      *    get and check flags.
624      * @tc.expected: step1. HITRACE_FLAG_INCLUDE_ASYNC is not enabled.
625      * @tc.steps: step2. start trace with HITRACE_FLAG_INCLUDE_ASYNC flag.
626      *    get and check flags.
627      * @tc.expected: step2. HITRACE_FLAG_INCLUDE_ASYNC is enabled.
628      */
629     /* begin with sync flag */
630     HiTraceId syncId = HiTraceChain::Begin("test sync only", HITRACE_FLAG_TP_INFO);
631     EXPECT_EQ(0, syncId.IsFlagEnabled(HITRACE_FLAG_INCLUDE_ASYNC));
632     HiTraceChain::Tracepoint(HITRACE_TP_CS, syncId, "client send msg: %s", "sync");
633         HiTraceChain::End(syncId);
634     /* begin with async flag */
635     HiTraceId asyncId = HiTraceChain::Begin("test sync+async", HITRACE_FLAG_INCLUDE_ASYNC | HITRACE_FLAG_TP_INFO);
636     EXPECT_EQ(1, asyncId.IsFlagEnabled(HITRACE_FLAG_INCLUDE_ASYNC));
637     HiTraceChain::Tracepoint(HITRACE_TP_CS, asyncId, "client send msg: %s", "async");
638 
639     HiTraceChain::End(asyncId);
640 }
641 
642 /**
643  * @tc.name: Dfx_HiTraceChainCppTest_InvalidParamTest_001
644  * @tc.desc: Start trace with SYNC or ASYNC.
645  * @tc.type: FUNC
646  * @tc.require: AR000CQV9U
647  */
648 HWTEST_F(HiTraceChainCppTest, InvalidParamTest_001, TestSize.Level1)
649 {
650     /**
651      * @tc.steps: step1. start trace with invalid flag and validate trace id.
652      * @tc.expected: step1. trace id is invalid.
653      * @tc.steps: step2. start trace with invalid name and validate trace id.
654      * @tc.expected: step2. trace id is valid.
655      */
656     /* begin with invalid flag */
657     HiTraceId invalidFlagId = HiTraceChain::Begin("invalid param", HITRACE_FLAG_MAX+1);
658     EXPECT_EQ(0, invalidFlagId.IsValid());
659     invalidFlagId = HiTraceChain::Begin("invalid param", -1);
660     EXPECT_EQ(0, invalidFlagId.IsValid());
661     HiTraceChain::End(invalidFlagId);
662 
663     /* begin with invalid name */
664     HiTraceId invalidNameId = HiTraceChain::Begin("", HITRACE_FLAG_TP_INFO);
665     EXPECT_EQ(1, invalidNameId.IsValid());
666     HiTraceChain::End(invalidNameId);
667 }
668 
669 /**
670  * @tc.name: Dfx_HiTraceChainCppTest_HiTraceTest_001
671  * @tc.desc: Start trace with SYNC or ASYNC.
672  * @tc.type: FUNC
673  */
674 HWTEST_F(HiTraceChainCppTest, HiTraceTest_001, TestSize.Level1)
675 {
676     /**
677      * @tc.steps: step1. start trace with invalid flag and validate trace id.
678      * @tc.expected: step1. trace id is invalid.
679      * @tc.steps: step2. start trace with invalid name and validate trace id.
680      * @tc.expected: step2. trace id is valid.
681      */
682     /* begin with invalid flag */
683     HiTraceId invalidFlagId = HiTraceChain::Begin("invalid param", HITRACE_FLAG_MAX+1);
684     EXPECT_EQ(0, invalidFlagId.IsValid());
685     invalidFlagId = HiTraceChain::Begin("invalid param", -1);
686     EXPECT_EQ(0, invalidFlagId.IsValid());
687     HiTraceChain::End(invalidFlagId);
688 
689     /* begin with invalid name */
690     HiTraceId invalidNameId = HiTraceChain::Begin("", HITRACE_FLAG_TP_INFO);
691     EXPECT_EQ(1, invalidNameId.IsValid());
692     HiTraceChain::End(invalidNameId);
693 
694     /* Function interface overlay */
695     int taskId = 123;
696     int count = 1;
697     HiTraceStartTrace(HITRACE_TAG_OHOS, "HiTraceTest001");
698     HiTraceFinishTrace(HITRACE_TAG_OHOS);
699     HiTraceStartAsyncTrace(HITRACE_TAG_OHOS, "HiTraceTest001", taskId);
700     HiTraceFinishAsyncTrace(HITRACE_TAG_OHOS, "HiTraceTest001", taskId);
701     HiTraceCountTrace(HITRACE_TAG_OHOS, "HiTraceTest001", count);
702 }
703 
704 /**
705  * @tc.name: Dfx_HiTraceChainCppTest_HiTraceTest_002
706  * @tc.desc: Create child and grand child span.
707  * @tc.type: FUNC
708  */
709 HWTEST_F(HiTraceChainCppTest, HiTraceTest_002, TestSize.Level1)
710 {
711     /* begin with span flag */
712     HiTraceId id = HiTraceChain::Begin("test", 0);
713     EXPECT_EQ(0, id.GetFlags());
714     EXPECT_EQ(0UL, id.GetSpanId());
715     EXPECT_EQ(0UL, id.GetParentSpanId());
716 
717     /* create child span */
718     HiTraceId childId = HiTraceChain::CreateSpan();
719     EXPECT_EQ(1, childId.IsValid());
720     EXPECT_EQ(childId.GetFlags(), id.GetFlags());
721     EXPECT_EQ(childId.GetChainId(), id.GetChainId());
722     EXPECT_EQ(childId.GetParentSpanId(), id.GetSpanId());
723 
724     /* set child id to thread id */
725     HiTraceChain::SetId(childId);
726 
727     /* Restore child*/
728     HiTraceChain::Restore(childId);
729 
730     /* save child and set child id to thread id */
731     HiTraceChain::SaveAndSet(childId);
732 
733     /* continue to create child span */
734     HiTraceId grandChildId = HiTraceChain::CreateSpan();
735     EXPECT_EQ(1, grandChildId.IsValid());
736     EXPECT_EQ(grandChildId.GetFlags(), id.GetFlags());
737     EXPECT_EQ(grandChildId.GetChainId(), id.GetChainId());
738     EXPECT_EQ(grandChildId.GetParentSpanId(), childId.GetSpanId());
739 
740     /* end */
741     HiTraceChain::End(id);
742 }
743 
744 /**
745  * @tc.name: Dfx_HiTraceChainCppTest_RestoreTest_001
746  * @tc.desc: Start normal trace.
747  * @tc.type: FUNC
748  */
749 HWTEST_F(HiTraceChainCppTest, RestoreTest_001, TestSize.Level1)
750 {
751     /**
752      * @tc.steps: step1. start trace without any flag.
753      * @tc.expected: step1. no flag is enabled.
754      * @tc.steps: step2. generate a temporary trace id.
755      * @tc.expected: step2. a trace id is generated.
756      * @tc.steps: step3. set new trace id and save old trace id.
757      * @tc.expected: step3. new trace id get into TLS.
758      * @tc.steps: step4. store old trace id.
759      * @tc.expected: step4. old trace id get into TLS.
760      * @tc.steps: step5. end trace.
761      * @tc.expected: step5. trace terminate.
762      */
763 
764     // begin trace
765     HiTraceId id = HiTraceChain::Begin("RestoreTest_001", HITRACE_FLAG_TP_INFO);
766 
767     // generate new trace id
768     HiTraceIdStruct tempId{0};
769     HiTraceChainInitId(&tempId);
770     tempId.valid=HITRACE_ID_VALID;
771     HiTraceId newId(tempId);
772     uint64_t chainId = GenerateChainId();
773     uint64_t spanId = GenerateSpanId();
774     uint64_t parentSpanId = GenerateParentSpanId();
775     newId.SetChainId(chainId);
776     newId.SetSpanId(spanId);
777     newId.SetParentSpanId(parentSpanId);
778 
779     // set new id and save old id
780     HiTraceId oldId = HiTraceChain::SaveAndSet(newId);
781     HiTraceId currentId = HiTraceChain::GetId();
782     HiTraceChain::Tracepoint(
783             HITRACE_CM_DEVICE, HITRACE_TP_CS, currentId, "client send msg %d", DEVICE_CLIENT_SEND);
784     HiTraceChain::Tracepoint(
785             HITRACE_CM_PROCESS, HITRACE_TP_CS, currentId, "client send msg %d", PROCESS_CLIENT_SEND);
786     HiTraceChain::Tracepoint(
787             HITRACE_CM_THREAD, HITRACE_TP_CS, currentId, "client send msg %d", THREAD_CLIENT_SEND);
788     HiTraceChain::Tracepoint(
789             HITRACE_CM_DEFAULT, HITRACE_TP_CS, currentId, "client send msg %d", DEFAULT_CLIENT_SEND);
790 
791     // restore old id
792     HiTraceChain::Restore(oldId);
793     HiTraceId currentId2 = HiTraceChain::GetId();
794     EXPECT_EQ(id.GetChainId(), currentId2.GetChainId());
795     EXPECT_EQ(id.GetSpanId(), currentId2.GetSpanId());
796     EXPECT_EQ(id.GetParentSpanId(), currentId2.GetParentSpanId());
797     HiTraceChain::Tracepoint(
798             HITRACE_CM_DEVICE, HITRACE_TP_CS, currentId2, "client send msg %d", DEVICE_CLIENT_SEND);
799     HiTraceChain::Tracepoint(
800             HITRACE_CM_PROCESS, HITRACE_TP_CS, currentId2, "client send msg %d", PROCESS_CLIENT_SEND);
801     HiTraceChain::Tracepoint(
802             HITRACE_CM_THREAD, HITRACE_TP_CS, currentId2, "client send msg %d", THREAD_CLIENT_SEND);
803     HiTraceChain::Tracepoint(
804             HITRACE_CM_DEFAULT, HITRACE_TP_CS, currentId2, "client send msg %d", DEFAULT_CLIENT_SEND);
805 
806     // end trace
807     HiTraceChain::End(id);
808 }
809 
810 /**
811  * @tc.name: Dfx_HiTraceChainCppTest_RestoreTest_002
812  * @tc.desc: Start normal with HITRACE_FLAG_INCLUDE_ASYNC flag.
813  * @tc.type: FUNC
814  */
815 HWTEST_F(HiTraceChainCppTest, RestoreTest_002, TestSize.Level1)
816 {
817     /**
818      * @tc.steps: step1. start trace with flag HITRACE_FLAG_INCLUDE_ASYNC.
819      * @tc.expected: step1. HITRACE_FLAG_INCLUDE_ASYNC flag is enabled.
820      * @tc.steps: step2. generate a temporary trace id.
821      * @tc.expected: step2. a trace id is generated.
822      * @tc.steps: step3. set new trace id and save old trace id.
823      * @tc.expected: step3. new trace id get into TLS.
824      * @tc.steps: step4. store old trace id.
825      * @tc.expected: step4. old trace id get into TLS.
826      * @tc.steps: step5. end trace.
827      * @tc.expected: step5. trace terminate.
828      */
829 
830     // begin trace
831     HiTraceId id = HiTraceChain::Begin("RestoreTest_002", HITRACE_FLAG_TP_INFO | HITRACE_FLAG_INCLUDE_ASYNC);
832 
833     // generate new trace id
834     HiTraceIdStruct tempId{0};
835     HiTraceChainInitId(&tempId);
836     tempId.valid=HITRACE_ID_VALID;
837     HiTraceId newId(tempId);
838     uint64_t chainId = GenerateChainId();
839     uint64_t spanId = GenerateSpanId();
840     uint64_t parentSpanId = GenerateParentSpanId();
841     newId.SetChainId(chainId);
842     newId.SetSpanId(spanId);
843     newId.SetParentSpanId(parentSpanId);
844 
845     // set new id and save old id
846     HiTraceId oldId = HiTraceChain::SaveAndSet(newId);
847     HiTraceId currentId = HiTraceChain::GetId();
848     HiTraceChain::Tracepoint(
849             HITRACE_CM_DEVICE, HITRACE_TP_CS, currentId, "client send msg %d", DEVICE_CLIENT_SEND);
850     HiTraceChain::Tracepoint(
851             HITRACE_CM_PROCESS, HITRACE_TP_CS, currentId, "client send msg %d", PROCESS_CLIENT_SEND);
852     HiTraceChain::Tracepoint(
853             HITRACE_CM_THREAD, HITRACE_TP_CS, currentId, "client send msg %d", THREAD_CLIENT_SEND);
854     HiTraceChain::Tracepoint(
855             HITRACE_CM_DEFAULT, HITRACE_TP_CS, currentId, "client send msg %d", DEFAULT_CLIENT_SEND);
856 
857     // restore old id
858     HiTraceChain::Restore(oldId);
859     HiTraceId currentId2 = HiTraceChain::GetId();
860     ASSERT_TRUE(currentId2.IsFlagEnabled(HITRACE_FLAG_INCLUDE_ASYNC));
861     HiTraceChain::Tracepoint(
862             HITRACE_CM_DEVICE, HITRACE_TP_CS, currentId2, "client send msg %d", DEVICE_CLIENT_SEND);
863     HiTraceChain::Tracepoint(
864             HITRACE_CM_PROCESS, HITRACE_TP_CS, currentId2, "client send msg %d", PROCESS_CLIENT_SEND);
865     HiTraceChain::Tracepoint(
866             HITRACE_CM_THREAD, HITRACE_TP_CS, currentId2, "client send msg %d", THREAD_CLIENT_SEND);
867     HiTraceChain::Tracepoint(
868             HITRACE_CM_DEFAULT, HITRACE_TP_CS, currentId2, "client send msg %d", DEFAULT_CLIENT_SEND);
869 
870     // end trace
871     HiTraceChain::End(id);
872 }
873 
874 /**
875  * @tc.name: Dfx_HiTraceChainCppTest_RestoreTest_003
876  * @tc.desc: Start normal trace and create span.
877  * @tc.type: FUNC
878  */
879 HWTEST_F(HiTraceChainCppTest, RestoreTest_003, TestSize.Level1)
880 {
881     /**
882      * @tc.steps: step1. start trace without any flag, then create span.
883      * @tc.expected: step1. no flag is enabled.
884      * @tc.steps: step2. generate a temporary trace id.
885      * @tc.expected: step2. a trace id is generated.
886      * @tc.steps: step3. set new trace id and save old trace id.
887      * @tc.expected: step3. new trace id get into TLS.
888      * @tc.steps: step4. store old trace id.
889      * @tc.expected: step4. old trace id get into TLS.
890      * @tc.steps: step5. end trace.
891      * @tc.expected: step5. trace terminate.
892      */
893 
894     // begin trace
895     HiTraceId id = HiTraceChain::Begin("RestoreTest_003", HITRACE_FLAG_TP_INFO);
896     HiTraceChain::CreateSpan();
897 
898     // generate new trace id
899     HiTraceIdStruct tempId{0};
900     HiTraceChainInitId(&tempId);
901     tempId.valid=HITRACE_ID_VALID;
902     HiTraceId newId(tempId);
903     uint64_t chainId = GenerateChainId();
904     uint64_t spanId = GenerateSpanId();
905     uint64_t parentSpanId = GenerateParentSpanId();
906     newId.SetChainId(chainId);
907     newId.SetSpanId(spanId);
908     newId.SetParentSpanId(parentSpanId);
909 
910     // set new id and save old id
911     HiTraceId oldId = HiTraceChain::SaveAndSet(newId);
912     HiTraceChain::CreateSpan();
913     HiTraceId currentId = HiTraceChain::GetId();
914     HiTraceChain::Tracepoint(
915             HITRACE_CM_DEVICE, HITRACE_TP_CS, currentId, "client send msg %d", DEVICE_CLIENT_SEND);
916     HiTraceChain::Tracepoint(
917             HITRACE_CM_PROCESS, HITRACE_TP_CS, currentId, "client send msg %d", PROCESS_CLIENT_SEND);
918     HiTraceChain::Tracepoint(
919             HITRACE_CM_THREAD, HITRACE_TP_CS, currentId, "client send msg %d", THREAD_CLIENT_SEND);
920     HiTraceChain::Tracepoint(
921             HITRACE_CM_DEFAULT, HITRACE_TP_CS, currentId, "client send msg %d", DEFAULT_CLIENT_SEND);
922 
923     // restore old id
924     HiTraceChain::Restore(oldId);
925     HiTraceId currentId2 = HiTraceChain::GetId();
926     EXPECT_EQ(id.GetChainId(), currentId2.GetChainId());
927     EXPECT_EQ(id.GetSpanId(), currentId2.GetSpanId());
928     EXPECT_EQ(id.GetParentSpanId(), currentId2.GetParentSpanId());
929     HiTraceChain::Tracepoint(
930             HITRACE_CM_DEVICE, HITRACE_TP_CS, currentId2, "client send msg %d", DEVICE_CLIENT_SEND);
931     HiTraceChain::Tracepoint(
932             HITRACE_CM_PROCESS, HITRACE_TP_CS, currentId2, "client send msg %d", PROCESS_CLIENT_SEND);
933     HiTraceChain::Tracepoint(
934             HITRACE_CM_THREAD, HITRACE_TP_CS, currentId2, "client send msg %d", THREAD_CLIENT_SEND);
935     HiTraceChain::Tracepoint(
936             HITRACE_CM_DEFAULT, HITRACE_TP_CS, currentId2, "client send msg %d", DEFAULT_CLIENT_SEND);
937 
938     // end trace
939     HiTraceChain::End(id);
940 }
941 
942 /**
943  * @tc.name: Dfx_HiTraceChainCppTest_RestoreTest_004
944  * @tc.desc: Start normal trace.
945  * @tc.type: FUNC
946  */
947 HWTEST_F(HiTraceChainCppTest, RestoreTest_004, TestSize.Level1)
948 {
949     /**
950      * @tc.steps: step1. start trace without any flag.
951      * @tc.expected: step1. no flag is enabled.
952      * @tc.steps: step2. generate a temporary trace id with HITRACE_ID_INVALID flag.
953      * @tc.expected: step2. a trace id is generated.
954      * @tc.steps: step3. set new trace id and save old trace id.
955      * @tc.expected: step3. new trace id get into TLS.
956      * @tc.steps: step4. store old trace id.
957      * @tc.expected: step4. old trace id get into TLS.
958      * @tc.steps: step5. end trace.
959      * @tc.expected: step5. trace terminate.
960      */
961 
962     // begin trace
963     HiTraceId id = HiTraceChain::Begin("RestoreTest_004", HITRACE_FLAG_TP_INFO);
964 
965     // generate new trace id
966     HiTraceIdStruct tempId{0};
967     HiTraceChainInitId(&tempId);
968     tempId.valid=HITRACE_ID_INVALID;
969     HiTraceId newId(tempId);
970     uint64_t chainId = GenerateChainId();
971     uint64_t spanId = GenerateSpanId();
972     uint64_t parentSpanId = GenerateParentSpanId();
973     newId.SetChainId(chainId);
974     newId.SetSpanId(spanId);
975     newId.SetParentSpanId(parentSpanId);
976 
977     // set new id and save old id
978     HiTraceId oldId = HiTraceChain::SaveAndSet(newId);
979     HiTraceId currentId = HiTraceChain::GetId();
980     HiTraceChain::Tracepoint(
981             HITRACE_CM_DEVICE, HITRACE_TP_CS, currentId, "client send msg %d", DEVICE_CLIENT_SEND);
982     HiTraceChain::Tracepoint(
983             HITRACE_CM_PROCESS, HITRACE_TP_CS, currentId, "client send msg %d", PROCESS_CLIENT_SEND);
984     HiTraceChain::Tracepoint(
985             HITRACE_CM_THREAD, HITRACE_TP_CS, currentId, "client send msg %d", THREAD_CLIENT_SEND);
986     HiTraceChain::Tracepoint(
987             HITRACE_CM_DEFAULT, HITRACE_TP_CS, currentId, "client send msg %d", DEFAULT_CLIENT_SEND);
988 
989     // restore old id
990     HiTraceChain::Restore(oldId);
991     HiTraceId currentId2 = HiTraceChain::GetId();
992     EXPECT_EQ(id.GetChainId(), currentId2.GetChainId());
993     EXPECT_EQ(id.GetSpanId(), currentId2.GetSpanId());
994     EXPECT_EQ(id.GetParentSpanId(), currentId2.GetParentSpanId());
995     HiTraceChain::Tracepoint(
996             HITRACE_CM_DEVICE, HITRACE_TP_CS, currentId2, "client send msg %d", DEVICE_CLIENT_SEND);
997     HiTraceChain::Tracepoint(
998             HITRACE_CM_PROCESS, HITRACE_TP_CS, currentId2, "client send msg %d", PROCESS_CLIENT_SEND);
999     HiTraceChain::Tracepoint(
1000             HITRACE_CM_THREAD, HITRACE_TP_CS, currentId2, "client send msg %d", THREAD_CLIENT_SEND);
1001     HiTraceChain::Tracepoint(
1002             HITRACE_CM_DEFAULT, HITRACE_TP_CS, currentId2, "client send msg %d", DEFAULT_CLIENT_SEND);
1003 
1004     // end trace
1005     HiTraceChain::End(id);
1006 }
1007 }  // namespace HiviewDFX
1008 }  // namespace OHOS
1009