• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "dbinder_service_test_helper.h"
17 #include <sys/time.h>
18 #include <csignal>
19 #include <unistd.h>
20 #include <vector>
21 #include <string>
22 #include <fstream>
23 #include <iostream>
24 #include <cstdlib>
25 #include <securec.h>
26 #include "ipc_types.h"
27 #include "hilog/log.h"
28 #include "log_tags.h"
29 
30 using namespace OHOS;
31 using namespace OHOS::HiviewDFX;
32 
33 #ifndef TITLE
34 #define TITLE __PRETTY_FUNCTION__
35 #endif
36 
37 static constexpr OHOS::HiviewDFX::HiLogLabel LOG_LABEL = { LOG_CORE, LOG_ID_RPC, "DbinderTestHelper" };
38 #define DBINDER_LOGE(fmt, args...) \
39     (void)OHOS::HiviewDFX::HiLog::Error(LOG_LABEL, "%{public}s %{public}d: " fmt, TITLE, __LINE__, ##args)
40 #define DBINDER_LOGI(fmt, args...) \
41     (void)OHOS::HiviewDFX::HiLog::Info(LOG_LABEL, "%{public}s %{public}d: " fmt, TITLE, __LINE__, ##args)
42 
GetPidByName(std::string taskName)43 pid_t GetPidByName(std::string taskName)
44 {
45     DIR *dir = nullptr;
46     struct dirent *ptr = nullptr;
47     FILE *fp = nullptr;
48     char filepath[PATH_LENGTH];
49     char curTaskName[PATH_LENGTH];
50     char buf[BUF_SIZE];
51     pid_t pid = INVALID_PID;
52 
53     dir = opendir("/proc");
54     if (dir == nullptr) {
55         return pid;
56     }
57     while ((ptr = readdir(dir)) != nullptr) {
58         if ((strcmp(ptr->d_name, ".") == 0) || (strcmp(ptr->d_name, "..") == 0))
59             continue;
60         if (DT_DIR != ptr->d_type) {
61             continue;
62         }
63 
64         if (sprintf_s(filepath, sizeof(filepath), "/proc/%s/status", ptr->d_name) <= EOK) {
65             DBINDER_LOGI("sprintf_s fail");
66             closedir(dir);
67             return INVALID_PID;
68         }
69 
70         fp = fopen(filepath, "r");
71         if (fp != nullptr) {
72             if (fgets(buf, BUF_SIZE - 1, fp) == nullptr) {
73                 fclose(fp);
74                 continue;
75             }
76             if (sscanf_s(buf, "%*s %s", curTaskName, sizeof(curTaskName)) <= EOK) {
77                 DBINDER_LOGI("sscanf fail");
78             }
79 
80             if (!strcmp(taskName.c_str(), curTaskName)) {
81                 if (sscanf_s(ptr->d_name, "%d", &pid) <= EOK) {
82                     DBINDER_LOGI("sscanf fail");
83                 }
84             }
85             fclose(fp);
86         }
87     }
88     closedir(dir);
89     return pid;
90 }
91 
GetChildPids(std::vector<pid_t> & childPids)92 int GetChildPids(std::vector<pid_t> &childPids)
93 {
94     pid_t current = getpid();
95     DBINDER_LOGI("current pid %{public}d", current);
96     const std::string TASK_PATH = "/proc/" + std::to_string(current) + "/task";
97     DIR *dir = nullptr;
98     struct dirent *ptr = nullptr;
99 
100     dir = opendir(TASK_PATH.c_str());
101     if (dir != nullptr) {
102         while ((ptr = readdir(dir)) != nullptr) {
103             if ((strcmp(ptr->d_name, ".") == 0) || (strcmp(ptr->d_name, "..") == 0)) {
104                 continue;
105             }
106             if (DT_DIR != ptr->d_type) {
107                 continue;
108             }
109 
110             pid_t child = std::stoi(ptr->d_name);
111             if (child == current) {
112                 continue;
113             }
114             childPids.push_back(child);
115             DBINDER_LOGI("child pid %{public}d", child);
116         }
117         closedir(dir);
118     }
119 
120     return ERR_NONE;
121 }
122 
StartExecutable(std::string name,std::string args)123 pid_t StartExecutable(std::string name, std::string args)
124 {
125     const char *ldLibraryPath = getenv("LD_LIBRARY_PATH");
126     if (ldLibraryPath != nullptr) {
127         unsetenv("LD_LIBRARY_PATH");
128     }
129     pid_t pid = GetPidByName(name);
130     if (pid != INVALID_PID) {
131         DBINDER_LOGI("test.service is already started, do nothing");
132         return pid;
133     }
134 
135     std::string cmd1 = "chmod +x /data/test/" + name;
136     int res = system(cmd1.c_str());
137     DBINDER_LOGI("%{public}s res = %d, errno = %{public}d %{public}s", cmd1.c_str(), res, errno, strerror(errno));
138 
139     std::string cmd2 = "/data/test/" + name + " " + args + "&";
140     res = system(cmd2.c_str());
141     DBINDER_LOGI("%{public}s res = %{public}d", cmd2.c_str(), res);
142 
143     if (ldLibraryPath != nullptr) {
144         setenv("LD_LIBRARY_PATH", ldLibraryPath, 1);
145     }
146     res = 0;
147     while (pid == INVALID_PID && res < 10) { // 10:try-time to wait for exe start
148         pid = GetPidByName(name);
149         DBINDER_LOGI("StartExecutable pid = %{public}d && name = %{public}s", pid, name.c_str());
150         usleep(100 * 1000); // 100:time-length 1000:time-unit
151         res++;
152     }
153 
154     DBINDER_LOGI("start %{public}s done", name.c_str());
155     return GetPidByName(name);
156 }
157 
StopExecutable(pid_t pid)158 void StopExecutable(pid_t pid)
159 {
160     kill(pid, SIGKILL);
161 }
162 
StopExecutable(std::string name)163 void StopExecutable(std::string name)
164 {
165     pid_t pid = GetPidByName(name);
166     DBINDER_LOGI("StopExecutable %{public}s pid = %{public}d, prepare to kill it", name.c_str(), pid);
167 
168     if (pid != INVALID_PID) {
169         DBINDER_LOGI("%{public}s pid = %{public}d, kill it", name.c_str(), pid);
170         kill(pid, SIGKILL);
171     }
172 }
173 
StartDBinderServiceSARegistry()174 int StartDBinderServiceSARegistry()
175 {
176     pid_t registryPid = GetPidByName(SYSTEM_ABILITY_MANAGER_NAME);
177     if (registryPid != -1) {
178         DBINDER_LOGI("SYSTEM_ABILITY_MANAGER_NAME Already Started pid=%{public}d", registryPid);
179         return registryPid;
180     }
181     StartExecutable(SYSTEM_ABILITY_MANAGER_NAME);
182     usleep(200 * 1000); // 100:200-length 1000:time-unit
183     DBINDER_LOGI("Start SYSTEM_ABILITY_MANAGER_NAME done");
184     return ERR_NONE;
185 }
186 
StopDBinderServiceSARegistry()187 void StopDBinderServiceSARegistry()
188 {
189     StopExecutable(SYSTEM_ABILITY_MANAGER_NAME);
190 }
191 
StartDBinderServiceTestService()192 void StartDBinderServiceTestService()
193 {
194     pid_t pid = StartExecutable(DBINDER_TEST_SERVICE_NAME);
195     DBINDER_LOGE("DBINDER_TEST_SERVICE_NAME pid : %{public}d", pid);
196 
197     pid = StartExecutable(DBINDER_TEST_SERVICE_NAME_SECOND);
198     DBINDER_LOGE("DBINDER_TEST_SERVICE_NAME_SECOND pid : %{public}d", pid);
199 }
200 
StopDBinderServiceTestService()201 void StopDBinderServiceTestService()
202 {
203     StopExecutable(DBINDER_TEST_SERVICE_NAME);
204     DBINDER_LOGE("Stop DBINDER_TEST_SERVICE_NAME");
205 
206     StopExecutable(DBINDER_TEST_SERVICE_NAME_SECOND);
207     DBINDER_LOGE("Stop DBINDER_TEST_SERVICE_NAME_SECOND");
208 }
209 
SetCurrentTestCase(int caseNum)210 int SetCurrentTestCase(int caseNum)
211 {
212     if (caseNum > DBINDER_TEST_START && caseNum < DBINDER_TEST_END) {
213         printf("SetCurrentTestCase to : %d\n", caseNum);
214         return g_currentTestCase = caseNum;
215     }
216     printf("SetCurrentTestCase to : %d\n", DBINDER_TEST_INIT);
217     return DBINDER_TEST_INIT;
218 }
219 
GetCurrentTestCase(void)220 int GetCurrentTestCase(void)
221 {
222     if (g_currentTestCase > DBINDER_TEST_START && g_currentTestCase < DBINDER_TEST_END) {
223         printf("GetCurrentTestCase is : %d\n", g_currentTestCase);
224         return g_currentTestCase;
225     }
226     printf("GetCurrentTestCase is : %d\n", DBINDER_TEST_INIT);
227     return DBINDER_TEST_INIT;
228 }
229 
GetCurrentTime()230 int64_t GetCurrentTime()
231 {
232     struct timeval timeInterval = {};
233     gettimeofday(&timeInterval, nullptr);
234     return timeInterval.tv_sec * SECOND_TO_MS + timeInterval.tv_usec / SECOND_TO_MS;
235 }
236 
GetSpeed(int64_t timeInterval,int size,int times)237 float GetSpeed(int64_t timeInterval, int size, int times)
238 {
239     if (timeInterval == 0) {
240         return 0;
241     }
242     float dataSize { times * size };
243     float costTime { timeInterval };
244     float speed = dataSize / costTime;
245     return speed * SECOND_TO_MS / KB_TO_B;
246 }
247