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
27namespace OHOS {
28namespace WuKong {
29namespace {
30const 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
58const 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:";
59const 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 */
89const 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
100const 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 */
114std::vector<std::string> systemPaths;
115
116const int ONE_HUNDRED_PERCENT = 100;
117// one minute (ms)
118const int ONE_MINUTE = 60000;
119// rotate
120const int ROTATE = 114;
121bool g_commandSEEDENABLE = false;
122bool g_commandHELPENABLE = false;
123bool g_commandTIMEENABLE = false;
124bool g_commandCOUNTENABLE = false;
125bool g_isAppStarted = false;
126bool g_commandALLOWABILITYENABLE = false;
127bool g_commandBLOCKABILITYENABLE = false;
128bool g_commandALLOWBUNDLEENABLE = false;
129bool g_commandSCREENSHOTENABLE = false;
130bool g_commandCHECKBWSCREEN = false;
131bool g_commandURIENABLE = false;
132bool g_commandURITYPEENABLE = false;
133
134// default false
135bool g_commandUITEST = false;
136}  // namespace
137using namespace std;
138
139RandomTestFlow::RandomTestFlow(WuKongShellCommand &shellcommand)
140    : TestFlow(shellcommand),
141      inputPercent_(INPUTTYPE_INVALIDINPUT, 0)
142{
143}
144
145RandomTestFlow::~RandomTestFlow()
146{
147    if (timer_ != nullptr) {
148        timer_->Shutdown();
149        timer_->Unregister(timerId_);
150        timer_ = nullptr;
151    }
152}
153
154ErrCode 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
206ErrCode 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
235ErrCode 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
270ErrCode 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
304ErrCode 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
325ErrCode 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
341ErrCode 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
365bool 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
384ErrCode 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
439ErrCode 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
487ErrCode 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
509ErrCode 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
537const struct option *RandomTestFlow::GetOptionArguments(std::string &shortOpts)
538{
539    shortOpts = SHORT_OPTIONS;
540    return LONG_OPTIONS;
541}
542
543ErrCode 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
590void 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
597void 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
606void RandomTestFlow::TestTimeout()
607{
608    g_commandTIMEENABLE = false;
609    isFinished_ = true;
610}
611
612ErrCode 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
629ErrCode 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
646ErrCode 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
667ErrCode 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
687bool 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