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
41static 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
56static 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
71static 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
85static 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
99namespace OHOS {
100namespace HiviewDFX {
101using namespace testing::ext;
102
103class HiTraceChainCppTest : public testing::Test {
104public:
105    static void SetUpTestCase();
106    static void TearDownTestCase();
107    void SetUp();
108    void TearDown();
109};
110
111void HiTraceChainCppTest::SetUpTestCase()
112{}
113
114void HiTraceChainCppTest::TearDownTestCase()
115{}
116
117void HiTraceChainCppTest::SetUp()
118{
119    HiTraceChain::ClearId();
120}
121
122void 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 */
131HWTEST_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 */
195HWTEST_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 */
258HWTEST_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 */
283HWTEST_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 */
342HWTEST_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 */
387HWTEST_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 */
418HWTEST_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 */
444HWTEST_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 */
467HWTEST_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 */
501HWTEST_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 */
526HWTEST_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 */
557HWTEST_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 */
588HWTEST_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 */
619HWTEST_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 */
648HWTEST_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 */
674HWTEST_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 */
709HWTEST_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 */
749HWTEST_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 */
815HWTEST_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 */
879HWTEST_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 */
947HWTEST_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