• 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 #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