From 4aff3d121162e1be9d3b13095abd4f0a608efcfb Mon Sep 17 00:00:00 2001 From: kuangyufei Date: Wed, 11 Oct 2023 10:11:18 +0800 Subject: [PATCH] =?UTF-8?q?=20=E5=90=8C=E6=AD=A5=E5=AE=98=E6=96=B9?= =?UTF-8?q?=E6=BA=90=E7=A0=81=EF=BC=8C=E5=AE=98=E6=96=B9=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E5=BE=88=E5=B0=91=20=20=20=20=20=E9=B8=BF=E8=92=99=E7=A0=94?= =?UTF-8?q?=E7=A9=B6=E7=AB=99=20|=20http://weharmonyos.com=20(=E5=9B=BD?= =?UTF-8?q?=E5=86=85)=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20|=20http?= =?UTF-8?q?s://weharmony.github.io=20(=E5=9B=BD=E5=A4=96)=20=20=20=20=20?= =?UTF-8?q?=E8=AE=BA=E5=9D=9B=20|=20http://bbs.weharmonyos.com=20=20=20=20?= =?UTF-8?q?=20=E6=96=87=E6=A1=A3=E4=B8=AD=E5=BF=83=20|=20http://open.wehar?= =?UTF-8?q?monyos.com=20=20=20=20=20=E5=8F=82=E8=80=83=E6=89=8B=E5=86=8C?= =?UTF-8?q?=20|=20http://doxygen.weharmonyos.com?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 +- donate.md | 8 +- fs/jffs2/src/vfs_jffs2.c | 8 +- kernel/base/core/los_swtmr.c | 2 +- kernel/extended/plimit/los_devicelimit.c | 26 +- syscall/ipc_syscall.c | 9 +- testsuites/unittest/BUILD.gn | 2 + .../libc/time/timer/time_timer_test.cpp | 20 - testsuites/unittest/tools/BUILD.gn | 38 ++ testsuites/unittest/tools/README.md | 63 +++ testsuites/unittest/tools/unittest_tools.cpp | 468 ++++++++++++++++++ zzz/git/push.sh | 2 +- 12 files changed, 608 insertions(+), 44 deletions(-) create mode 100644 testsuites/unittest/tools/BUILD.gn create mode 100644 testsuites/unittest/tools/README.md create mode 100644 testsuites/unittest/tools/unittest_tools.cpp diff --git a/README.md b/README.md index 6327692e..5920cdd4 100644 --- a/README.md +++ b/README.md @@ -202,6 +202,7 @@ ### 四大码仓发布 | 源码同步官方 内核注解同时在 [gitee](https://gitee.com/weharmony/kernel_liteos_a_note) | [github](https://github.com/kuangyufei/kernel_liteos_a_note) | [coding](https://weharmony.coding.net/public/harmony/kernel_liteos_a_note/git/files) | [gitcode](https://gitcode.net/kuangyufei/kernel_liteos_a_note) 发布,并与官方源码按月保持同步,同步历史如下: +* `2023/10/11` -- 同步官方源码,近五个月官方很少更新 * `2023/05/26` -- 同步官方源码,BUILD.gn 相关 * `2023/04/10` -- 调度算法优化,加入deadline * `2023/03/01` -- 增加网络容器和容器限额功能 @@ -287,7 +288,6 @@ * 左侧导航栏,右边索引区 ![](https://weharmonyos.oss-cn-hangzhou.aliyuncs.com/resources/52/4.png) -### 关注不迷路 | 代码即人生 +### 捐助名单 | 联系作者 -![](https://weharmonyos.oss-cn-hangzhou.aliyuncs.com/resources/common/so1so.png) -据说喜欢 **点赞 + 分享** 的,后来都成了大神。:) [ >> 查看捐助名单](./donate.md) +* [ >> 历史捐助](./donate.md) diff --git a/donate.md b/donate.md index dcba89a7..0e18ee9e 100644 --- a/donate.md +++ b/donate.md @@ -1,4 +1,4 @@ - ### 温暖记录 + ### 捐赠记录 @@ -17,11 +17,11 @@ + -### 捐助方式 +### 谢谢支持 - - + diff --git a/fs/jffs2/src/vfs_jffs2.c b/fs/jffs2/src/vfs_jffs2.c index 81333ecb..e0be7dd3 100644 --- a/fs/jffs2/src/vfs_jffs2.c +++ b/fs/jffs2/src/vfs_jffs2.c @@ -567,14 +567,14 @@ off_t VfsJffs2Seek(struct file *filep, off_t offset, int whence) filePos = filep->f_pos; switch (whence) { - case SEEK_SET: - filePos = offset; - break; - case SEEK_CUR: filePos += offset; break; + case SEEK_SET: + filePos = offset; + break; + case SEEK_END: filePos = node->i_size + offset; break; diff --git a/kernel/base/core/los_swtmr.c b/kernel/base/core/los_swtmr.c index 7af9149c..72c3662d 100644 --- a/kernel/base/core/los_swtmr.c +++ b/kernel/base/core/los_swtmr.c @@ -650,7 +650,7 @@ STATIC INLINE BOOL SwtmrRunqueueFind(SortLinkAttribute *swtmrSortLink, SCHED_TL_ STATIC BOOL SwtmrTimeListFind(SCHED_TL_FIND_FUNC checkFunc, UINTPTR arg) { for (UINT16 cpuid = 0; cpuid < LOSCFG_KERNEL_CORE_NUM; cpuid++) { - SortLinkAttribute *swtmrSortLink = &g_swtmrRunqueue[ArchCurrCpuid()].swtmrSortLink; + SortLinkAttribute *swtmrSortLink = &g_swtmrRunqueue[cpuid].swtmrSortLink; if (SwtmrRunqueueFind(swtmrSortLink, checkFunc, arg)) { return TRUE; } diff --git a/kernel/extended/plimit/los_devicelimit.c b/kernel/extended/plimit/los_devicelimit.c index a4a6446e..2cebaa3b 100644 --- a/kernel/extended/plimit/los_devicelimit.c +++ b/kernel/extended/plimit/los_devicelimit.c @@ -485,29 +485,35 @@ UINT32 OsDevLimitWriteDeny(ProcLimitSet *plimit, const CHAR *buf, UINT32 size) return DevLimitUpdateAccess(plimit, buf, DEVLIMIT_DENY); } -STATIC VOID DevLimitItemSetAccess(CHAR *acc, INT16 access) +STATIC VOID DevLimitItemSetAccess(CHAR *accArray, INT16 access) { INT32 index = 0; (VOID)memset_s(acc, ACCLEN, 0, ACCLEN); if (access & DEVLIMIT_ACC_READ) { - acc[index++] = 'r'; + accArray[index] = 'r'; + index++; } if (access & DEVLIMIT_ACC_WRITE) { - acc[index++] = 'w'; + accArray[index] = 'w'; + index++; } if (access & DEVLIMIT_ACC_MKNOD) { - acc[index++] = 'm'; + accArray[index] = 'm'; + index++; } } STATIC CHAR DevLimitItemTypeToChar(INT16 type) { - if (type == DEVLIMIT_DEV_ALL) { - return 'a'; - } else if (type == DEVLIMIT_DEV_CHAR) { - return 'c'; - } else if (type == DEVLIMIT_DEV_BLOCK) { - return 'b'; + switch (type) { + case DEVLIMIT_DEV_ALL: + return 'a'; + case DEVLIMIT_DEV_CHAR: + return 'c'; + case DEVLIMIT_DEV_BLOCK: + return 'b'; + default: + break; } return 'X'; } diff --git a/syscall/ipc_syscall.c b/syscall/ipc_syscall.c index 77b12f64..2ed7d2a5 100644 --- a/syscall/ipc_syscall.c +++ b/syscall/ipc_syscall.c @@ -116,12 +116,19 @@ int SysMqClose(mqd_t personal) FreeProcessFd(ufd); return ret; } + int SysMqNotify(mqd_t personal, const struct sigevent *sigev) { int ret; + struct sigevent ksigev; + + ret = LOS_ArchCopyFromUser(&ksigev, sigev, sizeof(struct sigevent)); + if (ret != 0) { + return -EFAULT; + } MQUEUE_FD_U2K(personal); - ret = OsMqNotify(personal, sigev); + ret = OsMqNotify(personal, &ksigev); if (ret < 0) { return -get_errno(); } diff --git a/testsuites/unittest/BUILD.gn b/testsuites/unittest/BUILD.gn index 0bfbaf78..b1ebb922 100644 --- a/testsuites/unittest/BUILD.gn +++ b/testsuites/unittest/BUILD.gn @@ -67,6 +67,8 @@ config("public_config_for_pressure") { group("unittest") { deps = [] if (ohos_build_type == "debug") { + deps += [ "tools:liteos_unittest_run" ] + # basic test if (LOSCFG_USER_TEST_BASIC == true) { if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_LOW) { diff --git a/testsuites/unittest/libc/time/timer/time_timer_test.cpp b/testsuites/unittest/libc/time/timer/time_timer_test.cpp index 4371de0a..d859b046 100644 --- a/testsuites/unittest/libc/time/timer/time_timer_test.cpp +++ b/testsuites/unittest/libc/time/timer/time_timer_test.cpp @@ -53,26 +53,6 @@ HWTEST_F(TimeTimerTest, TimerTest001, TestSize.Level0) TimerTest001(); } -/* * - * @tc.name: TimerTest002 - * @tc.desc: function for TimeTimerTest - * @tc.type: FUNC - */ -HWTEST_F(TimeTimerTest, TimerTest002, TestSize.Level0) -{ - TimerTest002(); -} - -/* * - * @tc.name: TimerTest003 - * @tc.desc: function for TimeTimerTest - * @tc.type: FUNC - */ -HWTEST_F(TimeTimerTest, TimerTest003, TestSize.Level0) -{ - TimerTest003(); -} - /* * * @tc.name: TimerTest005 * @tc.desc: function for timer_create SIGEV_THREAD. diff --git a/testsuites/unittest/tools/BUILD.gn b/testsuites/unittest/tools/BUILD.gn new file mode 100644 index 00000000..842065d4 --- /dev/null +++ b/testsuites/unittest/tools/BUILD.gn @@ -0,0 +1,38 @@ +# Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this list of +# conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, this list +# of conditions and the following disclaimer in the documentation and/or other materials +# provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors may be used +# to endorse or promote products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import("//build/lite/config/test.gni") +import("//kernel/liteos_a/liteos.gni") +import("//kernel/liteos_a/testsuites/unittest/config.gni") + +unittest("liteos_unittest_run") { + output_extension = "bin" + output_dir = "$root_out_dir/test/unittest/kernel" + sources = [ "unittest_tools.cpp" ] + deps = [ "$THIRDPARTY_BOUNDS_CHECKING_FUNCTION_DIR:libsec_shared" ] +} diff --git a/testsuites/unittest/tools/README.md b/testsuites/unittest/tools/README.md new file mode 100644 index 00000000..a3cd21ae --- /dev/null +++ b/testsuites/unittest/tools/README.md @@ -0,0 +1,63 @@ +# LiteOS Unittest tools + +## 介绍 + +可执行程序 ***liteos_unittest_run.bin*** 是为了提升liteos unittest 测试效率的工具。 + +## 使用介绍 + +### 1.使用帮助 + +``` +OHOS # ./liteos_unittest_run.bin --help +Usage: +liteos_unittest_run.bin [testsuites_dir] [options] +options: + -r [1-1000] --- The number of repeated runs of the test program. + -m [smoke/full] --- Run the smoke or full test case in this directory. + -t [case] [args] -t ... --- Runs the specified executable program name. +``` +- testsuites_dir: unittest 用例所在的绝对路径 + +### 2.常见测试场景举例 + +假设单板上单元测试用例位于路径 ***/usr/bin/unittest*** 下。 + +#### 2.1 运行全量用例或smoke用例 + +- smoke命令 +``` +./liteos_unittest_run.bin /usr/bin/unittest -r 10 -m smoke +``` +注: -r 10 表示: smoke用例运行10次, 一般用于压测 + +- 全量命令 +``` +./liteos_unittest_run.bin /usr/bin/unittest -r 10 -m full +``` + +注: -r 10 表示: 全量用例运行10次, 一般用于压测 + +#### 2.2 单或多用例组合运行 + +- 单用例执行命令 +``` +./liteos_unittest_run.bin /usr/bin/unittest -r 10 -t liteos_a_basic_unittest.bin +``` +注: 只运行liteos_a_basic_unittest.bin 用例, 重复10次 + +``` +./liteos_unittest_run.bin /usr/bin/unittest -r 10 -t liteos_a_basic_unittest.bin --gtest_filter=ExcTest.ItTestExc002 +``` +注: 只运行liteos_a_basic_unittest.bin 用例中的ItTestExc002,重复10次 + +- 多用例组合命令 +``` +./liteos_unittest_run.bin /usr/bin/unittest -r 10 -t liteos_a_basic_unittest.bin -t liteos_a_process_basic_pthread_unittest_door.bin +``` +注: 先运行liteos_a_basic_unittest.bin再运行liteos_a_process_basic_pthread_unittest_door.bin, 重复10次。-t 最多5个。 + +``` +./liteos_unittest_run.bin /usr/bin/unittest -r 10 -t liteos_a_basic_unittest.bin --gtest_filter=ExcTest.ItTestExc002 -t liteos_a_process_basic_pthread_unittest_door.bin --gtest_filter=ProcessPthreadTest.ItTestPthread003 +``` +注:先运行liteos_a_basic_unittest.bin的ItTestExc002,再运行liteos_a_process_basic_pthread_unittest_door.bin的ItTestPthread003,重复10次。-t最多5个。 diff --git a/testsuites/unittest/tools/unittest_tools.cpp b/testsuites/unittest/tools/unittest_tools.cpp new file mode 100644 index 00000000..79ba1fe0 --- /dev/null +++ b/testsuites/unittest/tools/unittest_tools.cpp @@ -0,0 +1,468 @@ +/* + * Copyright (c) 2023-2023 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +const static int TEST_PATH_MAX = 255; +const static int TEST_PARAM_NUM = 5; +const static int TEST_CASE_MODE_FULL = 0; +const static int TEST_CASE_MODE_SMOKE = 1; +const static int TEST_DEFAULT_CASE_MAX = 5; +const static int TEST_T_PARAM_LEN = 2; +const static unsigned int TEST_CASE_FLAGS_ALL = 1; +const static unsigned int TEST_CASE_FLAGS_SPECIFY = 2; +const static unsigned int TEST_CASE_FAILED_COUNT_MAX = 500; +static unsigned int g_testsuitesCount = 0; +static unsigned int g_testsuitesFailedCount = 0; + +struct TestCase { + char bin[TEST_PATH_MAX]; + char *param[TEST_PARAM_NUM]; + int caseLen; +}; + +struct TestsuitesParam { + char testsuitesBin[TEST_PATH_MAX]; + char testsuitesDir[TEST_PATH_MAX]; + int testsuitesDirLen; + struct TestCase *testCase[TEST_DEFAULT_CASE_MAX]; + int testCaseNum; + int testMode; + int repeat; +}; + +static struct TestsuitesParam g_param; +static char *g_testsuitesFailedCase[TEST_CASE_FAILED_COUNT_MAX]; + +static vector GetAllTestsuites(string testsuitesDir) +{ + vector vFiles; + int suffixLen = strlen(".bin"); + DIR *dir = opendir(testsuitesDir.c_str()); + if (dir == nullptr) { + cout << "opendir " << testsuitesDir << " failed" << endl; + return vFiles; + } + + do { + struct dirent *pDir = readdir(dir); + if (pDir == nullptr) { + break; + } + + if ((strcmp(pDir->d_name, ".") == 0) || (strcmp(pDir->d_name, "..") == 0)) { + continue; + } + + if (pDir->d_type == DT_REG) { + int pathLen = strlen(pDir->d_name); + if (pathLen <= suffixLen) { + continue; + } + if (strcmp(".bin", (char *)(pDir->d_name + (pathLen - suffixLen))) != 0) { + continue; + } + + vFiles.push_back(testsuitesDir + "/" + pDir->d_name); + } + } while (1); + closedir(dir); + return vFiles; +} + +static bool TestsuitesIsSmoke(string testsuite, int fileLen, string smokeTest, int smokeTestLen) +{ + if (fileLen <= smokeTestLen) { + return false; + } + + if (strcmp(smokeTest.c_str(), (char *)(testsuite.c_str() + (fileLen - smokeTestLen))) == 0) { + return true; + } + return false; +} + +static void RunCase(const char *testCase, char *param[]) +{ + int ret; + int size; + int status = 0; + pid_t pid = fork(); + if (pid < 0) { + cout << "fork failed, " << strerror(errno) << endl; + return; + } + + g_testsuitesCount++; + if (pid == 0) { + cout << testCase << ":" << endl; + ret = execve(param[0], param, nullptr); + if (ret != 0) { + cout << "execl: " << testCase << " failed, " << strerror(errno) << endl; + exit(0); + } + } + + ret = waitpid(pid, &status, 0); + if (ret != pid) { + cout << "waitpid failed, " << strerror(errno) << endl; + return; + } + + if (WEXITSTATUS(status) == 0) { + return; + } + + if (g_testsuitesFailedCount >= TEST_CASE_FAILED_COUNT_MAX) { + cout << "[UNITTEST_RUN] Failure cases more than upper limit!\n"; + return; + } + + size = strlen(testCase) + 1; + g_testsuitesFailedCase[g_testsuitesFailedCount] = static_cast(malloc(size)); + if (g_testsuitesFailedCase[g_testsuitesFailedCount] == nullptr) { + cout << "[UNITTEST_RUN] malloc failed!\n"; + return; + } + + if (memcpy_s(g_testsuitesFailedCase[g_testsuitesFailedCount], size, testCase, size) != EOK) { + cout << "[UNITTEST_RUN] memcpy failed!\n"; + return; + } + g_testsuitesFailedCount++; +} + +static void RunAllTestCase(vector files, struct TestsuitesParam *param) +{ + const char *testMode = nullptr; + const char *smokeTest = "door.bin"; + const char *unittestRun = g_param.testsuitesBin; + int unittestRunLen = strlen(unittestRun); + int smokeTestLen = strlen(smokeTest); + char *execParam[TEST_PARAM_NUM]; + + if (param->testMode == TEST_CASE_MODE_SMOKE) { + testMode = "door.bin"; + } else { + testMode = ".bin"; + } + + for (size_t i = 0; i < files.size(); i++) { + int fileLen = strlen(files[i].c_str()); + if (fileLen >= unittestRunLen) { + if (strcmp((char *)(files[i].c_str() + (fileLen - unittestRunLen)), unittestRun) == 0) { + continue; + } + } + + if (strcmp(testMode, smokeTest) == 0) { + if (!TestsuitesIsSmoke(files[i], fileLen, smokeTest, smokeTestLen)) { + continue; + } + } else { + if (TestsuitesIsSmoke(files[i], fileLen, smokeTest, smokeTestLen)) { + continue; + } + } + + (void)memset_s(execParam, sizeof(char *) * TEST_PARAM_NUM, 0, sizeof(char *) * TEST_PARAM_NUM); + execParam[0] = (char *)files[i].c_str(); + RunCase(files[i].c_str(), execParam); + } +} + +static void TestsuitesToolsUsage(void) +{ + cout << "Usage: " << endl; + cout << "liteos_unittest_run.bin [testsuites_dir] [options]" << endl; + cout << "options:" << endl; + cout << " -r [1-1000] --- The number of repeated runs of the test program." << endl; + cout << " -m [smoke/full] --- Run the smoke or full test case in this directory." << endl; + cout << " -t [case] [args] -t ... --- Runs the specified executable program name." << endl; +} + +static int TestsuitesDirFormat(char *testDir, int len) +{ + if (memcpy_s(g_param.testsuitesDir, TEST_PATH_MAX, testDir, len + 1) != EOK) { + cout << "testsuites dir: " << strerror(ENAMETOOLONG) << endl; + return -1; + } + + char *end = g_param.testsuitesDir + len; + while ((testDir != end) && (*end == '/')) { + *end = '\0'; + end--; + len--; + } + + g_param.testsuitesDirLen = len; + if (len <= 0) { + return -1; + } + return 0; +} + +static int GetTestsuitesToolsName(const char *argv[]) +{ + const char *testBin = static_cast(argv[0]); + const char *end = testBin + strlen(testBin); + while (*end != '/') { + end--; + } + end++; + + if (memcpy_s(g_param.testsuitesBin, TEST_PATH_MAX, end, strlen(end)) != EOK) { + cout << "testsuites dir: " << strerror(ENAMETOOLONG) << endl; + return -1; + } + return 0; +} + +static int ParseTestCaseAndParam(int argc, const char *argv[], int *index) +{ + int j; + + (*index)++; + if (*index >= argc) { + return -1; + } + + if (g_param.testCaseNum >= TEST_DEFAULT_CASE_MAX) { + return -1; + } + + g_param.testCase[g_param.testCaseNum] = (struct TestCase *)malloc(sizeof(struct TestCase)); + if (g_param.testCase[g_param.testCaseNum] == nullptr) { + cout << "test case " << strerror(ENOMEM) << endl; + return -1; + } + (void)memset_s(g_param.testCase[g_param.testCaseNum], sizeof(struct TestCase), 0, sizeof(struct TestCase)); + struct TestCase *testCase = g_param.testCase[g_param.testCaseNum]; + testCase->caseLen = strlen(argv[*index]); + if (memcpy_s(testCase->bin, TEST_PATH_MAX, argv[*index], testCase->caseLen + 1) != EOK) { + testCase->caseLen = 0; + cout << "test case " << strerror(ENAMETOOLONG) << endl; + return -1; + } + testCase->param[0] = testCase->bin; + (*index)++; + for (j = 1; (j < TEST_PARAM_NUM) && (*index < argc) && (strncmp("-t", argv[*index], TEST_T_PARAM_LEN) != 0); j++) { + testCase->param[j] = (char *)argv[*index]; + (*index)++; + } + g_param.testCaseNum++; + if (((*index) < argc) && (strncmp("-t", argv[*index], TEST_T_PARAM_LEN) == 0)) { + (*index)--; + } + return 0; +} + +static int TestsuitesParamCheck(int argc, const char *argv[]) +{ + int ret; + unsigned int mask = 0; + g_param.testMode = TEST_CASE_MODE_FULL; + g_param.repeat = 1; + ret = TestsuitesDirFormat((char *)argv[1], strlen(argv[1])); + if (ret < 0) { + return -1; + } + + for (int i = 2; i < argc; i++) { /* 2: param index */ + if (strcmp("-m", argv[i]) == 0) { + i++; + if (i >= argc) { + return -1; + } + mask |= TEST_CASE_FLAGS_ALL; + if (strcmp("smoke", argv[i]) == 0) { + g_param.testMode = TEST_CASE_MODE_SMOKE; + } else if (strcmp("full", argv[i]) == 0) { + g_param.testMode = TEST_CASE_MODE_FULL; + } else { + return -1; + } + } else if (strcmp("-t", argv[i]) == 0) { + mask |= TEST_CASE_FLAGS_SPECIFY; + ret = ParseTestCaseAndParam(argc, argv, &i); + if (ret < 0) { + return ret; + } + } else if (strcmp("-r", argv[i]) == 0) { + i++; + if (i >= argc) { + return -1; + } + g_param.repeat = atoi(argv[i]); + if ((g_param.repeat <= 0) || (g_param.repeat > 1000)) { /* 1000: repeat limit */ + return -1; + } + } + } + + if (((mask & TEST_CASE_FLAGS_ALL) != 0) && ((mask & TEST_CASE_FLAGS_SPECIFY) != 0)) { + cout << "Invalid parameter combination" << endl; + return -1; + } + return 0; +} + +static void IsCase(vector files, struct TestCase *testCase) +{ + for (size_t i = 0; i < files.size(); i++) { + string file = files[i]; + int fileLen = strlen(file.c_str()); + if (fileLen <= testCase->caseLen) { + continue; + } + + const string &suffix = file.c_str() + (fileLen - testCase->caseLen); + if (strcmp(suffix.c_str(), testCase->bin) != 0) { + continue; + } + + if (memcpy_s(testCase->bin, TEST_PATH_MAX, file.c_str(), fileLen + 1) != EOK) { + testCase->caseLen = 0; + return; + } + testCase->caseLen = fileLen; + g_param.testCaseNum++; + return; + } + cout << "liteos_unittest_run.bin: not find test case: " << testCase->bin << endl; + return; +} + +static int FindTestCase(vector files) +{ + int count = g_param.testCaseNum; + g_param.testCaseNum = 0; + + for (int i = 0; i < count; i++) { + IsCase(files, g_param.testCase[i]); + } + + if (g_param.testCaseNum == 0) { + cout << "Not find test case !" << endl; + return -1; + } + return 0; +} + +static void FreeTestCaseMem(void) +{ + for (int index = 0; index < g_param.testCaseNum; index++) { + free(g_param.testCase[index]); + g_param.testCase[index] = nullptr; + } +} + +static void ShowTestLog(int count) +{ + cout << "[UNITTEST_RUN] Repeats: " << count << " Succeed count: " + << g_testsuitesCount - g_testsuitesFailedCount + << " Failed count: " << g_testsuitesFailedCount << endl; + + if (g_testsuitesFailedCount == 0) { + return; + } + cout << "[UNITTEST_RUN] Failed testcase: " << endl; + for (int i = 0; i < g_testsuitesFailedCount; i++) { + cout << "[" << i << "] -> " << g_testsuitesFailedCase[i] << endl; + free(g_testsuitesFailedCase[i]); + g_testsuitesFailedCase[i] = nullptr; + } +} + +int main(int argc, const char *argv[]) +{ + int ret; + int count = 0; + + if ((argc < 2) || (argv == nullptr)) { /* 2: param index */ + cout << argv[0] << ": " << strerror(EINVAL) << endl; + return -1; + } + + if ((strcmp("--h", argv[1]) == 0) || (strcmp("--help", argv[1]) == 0)) { + TestsuitesToolsUsage(); + return 0; + } + + (void)memset_s(&g_param, sizeof(struct TestsuitesParam), 0, sizeof(struct TestsuitesParam)); + + ret = GetTestsuitesToolsName(argv); + if (ret < 0) { + return -1; + } + + ret = TestsuitesParamCheck(argc, argv); + if (ret < 0) { + cout << strerror(EINVAL) << endl; + FreeTestCaseMem(); + return -1; + } + + vector files = GetAllTestsuites(g_param.testsuitesDir); + + if (g_param.testCaseNum != 0) { + ret = FindTestCase(files); + if (ret < 0) { + files.clear(); + FreeTestCaseMem(); + return -1; + } + } + + while (count < g_param.repeat) { + if (g_param.testCaseNum == 0) { + RunAllTestCase(files, &g_param); + } else { + for (int index = 0; index < g_param.testCaseNum; index++) { + RunCase(g_param.testCase[index]->bin, g_param.testCase[index]->param); + } + } + count++; + } + files.clear(); + FreeTestCaseMem(); + ShowTestLog(count); + return 0; +} diff --git a/zzz/git/push.sh b/zzz/git/push.sh index c13bda72..f803801a 100644 --- a/zzz/git/push.sh +++ b/zzz/git/push.sh @@ -1,5 +1,5 @@ git add -A -git commit -m ' 容器模块迁移,由base --> extended +git commit -m ' 同步官方源码,官方更新很少 鸿蒙研究站 | http://weharmonyos.com (国内) | https://weharmony.github.io (国外) 论坛 | http://bbs.weharmonyos.com -- GitLab