1 /*
2  * Copyright (c) 2022 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 "random_test_flow.h"
17 
18 #include <string>
19 #include <regex>
20 
21 #include "report.h"
22 #include "wukong_define.h"
23 #include "ability_manager_client.h"
24 #include "component_manager.h"
25 #include "accessibility_ui_test_ability.h"
26 
27 namespace OHOS {
28 namespace WuKong {
29 namespace {
30 const std::string RANDOM_TEST_HELP_MSG =
31     "usage: wukong exec [<arguments>]\n"
32     "These are wukong exec arguments list:\n"
33     "   -h, --help                 random test help\n"
34     "   -a, --appswitch            appswitch event percent\n"
35     "   -b, --bundle               the bundle name of allowlist\n"
36     "   -p, --prohibit             the bundle name of blocklist\n"
37     "   -d, --page                 block page list\n"
38     "   -t, --touch                touch event percent\n"
39     "   -c, --count                test count\n"
40     "   -i, --interval             interval\n"
41     "   -s, --seed                 random seed\n"
42     "   -m, --mouse                mouse event percent\n"
43     "   -k, --keyboard             keyboard event percent\n"
44     "   -H, --hardkey              hardkey event percent\n"
45     "   -S, --swap                 swap event percent\n"
46     "   -T, --time                 test time\n"
47     "   -C, --component            component event percent\n"
48     "   -r, --rotate               rotate event percent\n"
49     "   -e, --allow ability        the ability name of allowlist\n"
50     "   -E, --block ability        the ability name of blocklist\n"
51     "   -Y, --blockCompId          the id list of block component\n"
52     "   -y, --blockCompType        the type list of block component\n"
53     "   -I, --screenshot           get screenshot(only in random input)\n"
54     "   -B, --checkBWScreen        black and white screen detection\n"
55     "   -U, --Uri                  set Uri pages\n"
56     "   -x, --Uri-type             set Uri-type \n";
57 
58 const std::string SHORT_OPTIONS = "a:b:c:d:e:E:hIBi:k:p:s:t:T:H:m:S:C:r:Y:y:U:x:";
59 const struct option LONG_OPTIONS[] = {
60     {"help", no_argument, nullptr, 'h'},             // help
61     {"seed", required_argument, nullptr, 's'},       // test seed
62     {"time", required_argument, nullptr, 'T'},       // test time
63     {"count", required_argument, nullptr, 'c'},      // test count
64     {"interval", required_argument, nullptr, 'i'},   // test interval
65     {"bundle", required_argument, nullptr, 'b'},     // test haps
66     {"appswitch", required_argument, nullptr, 'a'},  // switch app percent
67     {"keyboard", required_argument, nullptr, 'k'},   // keyboard percent
68     {"mouse", required_argument, nullptr, 'm'},      // mouse percent
69     {"touch", required_argument, nullptr, 't'},      // touch percent
70     {"swap", required_argument, nullptr, 'S'},       // swap percent
71     {"hardkey", required_argument, nullptr, 'H'},    // hardkey percent
72     {"prohibit", required_argument, nullptr, 'p'},   // prohibit
73     {"component", required_argument, nullptr, 'C'},  // prohibit
74     {"rotate", required_argument, nullptr, 'r'},     // rotate percent
75     {"page", required_argument, nullptr, 'd'},       // block page
76     {"allow ability", required_argument, nullptr, 'e'},
77     {"block ability", required_argument, nullptr, 'E'},
78     {"blockCompId", required_argument, nullptr, 'Y'},
79     {"blockCompType", required_argument, nullptr, 'y'},
80     {"screenshot", no_argument, nullptr, 'I'},
81     {"checkBWScreen", no_argument, nullptr, 'B'},
82     {"Uri", required_argument, nullptr, 'U'},
83     {"Uri-type", required_argument, nullptr, 'x'},
84 };
85 
86 /**
87  * WuKong default input action percent.
88  */
89 const vector<int> DEFAULT_INPUT_PERCENT = {
90     10,  // INPUTTYPE_TOUCHINPUT,      input touch event
91     3,   // INPUTTYPE_SWAPINPUT,       input swap event
92     1,   // INPUTTYPE_MOUSEINPUT,      input mouse event
93     2,   // INPUTTYPE_KEYBOARDINPUT,   input keyboard event
94     70,  // INPUTTYPE_ELEMENTINPUT,    input element event
95     10,  // INPUTTYPE_APPSWITCHINPUT,  input appswitch event
96     2,   // INPUTTYPE_HARDKEYINPUT,    input hardkey event
97     2    // INPUTTYPE_ROTATE,          input rotate event
98 };
99 
100 const map<int, InputType> OPTION_INPUT_PERCENT = {
101     {'a', INPUTTYPE_APPSWITCHINPUT},  // input appswitch event
102     {'C', INPUTTYPE_ELEMENTINPUT},    // input element event
103     {'k', INPUTTYPE_KEYBOARDINPUT},   // input keyboard event
104     {'S', INPUTTYPE_SWAPINPUT},       // input swap event
105     {'m', INPUTTYPE_MOUSEINPUT},      // input mouse event
106     {'t', INPUTTYPE_TOUCHINPUT},      // input touch event
107     {'H', INPUTTYPE_HARDKEYINPUT},    // input hardkey event
108     {'r', INPUTTYPE_ROTATEINPUT}      // input rotate event
109 };
110 
111 /**
112  * @brief Wukong block page
113  */
114 std::vector<std::string> systemPaths;
115 
116 const int ONE_HUNDRED_PERCENT = 100;
117 // one minute (ms)
118 const int ONE_MINUTE = 60000;
119 // rotate
120 const int ROTATE = 114;
121 bool g_commandSEEDENABLE = false;
122 bool g_commandHELPENABLE = false;
123 bool g_commandTIMEENABLE = false;
124 bool g_commandCOUNTENABLE = false;
125 bool g_isAppStarted = false;
126 bool g_commandALLOWABILITYENABLE = false;
127 bool g_commandBLOCKABILITYENABLE = false;
128 bool g_commandALLOWBUNDLEENABLE = false;
129 bool g_commandSCREENSHOTENABLE = false;
130 bool g_commandCHECKBWSCREEN = false;
131 bool g_commandURIENABLE = false;
132 bool g_commandURITYPEENABLE = false;
133 
134 // default false
135 bool g_commandUITEST = false;
136 }  // namespace
137 using namespace std;
138 
RandomTestFlow(WuKongShellCommand &shellcommand)139 RandomTestFlow::RandomTestFlow(WuKongShellCommand &shellcommand)
140     : TestFlow(shellcommand),
141       inputPercent_(INPUTTYPE_INVALIDINPUT, 0)
142 {
143 }
144 
~RandomTestFlow()145 RandomTestFlow::~RandomTestFlow()
146 {
147     if (timer_ != nullptr) {
148         timer_->Shutdown();
149         timer_->Unregister(timerId_);
150         timer_ = nullptr;
151     }
152 }
153 
InitEventPercent()154 ErrCode RandomTestFlow::InitEventPercent()
155 {
156     int sumPercent = 0;
157     int sumLastDefaultPercent = ONE_HUNDRED_PERCENT;
158     vector<int> lastDefaultPercent = DEFAULT_INPUT_PERCENT;
159     for (auto input : inputPercent_) {
160         TRACK_LOG_STR("input: (%02d)", input);
161     }
162     for (int type = 0; type < INPUTTYPE_INVALIDINPUT; type++) {
163         // add type to count input list for random algorithm.
164         for (int index = 0; index < inputPercent_[type]; index++) {
165             eventList_.push_back(type);
166         }
167         // check argument percent, and set last default percent.
168         if (inputPercent_[type] > 0) {
169             sumLastDefaultPercent -= lastDefaultPercent[type];
170             lastDefaultPercent[type] = 0;
171         }
172         sumPercent += inputPercent_[type];
173     }
174     TRACK_LOG_STR("sumPercent: %d", sumPercent);
175     // check the sum percent more than 100%, and exit wukong.
176     if (sumPercent > ONE_HUNDRED_PERCENT) {
177         shellcommand_.ResultReceiverAppend("all event percentage more than 1, please reset params.\n");
178         shellcommand_.ResultReceiverAppend(RANDOM_TEST_HELP_MSG);
179         return OHOS::ERR_INVALID_VALUE;
180     }
181 
182     // sum the last default percent for calculate last percent.
183     int lastPercent = ONE_HUNDRED_PERCENT - sumPercent;
184     int lastInputPercent = 0;
185     for (int type = 0; type < INPUTTYPE_INVALIDINPUT; type++) {
186         if (lastDefaultPercent[type] <= 0 || lastDefaultPercent[type] > ONE_HUNDRED_PERCENT ||
187             sumLastDefaultPercent <= 0) {
188             continue;
189         }
190         lastInputPercent = (int)(lastPercent * ((float)(lastDefaultPercent[type]) / sumLastDefaultPercent));
191         // add type to count input list for random algorithm.
192         for (int index = 0; index < lastInputPercent; index++) {
193             eventList_.push_back(type);
194         }
195         sumPercent += lastInputPercent;
196     }
197 
198     // if the sumPercent less than 100%, add INPUTTYPE_TOUCHINPUT to random algorithm.
199     for (int index = 0; index < ONE_HUNDRED_PERCENT - sumPercent; index++) {
200         eventList_.push_back(INPUTTYPE_TOUCHINPUT);
201     }
202 
203     return OHOS::ERR_OK;
204 }
205 
EnvInit()206 ErrCode RandomTestFlow::EnvInit()
207 {
208     // init event list percent.
209     ErrCode result = InitEventPercent();
210     if (result != OHOS::ERR_OK) {
211         return result;
212     }
213 
214     // init srand and print seed information.
215     if (g_commandSEEDENABLE) {
216         srand(seedArgs_);
217     } else {
218         time_t tempSeed = time(nullptr);
219         srand((unsigned int)tempSeed);
220         seedArgs_ = (int)time(nullptr);
221     }
222     Report::GetInstance()->SetSeed(std::to_string(seedArgs_));
223     TEST_RUN_LOG(("Seed: " + std::to_string(seedArgs_)).c_str());
224 
225     // shuffle the event list.
226     RandomShuffle();
227 
228     // if time test flow, register timer.
229     if (g_commandTIMEENABLE) {
230         RegisterTimer();
231     }
232     return result;
233 }
234 
SetInputPercent(const int option)235 ErrCode RandomTestFlow::SetInputPercent(const int option)
236 {
237     InputType inputType = INPUTTYPE_INVALIDINPUT;
238     auto it = OPTION_INPUT_PERCENT.find(option);
239     if (it == OPTION_INPUT_PERCENT.end()) {
240         return OHOS::ERR_INVALID_VALUE;
241     }
242 
243     inputType = it->second;
244     float percent = 0.0;
245     try {
246         percent = std::stof(optarg);
247         if ((it->first) == ROTATE && percent == 1) {
248             g_isAppStarted = true;
249         }
250     } catch (const std::exception &e) {
251         // try the option argument string convert float.
252         shellcommand_.ResultReceiverAppend("error: option '");
253         shellcommand_.ResultReceiverAppend(string((char *)(&option)));
254         shellcommand_.ResultReceiverAppend("' requires a value.\n");
255         shellcommand_.ResultReceiverAppend(RANDOM_TEST_HELP_MSG);
256         return OHOS::ERR_INVALID_VALUE;
257     }
258     // check valid of the option argument
259     if (percent > 1 || percent < 0) {
260         shellcommand_.ResultReceiverAppend("the input percent more than 1 (100%).\n");
261         shellcommand_.ResultReceiverAppend(RANDOM_TEST_HELP_MSG);
262         return OHOS::ERR_INVALID_VALUE;
263     }
264 
265     // convert float to int (0 ~ 100)
266     inputPercent_[inputType] = (int)(percent * ONE_HUNDRED_PERCENT);
267     return OHOS::ERR_OK;
268 }
269 
SetBlackWhiteSheet(const int option)270 ErrCode RandomTestFlow::SetBlackWhiteSheet(const int option)
271 {
272     ErrCode result = OHOS::ERR_OK;
273     if (option == 'b') {
274         result = WuKongUtil::GetInstance()->SetAllowList(optarg);
275         g_commandALLOWBUNDLEENABLE = true;
276     } else if (option == 'p') {
277         result = WuKongUtil::GetInstance()->SetBlockList(optarg);
278     } else if (option == 'e') {
279         result = WuKongUtil::GetInstance()->SetAllowAbilityList(optarg);
280         if (result != OHOS::ERR_INVALID_VALUE) {
281             result = CheckArgument(option);
282         }
283     } else if (option == 'E') {
284         result = WuKongUtil::GetInstance()->SetBlockAbilityList(optarg);
285         if (result != OHOS::ERR_INVALID_VALUE) {
286             result = CheckArgument(option);
287         }
288     } else if (option == 'd') {
289         result = WuKongUtil::GetInstance()->SetBlockPageList(optarg);
290     } else if (option == 'Y') {
291         WuKongUtil::GetInstance()->SetCompIdBlockList(optarg);
292     } else if (option == 'y') {
293         WuKongUtil::GetInstance()->SetCompTypeBlockList(optarg);
294     } else if (option == 'U') {
295         WuKongUtil::GetInstance()->SetComponentUri(optarg);
296         g_commandURIENABLE = true;
297     } else if (option == 'x') {
298         WuKongUtil::GetInstance()->SetComponentUriType(optarg);
299         g_commandURITYPEENABLE = true;
300     }
301     return OHOS::ERR_OK;
302 }
303 
SetRunningParam(const int option)304 ErrCode RandomTestFlow::SetRunningParam(const int option)
305 {
306     ErrCode result = OHOS::ERR_OK;
307     if (option == 'c' || option == 'T') {
308         result = CheckArgument(option);
309     } else if (option == 'i') {
310         std::regex pattern("[0-9]+");
311         if (std::regex_match(optarg, pattern)) {
312             intervalArgs_ = std::stoi(optarg);
313             TEST_RUN_LOG(("Interval: " + std::to_string(intervalArgs_)).c_str());
314         } else {
315             ERROR_LOG("Setting -i must follow an integer");
316             result = OHOS::ERR_INVALID_VALUE;
317         }
318     } else if (option == 's') {
319         seedArgs_ = std::stoi(optarg);
320         g_commandSEEDENABLE = true;
321     }
322     return result;
323 }
324 
SetRunningIndicator(const int option)325 ErrCode RandomTestFlow::SetRunningIndicator(const int option)
326 {
327     ErrCode result = OHOS::ERR_OK;
328     if (option == 'h') {
329         shellcommand_.ResultReceiverAppend(RANDOM_TEST_HELP_MSG);
330         result = OHOS::ERR_NO_INIT;
331         g_commandHELPENABLE = true;
332     } else if (option == 'I') {
333         g_commandSCREENSHOTENABLE = true;
334     } else if (option == 'B') {
335         g_commandSCREENSHOTENABLE = true;
336         g_commandCHECKBWSCREEN = true;
337     }
338     return OHOS::ERR_OK;
339 }
340 
InputScene(std::shared_ptr<InputAction> inputaction, bool inputFlag)341 ErrCode RandomTestFlow::InputScene(std::shared_ptr<InputAction> inputaction, bool inputFlag)
342 {
343     ErrCode result = OHOS::ERR_OK;
344     if (inputFlag) {
345         if (g_commandURIENABLE && inputaction->GetInputInfo() == INPUTTYPE_APPSWITCHINPUT) {
346             if (g_commandURITYPEENABLE) {
347                 std::string uri = WuKongUtil::GetInstance()->GetComponentUri();
348                 std::string uriType = WuKongUtil::GetInstance()->GetComponentUriType();
349                 result = inputaction->RandomInput(uri, uriType);
350             } else if (g_commandALLOWABILITYENABLE) {
351                 std::string uri = WuKongUtil::GetInstance()->GetComponentUri();
352                 std::vector<std::string> abilityList;
353                 WuKongUtil::GetInstance()->GetAllowAbilityList(abilityList);
354                 result = inputaction->RandomInput(uri, abilityList);
355             }
356         } else {
357             result = inputaction->RandomInput();
358         }
359     } else {
360         ComponentManager::GetInstance()->BackToPrePage();
361     }
362     return result;
363 }
364 
SetBlockPage(const std::vector<std::string> systemPaths)365 bool RandomTestFlow::SetBlockPage(const std::vector<std::string> systemPaths)
366 {
367     auto root = std::make_shared<OHOS::Accessibility::AccessibilityElementInfo>();
368     auto accPtr = OHOS::Accessibility::AccessibilityUITestAbility::GetInstance();
369     // Get root AccessibilityElementInfo from Accessibility
370     accPtr->GetRoot(*(root.get()));
371     std::string path = root->GetPagePath();
372     bool inputFlag = true;
373     TRACK_LOG_STR("Componentpage path: (%s)", path.c_str());
374     for (string systemPath : systemPaths) {
375         if (path.find(systemPath) != string::npos) {
376             INFO_LOG_STR("Block the current page and return. Block page : (%s)", path.c_str());
377             inputFlag = false;
378             break;
379         }
380     }
381     return inputFlag;
382 }
383 
RunStep()384 ErrCode RandomTestFlow::RunStep()
385 {
386     ErrCode result;
387     // control the count test flow
388     if (g_commandCOUNTENABLE == true) {
389         totalCount_--;
390         if (totalCount_ < 0) {
391             isFinished_ = true;
392             return OHOS::ERR_OK;
393         }
394     }
395     if (g_commandSCREENSHOTENABLE) {
396         std::string screenStorePath;
397         result = WuKongUtil::GetInstance()->WukongScreenCap(screenStorePath, g_commandUITEST, g_commandCHECKBWSCREEN);
398         if (result == OHOS::ERR_OK) {
399             Report::GetInstance()->RecordScreenPath(screenStorePath);
400         }
401     }
402     bool inputFlag = SetBlockPage(systemPaths);
403     std::shared_ptr<InputAction> inputaction = nullptr;
404     if (!g_isAppStarted) {
405         inputaction = InputFactory::GetInputAction(INPUTTYPE_APPSWITCHINPUT);
406         if (inputaction == nullptr) {
407             ERROR_LOG("inputaction is nullptr");
408             return OHOS::ERR_INVALID_VALUE;
409         }
410         result = InputScene(inputaction, inputFlag);
411         if (result != OHOS::ERR_OK) {
412             ERROR_LOG("launch app failed and exit");
413             return result;
414         }
415         inputaction = nullptr;
416         g_isAppStarted = true;
417         usleep(intervalArgs_ * oneSecond_);
418     }
419     if (g_commandBLOCKABILITYENABLE == true) {
420         inputFlag = CheckBlockAbility();
421     }
422     // input event, get event index form event list by random algorithm.
423     int eventindex = rand() % ONE_HUNDRED_PERCENT;
424     InputType eventTypeId = (InputType)(eventList_.at(eventindex));
425     inputaction = InputFactory::GetInputAction(eventTypeId);
426     if (inputaction == nullptr) {
427         ERROR_LOG("inputaction is nullptr");
428         return OHOS::ERR_INVALID_VALUE;
429     }
430 
431     if (ProtectRightAbility(inputaction, eventTypeId) == OHOS::ERR_INVALID_VALUE) {
432         return OHOS::ERR_INVALID_VALUE;
433     }
434     result = InputScene(inputaction, inputFlag);
435     usleep(intervalArgs_ * oneSecond_);
436     return result;
437 }
438 
ProtectRightAbility(std::shared_ptr<InputAction> &inputaction, InputType &eventTypeId)439 ErrCode RandomTestFlow::ProtectRightAbility(std::shared_ptr<InputAction> &inputaction, InputType &eventTypeId)
440 {
441     std::vector<std::string> allowList;
442     WuKongUtil::GetInstance()->GetAllowList(allowList);
443     if (allowList.size() > 0 && g_commandALLOWABILITYENABLE == false) {
444         std::string bundleName = "com.ohos.launcher";
445         auto elementName = AAFwk::AbilityManagerClient::GetInstance()->GetTopAbility();
446         if (elementName.GetBundleName() == bundleName) {
447             if (eventTypeId == INPUTTYPE_TOUCHINPUT || eventTypeId == INPUTTYPE_ELEMENTINPUT) {
448                 return OHOS::ERR_INVALID_VALUE;
449             }
450         }
451         // allowList 数量大于0 并且 elementName.GetBundleName() 不在allowList里面,重新拉起一个应用
452         auto curBundleName = elementName.GetBundleName();
453         auto it = find(allowList.begin(), allowList.end(), curBundleName);
454         if (it == allowList.end()) {
455             inputaction = InputFactory::GetInputAction(INPUTTYPE_APPSWITCHINPUT);
456             if (inputaction == nullptr) {
457                 ERROR_LOG("inputaction is nullptr");
458                 return OHOS::ERR_INVALID_VALUE;
459             }
460         }
461     } else if (allowList.size() > 0 && g_commandALLOWABILITYENABLE && !g_commandURIENABLE) {
462         std::vector<std::string> abilityList;
463         WuKongUtil::GetInstance()->GetAllowAbilityList(abilityList);
464         auto elementName = AAFwk::AbilityManagerClient::GetInstance()->GetTopAbility();
465         auto curBundleName = elementName.GetBundleName();
466         auto curAbilityName = elementName.GetAbilityName();
467         TRACK_LOG_STR("curAbilityName : %s", curAbilityName.c_str());
468         auto bundleIndex = find(allowList.begin(), allowList.end(), curBundleName);
469         auto abilityIndex = find(abilityList.begin(), abilityList.end(), curAbilityName);
470         if (bundleIndex == allowList.end() || abilityIndex == abilityList.end()) {
471             int index = rand() % abilityList.size();
472             // start ability through bundle infomation
473             ErrCode result = AppManager::GetInstance()->StartAbilityByBundleInfo(abilityList[index], allowList[0]);
474             // print the result of start event
475             if (result ==OHOS::ERR_OK) {
476                 INFO_LOG_STR("Ability Name : ("%s") startup successful", abilityList[index].c_str());
477             } else {
478                 ERROR_LOG_STR("Ability Name : ("%s") startup failed", abilityList[index].c_str());
479             }
480             TRACK_LOG_STR("ability index : %d", index);
481         }
482         return OHOS::ERR_OK;
483     }
484     return OHOS::ERR_OK;
485 }
486 
HandleNormalOption(const int option)487 ErrCode RandomTestFlow::HandleNormalOption(const int option)
488 {
489     ErrCode result;
490     if (option == 't' || option == 'm' || option == 'S' || option == 'k' || option == 'a' ||
491         option == 'r' || option == 'C' || option == 'H') {
492         result = SetInputPercent(option);
493     } else {
494         result = SetBlackWhiteSheet(option);
495         if (result != OHOS::ERR_OK) {
496             return result;
497         }
498         result = SetRunningParam(option);
499         if (result != OHOS::ERR_OK) {
500             return result;
501         }
502         result = SetRunningIndicator(option);
503     }
504     WuKongUtil::GetInstance()->GetBlockPageList(systemPaths);
505     WuKongUtil::GetInstance()->SetOrderFlag(false);
506     return result;
507 }
508 
CheckArgument(const int option)509 ErrCode RandomTestFlow::CheckArgument(const int option)
510 {
511     ErrCode result = OHOS::ERR_OK;
512     switch (option) {
513         case 'c': {
514             result = CheckArgumentOptionOfc();
515             break;
516         }
517         case 'T': {
518             result = CheckArgumentOptionOfT();
519             break;
520         }
521         case 'e': {
522             result = CheckArgumentOptionOfe();
523             break;
524         }
525         case 'E': {
526             result = CheckArgumentOptionOfE();
527             break;
528         }
529         default: {
530             result = OHOS::ERR_INVALID_VALUE;
531             break;
532         }
533     }
534     return result;
535 }
536 
GetOptionArguments(std::string &shortOpts)537 const struct option *RandomTestFlow::GetOptionArguments(std::string &shortOpts)
538 {
539     shortOpts = SHORT_OPTIONS;
540     return LONG_OPTIONS;
541 }
542 
HandleUnknownOption(const char optopt)543 ErrCode RandomTestFlow::HandleUnknownOption(const char optopt)
544 {
545     ErrCode result = OHOS::ERR_OK;
546     switch (optopt) {
547         case 'a':
548         case 'b':
549         case 'c':
550         case 'd':
551         case 'e':
552         case 'i':
553         case 's':
554         case 't':
555         case 'r':
556         case 'S':
557         case 'p':
558         case 'k':
559         case 'H':
560         case 'T':
561         case 'm':
562         case 'C':
563         case 'E':
564         case 'Y':
565         case 'y':
566         case 'U':
567         case 'x':
568             // error: option 'x' requires a value.
569             shellcommand_.ResultReceiverAppend("error: option '-");
570             shellcommand_.ResultReceiverAppend(string(1, optopt));
571             shellcommand_.ResultReceiverAppend("' requires a value.\n");
572             result = OHOS::ERR_INVALID_VALUE;
573             break;
574         case 'h': {
575             result = OHOS::ERR_INVALID_VALUE;
576             break;
577         }
578         default: {
579             // 'wukong exec' with an unknown option: wukong exec -x
580             shellcommand_.ResultReceiverAppend(
581                 "'wukong exec' with an unknown option, please reference help information:\n");
582             result = OHOS::ERR_INVALID_VALUE;
583             break;
584         }
585     }
586     shellcommand_.ResultReceiverAppend(RANDOM_TEST_HELP_MSG);
587     return result;
588 }
589 
RandomShuffle()590 void RandomTestFlow::RandomShuffle()
591 {
592     for (uint32_t i = eventList_.size() - 1; i > 0; --i) {
593         std::swap(eventList_[i], eventList_[std::rand() % (i + 1)]);
594     }
595 }
596 
RegisterTimer()597 void RandomTestFlow::RegisterTimer()
598 {
599     if (timer_ == nullptr) {
600         timer_ = std::make_shared<Utils::Timer>("wukong");
601         timerId_ = timer_->Register([this] () { RandomTestFlow::TestTimeout(); }, totalTime_ * ONE_MINUTE, true);
602         timer_->Setup();
603     }
604 }
605 
TestTimeout()606 void RandomTestFlow::TestTimeout()
607 {
608     g_commandTIMEENABLE = false;
609     isFinished_ = true;
610 }
611 
CheckArgumentOptionOfe()612 ErrCode RandomTestFlow::CheckArgumentOptionOfe()
613 {
614     if (g_commandALLOWABILITYENABLE == false) {
615         g_commandALLOWABILITYENABLE = true;
616         if (g_commandALLOWBUNDLEENABLE == true) {
617             return OHOS::ERR_OK;
618         } else {
619             ERROR_LOG("invalid param : When -e is configured, -b must be configured.");
620             ERROR_LOG("invalid param : please ensure that the -b is before the -e");
621             return OHOS::ERR_INVALID_VALUE;
622         }
623     } else {
624         ERROR_LOG("invalid param : please check params of '-e'.");
625         return OHOS::ERR_INVALID_VALUE;
626     }
627 }
628 
CheckArgumentOptionOfE()629 ErrCode RandomTestFlow::CheckArgumentOptionOfE()
630 {
631     if (g_commandBLOCKABILITYENABLE == false) {
632         g_commandBLOCKABILITYENABLE = true;
633         if (g_commandALLOWBUNDLEENABLE == true) {
634             return OHOS::ERR_OK;
635         } else {
636             ERROR_LOG("invalid param : When -E is configure, -b must be configured.");
637             ERROR_LOG("invalid param : Plese ensure that the -b is before the -E.");
638             return OHOS::ERR_INVALID_VALUE;
639         }
640     } else {
641         ERROR_LOG("invalid param : please check params of '-E'.");
642         return OHOS::ERR_INVALID_VALUE;
643     }
644 }
645 
CheckArgumentOptionOfc()646 ErrCode RandomTestFlow::CheckArgumentOptionOfc()
647 {
648     // check if the '-c' and 'T' is exist at the same time
649     if (g_commandTIMEENABLE == false) {
650         std::stringstream ss(optarg);
651         if (ss >> countArgs_) {
652             g_commandCOUNTENABLE = true;
653             TEST_RUN_LOG(("Count: " + std::to_string(countArgs_)).c_str());
654             totalCount_ = countArgs_;
655             return OHOS::ERR_OK;
656         } else {
657             ERROR_LOG("Setting -c must follow an interger");
658             return OHOS::ERR_INVALID_VALUE;
659         }
660     } else {
661         DEBUG_LOG(PARAM_COUNT_TIME_ERROR);
662         shellcommand_.ResultReceiverAppend(std::string(PARAM_COUNT_TIME_ERROR) + "\n");
663         return OHOS::ERR_INVALID_VALUE;
664     }
665 }
666 
CheckArgumentOptionOfT()667 ErrCode RandomTestFlow::CheckArgumentOptionOfT()
668 {
669     // check if the '-c' and 'T' is exist at the same time
670     if (g_commandCOUNTENABLE == false) {
671         std::stringstream ss(optarg);
672         if (ss >> totalTime_) {
673             TEST_RUN_LOG(("Time: " + std::to_string(totalTime_)).c_str());
674             g_commandTIMEENABLE = true;
675             return OHOS::ERR_OK;
676         } else {
677             ERROR_LOG("Setting -T must follow a float");
678             return OHOS::ERR_INVALID_VALUE;
679         }
680     } else {
681         DEBUG_LOG(PARAM_TIME_COUNT_ERROR);
682         shellcommand_.ResultReceiverAppend(std::string(PARAM_TIME_COUNT_ERROR) + "\n");
683         return OHOS::ERR_INVALID_VALUE;
684     }
685 }
686 
CheckBlockAbility()687 bool RandomTestFlow::CheckBlockAbility()
688 {
689     bool inputFlag = true;
690     auto elementName = AAFwk::AbilityManagerClient::GetInstance()->GetTopAbility();
691     auto currentAbility = elementName.GetAbilityName();
692     std::vector<string> blockAbilityList;
693     WuKongUtil::GetInstance()->GetBlockAbilityList(blockAbilityList);
694     auto it = find(blockAbilityList.begin(), blockAbilityList.end(), currentAbility);
695     if (it != blockAbilityList.end()) {
696         INFO_LOG_STR("Block the current Ability and return. Block Ability : (%s)", currentAbility.c_str());
697         inputFlag = false;
698     }
699     return inputFlag;
700 }
701 }  // namespace WuKong
702 }  // namespace OHOS
703