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 #include <fcntl.h>
16 #include <pthread.h>
17 #include <string.h>
18 #include <sys/time.h>
19
20 #include "begetctl.h"
21 #include "init_param.h"
22 #include "init_utils.h"
23 #include "loop_event.h"
24 #include "parameter.h"
25 #include "plugin_test.h"
26 #include "service_watcher.h"
27 #include "parameter.h"
28
29 #define MAX_THREAD_NUMBER 100
30 #define MAX_NUMBER 10
31 #define READ_DURATION 100000
32 #define CMD_INDEX 2
33
GetLocalBuffer(uint32_t * buffSize)34 static char *GetLocalBuffer(uint32_t *buffSize)
35 {
36 static char buffer[PARAM_NAME_LEN_MAX + PARAM_CONST_VALUE_LEN_MAX] = {0};
37 if (buffSize != NULL) {
38 *buffSize = sizeof(buffer);
39 }
40 return buffer;
41 }
42
43 int g_stop = 0;
CmdReader(void * args)44 static void *CmdReader(void *args)
45 {
46 (void)srand((unsigned)time(NULL));
47 uint32_t buffSize = 0;
48 char *buffer = GetLocalBuffer(&buffSize);
49 while (g_stop == 0) {
50 int wait = READ_DURATION + READ_DURATION; // 100ms rand
51 uint32_t size = buffSize;
52 int ret = SystemGetParameter("test.randrom.read", buffer, &size);
53 if (ret == 0) {
54 printf("SystemGetParameter value %s %d \n", buffer, wait);
55 } else {
56 printf("SystemGetParameter fail %d \n", wait);
57 }
58 usleep(wait);
59 }
60 return NULL;
61 }
62
BShellParamCmdRead(BShellHandle shell,int32_t argc,char * argv[])63 static int32_t BShellParamCmdRead(BShellHandle shell, int32_t argc, char *argv[])
64 {
65 PLUGIN_CHECK(argc >= 1, return -1, "Invalid parameter");
66 static pthread_t thread = 0;
67 PLUGIN_LOGV("BShellParamCmdWatch %s, threadId %d", argv[1], thread);
68 if (strcmp(argv[1], "start") == 0) {
69 if (thread != 0) {
70 return 0;
71 }
72 SystemSetParameter("test.randrom.read.start", "1");
73 pthread_create(&thread, NULL, CmdReader, argv[1]);
74 } else if (strcmp(argv[1], "stop") == 0) {
75 if (thread == 0) {
76 return 0;
77 }
78 SystemSetParameter("test.randrom.read.start", "0");
79 g_stop = 1;
80 pthread_join(thread, NULL);
81 thread = 0;
82 }
83 return 0;
84 }
85
86 typedef struct {
87 char name[PARAM_NAME_LEN_MAX];
88 pthread_t thread;
89 } TestWatchContext;
90
HandleParamChange2(const char * key,const char * value,void * context)91 static void HandleParamChange2(const char *key, const char *value, void *context)
92 {
93 PLUGIN_CHECK(key != NULL && value != NULL, return, "Invalid parameter");
94 long long commit = GetSystemCommitId();
95 size_t index = (size_t)context;
96 printf("[%zu] Receive parameter commit %lld change %s %s \n", index, commit, key, value);
97 static int addWatcher = 0;
98 int ret = 0;
99 if ((index == 4) && !addWatcher) { // 4 when context == 4 add
100 index = 5; // 5 add context
101 ret = SystemWatchParameter(key, HandleParamChange2, (void *)index);
102 if (ret != 0) {
103 printf("Add watcher %s fail %zu \n", key, index);
104 }
105 addWatcher = 1;
106 return;
107 }
108 if (index == 2) { // 2 when context == 2 delete 3
109 index = 3; // 3 delete context
110 RemoveParameterWatcher(key, HandleParamChange2, (void *)index);
111 if (ret != 0) {
112 printf("Remove watcher fail %zu \n", index);
113 }
114 return;
115 }
116 if (index == 1) { // 1 when context == 1 delete 1
117 RemoveParameterWatcher(key, HandleParamChange2, (void *)index);
118 if (ret != 0) {
119 printf("Remove watcher fail %zu \n", index);
120 }
121 return;
122 }
123 if ((index == 5) && (addWatcher == 1)) { // 5 when context == 5 delete 5
124 RemoveParameterWatcher(key, HandleParamChange2, (void *)index);
125 if (ret != 0) {
126 printf("Remove watcher fail %zu \n", index);
127 }
128 addWatcher = 0;
129 }
130 }
131
HandleParamChange1(const char * key,const char * value,void * context)132 static void HandleParamChange1(const char *key, const char *value, void *context)
133 {
134 PLUGIN_CHECK(key != NULL && value != NULL, return, "Invalid parameter");
135 long long commit = GetSystemCommitId();
136 size_t index = (size_t)context;
137 printf("[%zu] Receive parameter commit %lld change %s %s \n", index, commit, key, value);
138 }
139
CmdThreadWatcher(void * args)140 static void *CmdThreadWatcher(void *args)
141 {
142 TestWatchContext *context = (TestWatchContext *)args;
143 for (size_t i = 1; i <= MAX_NUMBER; i++) {
144 int ret = SystemWatchParameter(context->name, HandleParamChange2, (void *)i);
145 if (ret != 0) {
146 printf("Add watcher %s fail %zu \n", context->name, i);
147 }
148 ret = SetParameter(context->name, context->name);
149 if (ret != 0) {
150 printf("Set parameter %s fail %zu \n", context->name, i);
151 }
152 }
153 sleep(1);
154 for (size_t i = 1; i <= MAX_NUMBER; i++) {
155 int ret = RemoveParameterWatcher(context->name, HandleParamChange2, (void *)i);
156 if (ret != 0) {
157 printf("Remove watcher %s fail %zu \n", context->name, i);
158 }
159 }
160 free(context);
161 return NULL;
162 }
163
StartWatcherInThread(const char * prefix)164 static void StartWatcherInThread(const char *prefix)
165 {
166 TestWatchContext *context[MAX_THREAD_NUMBER] = { NULL };
167 for (size_t i = 0; i < MAX_THREAD_NUMBER; i++) {
168 context[i] = calloc(1, sizeof(TestWatchContext));
169 PLUGIN_CHECK(context[i] != NULL, return, "Failed to alloc context");
170 int len = sprintf_s(context[i]->name, sizeof(context[i]->name), "%s.%zu", prefix, i);
171 if (len > 0) {
172 printf("Add watcher %s \n", context[i]->name);
173 pthread_create(&context[i]->thread, NULL, CmdThreadWatcher, context[i]);
174 }
175 }
176 }
177
StartWatcher(const char * prefix)178 static void StartWatcher(const char *prefix)
179 {
180 static size_t index = 0;
181 int ret = SystemWatchParameter(prefix, HandleParamChange1, (void *)index);
182 if (ret != 0) {
183 printf("Add watcher %s fail \n", prefix);
184 return;
185 }
186 index++;
187 }
188
BShellParamCmdWatch(BShellHandle shell,int32_t argc,char * argv[])189 static int32_t BShellParamCmdWatch(BShellHandle shell, int32_t argc, char *argv[])
190 {
191 PLUGIN_CHECK(argc >= 1, return -1, "Invalid parameter");
192 PLUGIN_LOGV("BShellParamCmdWatch %s", argv[1]);
193 StartWatcher(argv[1]);
194
195 if (argc <= CMD_INDEX) {
196 return 0;
197 }
198 if (strcmp(argv[CMD_INDEX], "thread") == 0) { // 2 cmd index
199 StartWatcherInThread(argv[1]);
200 return 0;
201 }
202
203 int maxCount = StringToInt(argv[CMD_INDEX], -1); // 2 cmd index
204 if (maxCount <= 0 || maxCount > 65535) { // 65535 max count
205 PLUGIN_LOGE("Invalid input %s", argv[CMD_INDEX]);
206 return 0;
207 }
208 uint32_t buffSize = 0;
209 char *buffer = GetLocalBuffer(&buffSize);
210 size_t count = 0;
211 while (count < (size_t)maxCount) { // 100 max count
212 int len = sprintf_s(buffer, buffSize, "%s.%zu", argv[1], count);
213 PLUGIN_CHECK(len > 0, return -1, "Invalid buffer");
214 buffer[len] = '\0';
215 StartWatcher(buffer);
216 count++;
217 }
218 return 0;
219 }
220
BShellParamCmdInstall(BShellHandle shell,int32_t argc,char * argv[])221 static int32_t BShellParamCmdInstall(BShellHandle shell, int32_t argc, char *argv[])
222 {
223 PLUGIN_CHECK(argc >= 1, return -1, "Invalid parameter");
224 PLUGIN_LOGV("BShellParamCmdInstall %s %s", argv[0], argv[1]);
225 uint32_t buffSize = 0;
226 char *buffer = GetLocalBuffer(&buffSize);
227 int ret = sprintf_s(buffer, buffSize, "ohos.servicectrl.%s", argv[0]);
228 PLUGIN_CHECK(ret > 0, return -1, "Invalid buffer");
229 buffer[ret] = '\0';
230 SystemSetParameter(buffer, argv[1]);
231 return 0;
232 }
233
BShellParamCmdDisplay(BShellHandle shell,int32_t argc,char * argv[])234 static int32_t BShellParamCmdDisplay(BShellHandle shell, int32_t argc, char *argv[])
235 {
236 PLUGIN_CHECK(argc >= 1, return -1, "Invalid parameter");
237 PLUGIN_LOGV("BShellParamCmdDisplay %s %s", argv[0], argv[1]);
238 SystemSetParameter("ohos.servicectrl.display", argv[1]);
239 return 0;
240 }
241
ServiceStatusChangeTest(const char * key,ServiceStatus status)242 void ServiceStatusChangeTest(const char *key, ServiceStatus status)
243 {
244 PLUGIN_LOGI("group-test-stage3: wait service %s status: %d", key, status);
245 if (status == SERVICE_READY || status == SERVICE_STARTED) {
246 PLUGIN_LOGI("Service %s start work", key);
247 }
248 }
249
BShellParamCmdGroupTest(BShellHandle shell,int32_t argc,char * argv[])250 static int32_t BShellParamCmdGroupTest(BShellHandle shell, int32_t argc, char *argv[])
251 {
252 PLUGIN_CHECK(argc >= 1, return -1, "Invalid parameter");
253 PLUGIN_LOGI("BShellParamCmdGroupTest %s stage: %s", argv[0], argv[1]);
254 if (argc > 2 && strcmp(argv[1], "wait") == 0) { // 2 service name index
255 PLUGIN_LOGI("group-test-stage3: wait service %s", argv[2]); // 2 service name index
256 ServiceWatchForStatus(argv[2], ServiceStatusChangeTest); // 2 service name index
257 LE_RunLoop(LE_GetDefaultLoop());
258 LE_CloseLoop(LE_GetDefaultLoop());
259 }
260 return 0;
261 }
262
BShellParamCmdUdidGet(BShellHandle shell,int32_t argc,char * argv[])263 static int32_t BShellParamCmdUdidGet(BShellHandle shell, int32_t argc, char *argv[])
264 {
265 PLUGIN_CHECK(argc >= 1, return -1, "Invalid parameter");
266 PLUGIN_LOGI("BShellParamCmdUdidGet ");
267 char localDeviceId[65] = {0}; // 65 udid len
268 AclGetDevUdid(localDeviceId, 65); // 65 udid len
269 BShellEnvOutput(shell, " udid: %s\r\n", localDeviceId);
270 return 0;
271 }
272
CalcValue(const char * value)273 static int CalcValue(const char *value)
274 {
275 char *begin = (char *)value;
276 while (*begin != '\0') {
277 if (*begin == ' ') {
278 begin++;
279 } else {
280 break;
281 }
282 }
283 char *end = begin + strlen(begin);
284 while (end > begin) {
285 if (*end > '9' || *end < '0') {
286 *end = '\0';
287 }
288 end--;
289 }
290 return StringToInt(begin, -1);
291 }
292
BShellParamCmdMemGet(BShellHandle shell,int32_t argc,char * argv[])293 static int32_t BShellParamCmdMemGet(BShellHandle shell, int32_t argc, char *argv[])
294 {
295 PLUGIN_CHECK(argc > 1, return -1, "Invalid parameter");
296 uint32_t buffSize = 0; // 1024 max buffer for decode
297 char *buff = GetLocalBuffer(&buffSize);
298 PLUGIN_CHECK(buff != NULL, return -1, "Failed to get local buffer");
299 int ret = sprintf_s(buff, buffSize - 1, "/proc/%s/smaps", argv[1]);
300 PLUGIN_CHECK(ret > 0, return -1, "Failed to format path %s", argv[1]);
301 buff[ret] = '\0';
302 char *realPath = GetRealPath(buff);
303 PLUGIN_CHECK(realPath != NULL, return -1, "Failed to get real path");
304 int all = 0;
305 if (argc > 2 && strcmp(argv[2], "all") == 0) { // 2 2 max arg
306 all = 1;
307 }
308 FILE *fp = fopen(realPath, "r");
309 free(realPath);
310 int value = 0;
311 while (fp != NULL && buff != NULL && fgets(buff, buffSize, fp) != NULL) {
312 buff[buffSize - 1] = '\0';
313 if (strncmp(buff, "Pss:", strlen("Pss:")) == 0) {
314 int v = CalcValue(buff + strlen("Pss:"));
315 if (all) {
316 printf("Pss: %d kb\n", v);
317 }
318 value += v;
319 } else if (strncmp(buff, "SwapPss:", strlen("SwapPss:")) == 0) {
320 int v = CalcValue(buff + strlen("SwapPss:"));
321 if (all) {
322 printf("SwapPss: %d kb\n", v);
323 }
324 value += v;
325 }
326 }
327 if (fp != NULL) {
328 fclose(fp);
329 printf("Total mem %d kb\n", value);
330 } else {
331 printf("Failed to get memory for %s %s \n", argv[1], buff);
332 }
333 return 0;
334 }
335
336 #define MAX_TEST 10000
DiffLocalTime(struct timespec * startTime)337 static long long DiffLocalTime(struct timespec *startTime)
338 {
339 struct timespec endTime;
340 clock_gettime(CLOCK_MONOTONIC, &(endTime));
341 long long diff = (long long)((endTime.tv_sec - startTime->tv_sec) * 1000000); // 1000000 1000ms
342 if (endTime.tv_nsec > startTime->tv_nsec) {
343 diff += (endTime.tv_nsec - startTime->tv_nsec) / 1000; // 1000 1ms
344 } else {
345 diff -= (startTime->tv_nsec - endTime.tv_nsec) / 1000; // 1000 1ms
346 }
347 return diff;
348 }
349
TestPerformance(const char * testParamName)350 static void TestPerformance(const char *testParamName)
351 {
352 struct timespec startTime;
353 CachedHandle cacheHandle = CachedParameterCreate(testParamName, "true");
354 clock_gettime(CLOCK_MONOTONIC, &(startTime));
355 const char *value = NULL;
356 for (int i = 0; i < MAX_TEST; ++i) {
357 value = CachedParameterGet(cacheHandle);
358 }
359 CachedParameterDestroy(cacheHandle);
360 printf("CachedParameterGet time %lld us value %s \n", DiffLocalTime(&startTime), value);
361 return;
362 }
363
BShellParamCmdPerformance(BShellHandle shell,int32_t argc,char * argv[])364 static int32_t BShellParamCmdPerformance(BShellHandle shell, int32_t argc, char *argv[])
365 {
366 const char *name = "test.performance.read";
367 TestPerformance(name);
368 CachedHandle cacheHandle = CachedParameterCreate(name, "true");
369 int i = 0;
370 while (++i < MAX_TEST) {
371 const char *value = CachedParameterGet(cacheHandle);
372 printf("CachedParameterGet %s value %s \n", name, value);
373 usleep(100);
374 }
375 CachedParameterDestroy(cacheHandle);
376 return 0;
377 }
378
BShellCmdRegister(BShellHandle shell,int execMode)379 int32_t BShellCmdRegister(BShellHandle shell, int execMode)
380 {
381 if (execMode == 0) {
382 const CmdInfo infos[] = {
383 {"init", BShellParamCmdGroupTest, "init group test", "init group test [stage]", "init group test"},
384 {"display", BShellParamCmdMemGet, "display memory pid", "display memory [pid]", "display memory"},
385 };
386 for (size_t i = 0; i < sizeof(infos) / sizeof(infos[0]); i++) {
387 BShellEnvRegisterCmd(shell, &infos[i]);
388 }
389 } else {
390 const CmdInfo infos[] = {
391 {"display", BShellParamCmdDisplay, "display system service", "display service", "display service"},
392 {"read", BShellParamCmdRead, "read system parameter", "read [start | stop]", ""},
393 {"watcher", BShellParamCmdWatch, "watcher system parameter", "watcher [name]", ""},
394 {"install", BShellParamCmdInstall, "install plugin", "install [name]", ""},
395 {"uninstall", BShellParamCmdInstall, "uninstall plugin", "uninstall [name]", ""},
396 {"group", BShellParamCmdGroupTest, "group test", "group test [stage]", "group test"},
397 {"display", BShellParamCmdUdidGet, "display udid", "display udid", "display udid"},
398 {"display", BShellParamCmdMemGet, "display memory pid", "display memory [pid]", "display memory"},
399 {"test", BShellParamCmdPerformance, "test performance", "test performance", "test performance"},
400 };
401 for (size_t i = 0; i < sizeof(infos) / sizeof(infos[0]); i++) {
402 BShellEnvRegisterCmd(GetShellHandle(), &infos[i]);
403 }
404 }
405 return 0;
406 }
407