• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-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 <chrono>
16 #include <ctime>
17 #include <gtest/gtest.h>
18 #include <iostream>
19 #include <unistd.h>
20 
21 #include "accesstoken_kit.h"
22 #include "file_util.h"
23 #include "nativetoken_kit.h"
24 #include "parameter_ex.h"
25 #include "token_setproc.h"
26 #include "trace_collector_client.h"
27 
28 using namespace testing::ext;
29 using namespace OHOS::HiviewDFX;
30 using namespace OHOS::HiviewDFX::UCollectClient;
31 using namespace OHOS::HiviewDFX::UCollect;
32 
33 namespace {
34 constexpr int SLEEP_DURATION = 10;
35 const std::vector<std::string> TAG_GROUPS = {"scene_performance"};
36 
NativeTokenGet(const char * perms[],int size)37 void NativeTokenGet(const char* perms[], int size)
38 {
39     uint64_t tokenId;
40     NativeTokenInfoParams infoInstance = {
41         .dcapsNum = 0,
42         .permsNum = size,
43         .aclsNum = 0,
44         .dcaps = nullptr,
45         .perms = perms,
46         .acls = nullptr,
47         .aplStr = "system_basic",
48     };
49 
50     infoInstance.processName = "UCollectionClientUnitTest";
51     tokenId = GetAccessTokenId(&infoInstance);
52     SetSelfTokenID(tokenId);
53     OHOS::Security::AccessToken::AccessTokenKit::ReloadNativeTokenInfo();
54 }
55 
EnablePermissionAccess()56 void EnablePermissionAccess()
57 {
58     const char* perms[] = {
59         "ohos.permission.WRITE_HIVIEW_SYSTEM",
60         "ohos.permission.READ_HIVIEW_SYSTEM",
61         "ohos.permission.DUMP",
62     };
63     NativeTokenGet(perms, 3); // 3 is the size of the array which consists of required permissions.
64 }
65 
DisablePermissionAccess()66 void DisablePermissionAccess()
67 {
68     NativeTokenGet(nullptr, 0); // empty permission array.
69 }
70 
Sleep()71 void Sleep()
72 {
73     sleep(SLEEP_DURATION);
74 }
75 
IsCommonState()76 bool IsCommonState()
77 {
78     bool isBetaVersion = Parameter::IsBetaVersion();
79     bool isUCollectionSwitchOn = Parameter::IsUCollectionSwitchOn();
80     bool isTraceCollectionSwitchOn = Parameter::IsTraceCollectionSwitchOn();
81     bool isFrozeSwitchOn = Parameter::GetBoolean("persist.hiview.freeze_detector", false);
82     if (!isBetaVersion && !isFrozeSwitchOn && !isUCollectionSwitchOn && !isTraceCollectionSwitchOn) {
83         return false;
84     }
85     if (isTraceCollectionSwitchOn) {
86         return false;
87     }
88     return true;
89 }
90 }
91 
92 class TraceCollectorTest : public testing::Test {
93 public:
SetUp()94     void SetUp() {}
TearDown()95     void TearDown() {}
SetUpTestCase()96     static void SetUpTestCase() {}
TearDownTestCase()97     static void TearDownTestCase() {}
98 };
99 
100 /**
101  * @tc.name: TraceCollectorTest001
102  * @tc.desc: use trace in command state.
103  * @tc.type: FUNC
104 */
105 HWTEST_F(TraceCollectorTest, TraceCollectorTest001, TestSize.Level1)
106 {
107     auto traceCollector = TraceCollector::Create();
108     ASSERT_TRUE(traceCollector != nullptr);
109     EnablePermissionAccess();
110     auto openRet = traceCollector->OpenSnapshot(TAG_GROUPS);
111     ASSERT_EQ(openRet.retCode, UcError::SUCCESS);
112     Sleep();
113     auto dumpRes = traceCollector->DumpSnapshot(UCollect::TraceClient::COMMAND);
114     ASSERT_TRUE(dumpRes.retCode == UcError::SUCCESS);
115     ASSERT_TRUE(dumpRes.data.size() >= 0);
116     auto dumpRes2 = traceCollector->DumpSnapshot(); // dump common trace in command state return fail
117     ASSERT_EQ(dumpRes2.retCode, UcError::TRACE_STATE_ERROR);
118     auto closeRet = traceCollector->Close();
119     ASSERT_TRUE(closeRet.retCode == UcError::SUCCESS);
120 
121     DisablePermissionAccess();
122 }
123 
124 /**
125  * @tc.name: TraceCollectorTest002
126  * @tc.desc: use trace in recording mode.
127  * @tc.type: FUNC
128 */
129 HWTEST_F(TraceCollectorTest, TraceCollectorTest002, TestSize.Level1)
130 {
131     auto traceCollector = TraceCollector::Create();
132     ASSERT_TRUE(traceCollector != nullptr);
133     EnablePermissionAccess();
134     std::string args = "tags:sched clockType:boot bufferSize:1024 overwrite:1 output:/data/log/test.sys";
135     auto openRet = traceCollector->OpenRecording(args);
136     if (openRet.retCode == UcError::SUCCESS) {
137         auto recOnRet = traceCollector->RecordingOn();
138         ASSERT_TRUE(recOnRet.retCode == UcError::SUCCESS);
139         Sleep();
140         auto recOffRet = traceCollector->RecordingOff();
141         ASSERT_TRUE(recOffRet.data.size() >= 0);
142     }
143     traceCollector->Close();
144     DisablePermissionAccess();
145 }
146 
147 /**
148  * @tc.name: TraceCollectorTest003
149  * @tc.desc: dump trace in common state.
150  * @tc.type: FUNC
151 */
152 HWTEST_F(TraceCollectorTest, TraceCollectorTest003, TestSize.Level1)
153 {
154     auto traceCollector = TraceCollector::Create();
155     ASSERT_TRUE(traceCollector != nullptr);
156     EnablePermissionAccess();
157     auto ret = traceCollector->DumpSnapshot();
158     if (IsCommonState()) {
159         ASSERT_TRUE(ret.retCode == UcError::SUCCESS);
160         ASSERT_TRUE(ret.data.size() >= 0);
161     } else {
162         ASSERT_EQ(ret.retCode, UcError::TRACE_STATE_ERROR);
163     }
164     DisablePermissionAccess();
165 }
166 
GetMilliseconds()167 static uint64_t GetMilliseconds()
168 {
169     auto now = std::chrono::system_clock::now();
170     auto millisecs = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch());
171     return millisecs.count();
172 }
173 
174 /**
175  * @tc.name: TraceCollectorTest003
176  * @tc.desc: start app trace.
177  * @tc.type: FUNC
178 */
179 HWTEST_F(TraceCollectorTest, TraceCollectorTest004, TestSize.Level1)
180 {
181     auto traceCollector = TraceCollector::Create();
182     ASSERT_TRUE(traceCollector != nullptr);
183     EnablePermissionAccess();
184     AppCaller appCaller;
185     appCaller.actionId = ACTION_ID_START_TRACE;
186     appCaller.bundleName = "com.example.helloworld";
187     appCaller.bundleVersion = "2.0.1";
188     appCaller.foreground = 1;
189     appCaller.threadName = "mainThread";
190     appCaller.uid = 20020143; // 20020143: user uid
191     appCaller.pid = 100; // 100: pid
192     appCaller.happenTime = GetMilliseconds();
193     appCaller.beginTime = appCaller.happenTime - 100; // 100: ms
194     appCaller.endTime = appCaller.happenTime + 100; // 100: ms
195     auto result = traceCollector->CaptureDurationTrace(appCaller);
196     std::cout << "retCode=" << result.retCode << ", data=" << result.data << std::endl;
197     ASSERT_TRUE(result.data == 0);
198 
199     AppCaller appCaller2;
200     appCaller2.actionId = ACTION_ID_DUMP_TRACE;
201     appCaller2.bundleName = "com.example.helloworld";
202     appCaller2.bundleVersion = "2.0.1";
203     appCaller2.foreground = 1;
204     appCaller2.threadName = "mainThread";
205     appCaller2.uid = 20020143; // 20020143: user id
206     appCaller2.pid = 100; // 100: pid
207     appCaller2.happenTime = GetMilliseconds();
208     appCaller2.beginTime = appCaller.happenTime - 100; // 100: ms
209     appCaller2.endTime = appCaller.happenTime + 100; // 100: ms
210     auto result2 = traceCollector->CaptureDurationTrace(appCaller2);
211     std::cout << "retCode=" << result2.retCode << ", data=" << result2.data << std::endl;
212     ASSERT_NE(result2.retCode, UcError::TRACE_STATE_ERROR);
213     DisablePermissionAccess();
214     Sleep();
215 }
216