Compare commits

...

24 Commits

Author SHA1 Message Date
openharmony_ci
e3eaae1b1c !1184 【轻量级 PR】:修改 SortQueueIndexArray 函数笔误
Merge pull request !1184 from brucezhao/N/A
2024-03-26 07:19:04 +00:00
openharmony_ci
9b5892e0a6 !1187 LTS 5.10 补丁升级适配
Merge pull request !1187 from Wanxiaoqing/master
2024-03-14 07:52:29 +00:00
wanxiaoqing
6a4d0be681 LTS 5.10 补丁升级适配
Signed-off-by: wanxiaoqing <wanxiaoqing@huawei.com>
2024-03-13 09:38:42 +08:00
openharmony_ci
8fe4080d08 !1185 删除bundle.json中的syscap信息,确保与架构信息平台设计信息一致
Merge pull request !1185 from hw_llm/master
2024-02-05 07:22:47 +00:00
hw_llm
cfa0209c14 Description: 删除bundle.json中syscap信息
IssueNo: https://gitee.com/openharmony/kernel_liteos_a/issues/I90PKD
Feature Or Bugfix: Feature
Binary Source: No
Signed-off-by: hw_llm <liu.limin@huawei.com>
2024-02-02 15:41:59 +08:00
brucezhao
a235c4c106 修改 SortQueueIndexArray 函数笔误
修改 SortQueueIndexArray 函数 queueSortParam.ipcDebugCBCnt = LOSCFG_BASE_IPC_SEM_LIMIT; 的笔误为 LOSCFG_BASE_IPC_QUEUE_LIMIT

Signed-off-by: brucezhao <bruce.e.zhao@gmail.com>
2023-11-24 07:57:04 +00:00
openharmony_ci
c2cb0435b2 !1182 LTS 5.10 补丁升级适配
Merge pull request !1182 from Ywenrui44091/master
2023-11-20 04:43:43 +00:00
yaowenrui
4fbb41b7d5 LTS 5.10 补丁升级适配
Signed-off-by: yaowenrui <yaowenrui2@huawei.com>
2023-11-16 10:46:44 +08:00
openharmony_ci
04f971084b !1178 fix: /dev/mem 及 /proc/fs_cache 权限漏洞修复
Merge pull request !1178 from yinjiaming/fix
2023-10-16 09:38:00 +00:00
yinjiaming
6daecc8d26 fix: /dev/mem 及 /proc/fs_cache 权限漏洞修复
/dev/mem 和 /proc/fs_cache 存在多余的读写权限,
有被低权限者利用进行攻击的风险,现予以修复。

Signed-off-by: yinjiaming <yinjiaming@huawei.com>
Change-Id: Ie6b537e8cb1de7353dfc357411eba4920a539b4f
2023-10-12 09:52:18 +08:00
openharmony_ci
173cdeb077 !1166 fix: 修复告警
Merge pull request !1166 from Zhaotianyu/20230526fix_codecheck
2023-09-05 13:36:55 +00:00
openharmony_ci
e28271d650 !1174 fix:SysMqNotify系统调用安全增强
Merge pull request !1174 from zhangdengyu/mq_0904
2023-09-04 13:19:17 +00:00
zhangdengyu
27eb4e2334 fix:SysMqNotify系统调用安全增强
Close: #I7YG58

Signed-off-by: zhangdengyu <zhangdengyu2@huawei.com>
Change-Id: Iee5a6c24cd2226e9cab0c4fd37e76194ad068862
2023-09-04 20:43:40 +08:00
openharmony_ci
bd57ef7e2c !1161 添加unittest用例测试工具
Merge pull request !1161 from zhushengle/unittest_tools
2023-09-04 09:12:43 +00:00
zhushengle
342a3eb5c1 feat: 添加unittest用例测试工具
Close #I73IZ3

Signed-off-by: zhushengle <zhushengle@huawei.com>
Change-Id: I899978a8d8d2edeb30f0ba4d896f6f5abc8a6939
2023-09-04 11:57:15 +08:00
openharmony_ci
63885154d2 !1173 test:调整测试用例
Merge pull request !1173 from zhangdengyu/test_0831
2023-08-31 03:47:11 +00:00
zhangdengyu
95d1eb890a test: 调整测试用例
Close: #I7XBLH

Signed-off-by: zhangdengyu <zhangdengyu2@huawei.com>
Change-Id: Ie58907ea40c062fd1604035945810c53dc7f0bf2
2023-08-31 09:04:51 +08:00
openharmony_ci
0bc453c2cd !1169 修复swtmr遍历不全导致的用例问题
Merge pull request !1169 from wangchen/0726_a
2023-07-26 02:39:24 +00:00
wangchen
73bcf0ec9a Fix: 修复swtmr只在当前核遍历链表的问题
Close #I7NZDT
Signed-off-by: wangchen <wangchen240@huawei.com>
2023-07-26 09:35:58 +08:00
openharmony_ci
49bfc90a63 !1167 容器代码container目录位置变更
Merge pull request !1167 from zwx1232718/master
2023-06-09 09:21:56 +00:00
zwx1232718
b0708886fa container dir change
Signed-off-by: zwx1232718 <zhenghui23@huawei.com>
2023-06-09 16:29:23 +08:00
openharmony_ci
a388a3f565 !1148 修复一些typo错误
Merge pull request !1148 from 景涛/master
2023-06-06 13:36:01 +00:00
arvinzzz
145ff76ab6 refactor: fix codecheck
Signed-off-by: arvinzzz <zhaotianyu9@huawei.com>
Change-Id: Ib35ca40dc837d78a4c9dc03e44d117088865a5a6
2023-05-26 15:44:47 +08:00
”景涛“
24aa6858ee fix some typo errors
Signed-off-by: ”景涛“ <jingtao3@hust.edu.cn>
2023-04-15 22:16:32 +08:00
46 changed files with 834 additions and 150 deletions

View File

@@ -87,6 +87,8 @@ OpenHarmony LiteOS-A内核支持[Hi3516DV300](https://gitee.com/openharmony/docs
编译可以参考:[编译指导](https://gitee.com/openharmony/docs/blob/master/zh-cn/device-dev/quick-start/quickstart-pkg-3516-build.md)
测试参考:[单元测试](testsuites/unittest/tools/README.md)
## 贡献<a name="section1371123476304"></a>
[如何贡献](https://gitee.com/openharmony/docs/blob/HEAD/zh-cn/contribute/%E5%8F%82%E4%B8%8E%E8%B4%A1%E7%8C%AE.md)

View File

@@ -27,9 +27,6 @@
"component": {
"name": "liteos_a",
"subsystem": "kernel",
"syscap": [
"SystemCapability.Kernel.Liteos-A"
],
"features": [],
"adapted_system_type": [
"small"

View File

@@ -97,5 +97,5 @@ static const struct file_operations_vfs g_memDevOps = {
int DevMemRegister(void)
{
return register_driver("/dev/mem", &g_memDevOps, 0666, 0); /* 0666: file mode */
return register_driver("/dev/mem", &g_memDevOps, 0644, 0); /* 0644: file mode */
}

View File

@@ -2311,7 +2311,7 @@ diff -Nupr old/fs/jffs2/erase.c new/fs/jffs2/erase.c
diff -Nupr old/fs/jffs2/file.c new/fs/jffs2/file.c
--- old/fs/jffs2/file.c 2022-05-09 17:22:53.000000000 +0800
+++ new/fs/jffs2/file.c 2022-05-10 09:43:14.250000000 +0800
@@ -9,335 +9,30 @@
@@ -9,334 +9,31 @@
* For licensing information, see the file 'LICENCE' in this directory.
*
*/
@@ -2348,7 +2348,7 @@ diff -Nupr old/fs/jffs2/file.c new/fs/jffs2/file.c
- struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
+ /* FIXME: This works only with one file system mounted at a time */
int ret;
-
- ret = file_write_and_wait_range(filp, start, end);
+ ret = jffs2_read_inode_range(c, f, gc_buffer,
+ offset & ~(PAGE_SIZE-1), PAGE_SIZE);
@@ -2361,8 +2361,10 @@ diff -Nupr old/fs/jffs2/file.c new/fs/jffs2/file.c
- inode_unlock(inode);
-
- return 0;
-}
-
+ return ERR_PTR(ret);
+ return gc_buffer;
}
-const struct file_operations jffs2_file_operations =
-{
- .llseek = generic_file_llseek,
@@ -2387,7 +2389,10 @@ diff -Nupr old/fs/jffs2/file.c new/fs/jffs2/file.c
-};
-
-const struct address_space_operations jffs2_file_address_operations =
-{
+void jffs2_gc_release_page(struct jffs2_sb_info *c,
+ unsigned char *ptr,
+ unsigned long *priv)
{
- .readpage = jffs2_readpage,
- .write_begin = jffs2_write_begin,
- .write_end = jffs2_write_end,
@@ -2443,35 +2448,29 @@ diff -Nupr old/fs/jffs2/file.c new/fs/jffs2/file.c
- ret = jffs2_do_readpage_unlock(pg->mapping->host, pg);
- mutex_unlock(&f->sem);
- return ret;
+ return ERR_PTR(ret);
+ return gc_buffer;
}
-}
-
-static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
- loff_t pos, unsigned len, unsigned flags,
- struct page **pagep, void **fsdata)
+void jffs2_gc_release_page(struct jffs2_sb_info *c,
+ unsigned char *ptr,
+ unsigned long *priv)
{
-{
- struct page *pg;
- struct inode *inode = mapping->host;
- struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
- struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
- pgoff_t index = pos >> PAGE_SHIFT;
- uint32_t pageofs = index << PAGE_SHIFT;
- int ret = 0;
-
- jffs2_dbg(1, "%s()\n", __func__);
-
- if (pageofs > inode->i_size) {
- /* Make new hole frag from old EOF to new page */
- if (pos > inode->i_size) {
- /* Make new hole frag from old EOF to new position */
- struct jffs2_raw_inode ri;
- struct jffs2_full_dnode *fn;
- uint32_t alloc_len;
-
- jffs2_dbg(1, "Writing new hole frag 0x%x-0x%x between current EOF and new page\n",
- (unsigned int)inode->i_size, pageofs);
- jffs2_dbg(1, "Writing new hole frag 0x%x-0x%x between current EOF and new position\n",
- (unsigned int)inode->i_size, (uint32_t)pos);
-
- ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len,
- ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
@@ -2491,10 +2490,10 @@ diff -Nupr old/fs/jffs2/file.c new/fs/jffs2/file.c
- ri.mode = cpu_to_jemode(inode->i_mode);
- ri.uid = cpu_to_je16(i_uid_read(inode));
- ri.gid = cpu_to_je16(i_gid_read(inode));
- ri.isize = cpu_to_je32(max((uint32_t)inode->i_size, pageofs));
- ri.isize = cpu_to_je32((uint32_t)pos);
- ri.atime = ri.ctime = ri.mtime = cpu_to_je32(JFFS2_NOW());
- ri.offset = cpu_to_je32(inode->i_size);
- ri.dsize = cpu_to_je32(pageofs - inode->i_size);
- ri.dsize = cpu_to_je32((uint32_t)pos - inode->i_size);
- ri.csize = cpu_to_je32(0);
- ri.compr = JFFS2_COMPR_ZERO;
- ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8));
@@ -2524,7 +2523,7 @@ diff -Nupr old/fs/jffs2/file.c new/fs/jffs2/file.c
- goto out_err;
- }
- jffs2_complete_reservation(c);
- inode->i_size = pageofs;
- inode->i_size = pos;
- mutex_unlock(&f->sem);
- }
-
@@ -8668,7 +8667,7 @@ diff -Nupr old/fs/jffs2/writev.c new/fs/jffs2/writev.c
diff -Nupr old/fs/jffs2/xattr.c new/fs/jffs2/xattr.c
--- old/fs/jffs2/xattr.c 2022-05-09 17:15:24.360000000 +0800
+++ new/fs/jffs2/xattr.c 1970-01-01 08:00:00.000000000 +0800
@@ -1,1347 +0,0 @@
@@ -1,1352 +0,0 @@
-/*
- * JFFS2 -- Journalling Flash File System, Version 2.
- *
@@ -9443,10 +9442,10 @@ diff -Nupr old/fs/jffs2/xattr.c new/fs/jffs2/xattr.c
-}
-
-#define XREF_TMPHASH_SIZE (128)
-void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c)
-int jffs2_build_xattr_subsystem(struct jffs2_sb_info *c)
-{
- struct jffs2_xattr_ref *ref, *_ref;
- struct jffs2_xattr_ref *xref_tmphash[XREF_TMPHASH_SIZE];
- struct jffs2_xattr_ref **xref_tmphash;
- struct jffs2_xattr_datum *xd, *_xd;
- struct jffs2_inode_cache *ic;
- struct jffs2_raw_node_ref *raw;
@@ -9455,9 +9454,12 @@ diff -Nupr old/fs/jffs2/xattr.c new/fs/jffs2/xattr.c
-
- BUG_ON(!(c->flags & JFFS2_SB_FLAG_BUILDING));
-
- xref_tmphash = kcalloc(XREF_TMPHASH_SIZE,
- sizeof(struct jffs2_xattr_ref *), GFP_KERNEL);
- if (!xref_tmphash)
- return -ENOMEM;
-
- /* Phase.1 : Merge same xref */
- for (i=0; i < XREF_TMPHASH_SIZE; i++)
- xref_tmphash[i] = NULL;
- for (ref=c->xref_temp; ref; ref=_ref) {
- struct jffs2_xattr_ref *tmp;
-
@@ -9555,6 +9557,8 @@ diff -Nupr old/fs/jffs2/xattr.c new/fs/jffs2/xattr.c
- "%u of xref (%u dead, %u orphan) found.\n",
- xdatum_count, xdatum_unchecked_count, xdatum_orphan_count,
- xref_count, xref_dead_count, xref_orphan_count);
- kfree(xref_tmphash);
- return 0;
-}
-
-struct jffs2_xattr_datum *jffs2_setup_xattr_datum(struct jffs2_sb_info *c,

View File

@@ -490,14 +490,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;

View File

@@ -207,7 +207,7 @@ static const struct ProcFileOperations FS_CACHE_PROC_FOPS = {
void ProcFsCacheInit(void)
{
struct ProcDirEntry *pde = CreateProcEntry("fs_cache", 0, NULL);
struct ProcDirEntry *pde = CreateProcEntry("fs_cache", 0400, NULL);
if (pde == NULL) {
PRINT_ERR("create fs_cache error!\n");
return;

View File

@@ -67,51 +67,6 @@ config PAGE_TABLE_FINE_LOCK
help
This option will enable fine lock for page table.
######################### config options of container ####################
config KERNEL_CONTAINER
bool "Enable container Feature"
default n
depends on KERNEL_VM
config PID_CONTAINER
bool "Enable pid container Feature"
default n
depends on KERNEL_CONTAINER
config UTS_CONTAINER
bool "Enable uts container Feature"
default n
depends on KERNEL_CONTAINER
config MNT_CONTAINER
bool "Enable mnt container Feature"
default n
depends on KERNEL_CONTAINER
config CHROOT
bool "Enable chroot"
default n
depends on MNT_CONTAINER
config IPC_CONTAINER
bool "Enable ipc container Feature"
default n
depends on KERNEL_CONTAINER
config TIME_CONTAINER
bool "Enable time container"
default n
depends on KERNEL_CONTAINER
config USER_CONTAINER
bool "Enable user container"
default n
depends on KERNEL_CONTAINER
config NET_CONTAINER
bool "Enable net container"
default n
depends on KERNEL_CONTAINER
######################### config options of extended #####################
source "kernel/extended/Kconfig"

View File

@@ -32,15 +32,6 @@ import("//kernel/liteos_a/liteos.gni")
module_name = get_path_info(rebase_path("."), "name")
kernel_module(module_name) {
sources = [
"container/los_container.c",
"container/los_credentials.c",
"container/los_ipc_container.c",
"container/los_mnt_container.c",
"container/los_net_container.c",
"container/los_pid_container.c",
"container/los_time_container.c",
"container/los_user_container.c",
"container/los_uts_container.c",
"core/los_bitmap.c",
"core/los_info.c",
"core/los_process.c",

View File

@@ -39,7 +39,6 @@ LOCAL_SRCS := $(wildcard ipc/*.c) $(wildcard core/*.c) $(wildcard mem/membox/*.
$(wildcard mp/*.c) \
$(wildcard sched/*.c) \
$(wildcard vm/*.c) \
$(wildcard container/*.c)
LOCAL_FLAGS := $(LITEOS_CFLAGS_INTERWORK) -Wno-frame-address

View File

@@ -583,7 +583,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;
}

View File

@@ -103,7 +103,7 @@ STATIC VOID SortQueueIndexArray(UINT32 *indexArray, UINT32 count)
IpcSortParam queueSortParam;
queueSortParam.buf = (CHAR *)g_queueDebugArray;
queueSortParam.ipcDebugCBSize = sizeof(QueueDebugCB);
queueSortParam.ipcDebugCBCnt = LOSCFG_BASE_IPC_SEM_LIMIT;
queueSortParam.ipcDebugCBCnt = LOSCFG_BASE_IPC_QUEUE_LIMIT;
queueSortParam.sortElemOff = LOS_OFF_SET_OF(QueueDebugCB, lastAccessTime);
if (count > 0) {

View File

@@ -32,6 +32,7 @@ import("//kernel/liteos_a/liteos.gni")
group("extended") {
deps = [
"blackbox",
"container",
"cppsupport",
"cpup",
"dynload",
@@ -52,6 +53,7 @@ group("extended") {
config("public") {
configs = [
"blackbox:public",
"container:public",
"cpup:public",
"dynload:public",
"hidumper:public",

View File

@@ -113,6 +113,54 @@ config KERNEL_HOOK
default n
depends on KERNEL_EXTKERNEL && DEBUG_VERSION
######################### config options of container ####################
config KERNEL_CONTAINER
bool "Enable container Feature"
default n
depends on KERNEL_VM
config PID_CONTAINER
bool "Enable pid container Feature"
default n
depends on KERNEL_CONTAINER
config UTS_CONTAINER
bool "Enable uts container Feature"
default n
depends on KERNEL_CONTAINER
config MNT_CONTAINER
bool "Enable mnt container Feature"
default n
depends on KERNEL_CONTAINER
config CHROOT
bool "Enable chroot"
default n
depends on MNT_CONTAINER
config IPC_CONTAINER
bool "Enable ipc container Feature"
default n
depends on KERNEL_CONTAINER
config TIME_CONTAINER
bool "Enable time container"
default n
depends on KERNEL_CONTAINER
config USER_CONTAINER
bool "Enable user container"
default n
depends on KERNEL_CONTAINER
config NET_CONTAINER
bool "Enable net container"
default n
depends on KERNEL_CONTAINER
######################### config options of trace #########################
source "kernel/extended/trace/Kconfig"

View File

@@ -0,0 +1,65 @@
# 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("//kernel/liteos_a/liteos.gni")
module_switch = defined(LOSCFG_KERNEL_CONTAINER)
module_name = get_path_info(rebase_path("."), "name")
kernel_module(module_name) {
sources = [ "los_container.c" ]
if (defined(LOSCFG_IPC_CONTAINER)) {
sources += [ "los_ipc_container.c" ]
}
if (defined(LOSCFG_MNT_CONTAINER)) {
sources += [ "los_mnt_container.c" ]
}
if (defined(LOSCFG_NET_CONTAINER)) {
sources += [ "los_net_container.c" ]
}
if (defined(LOSCFG_PID_CONTAINER)) {
sources += [ "los_pid_container.c" ]
}
if (defined(LOSCFG_TIME_CONTAINER)) {
sources += [ "los_time_container.c" ]
}
if (defined(LOSCFG_USER_CONTAINER)) {
sources += [
"los_credentials.c",
"los_user_container.c",
]
}
if (defined(LOSCFG_UTS_CONTAINER)) {
sources += [ "los_uts_container.c" ]
}
public_configs = [ ":public" ]
}
config("public") {
include_dirs = [ "." ]
}

View File

@@ -0,0 +1,63 @@
# 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 $(LITEOSTOPDIR)/config.mk
MODULE_NAME := $(notdir $(shell pwd))
LOCAL_SRCS := $(wildcard *.c)
ifneq ($(LOSCFG_IPC_CONTAINER), y)
LOCAL_SRCS += $(filter-out los_ipc_container.c, $(LOCAL_SRCS))
endif
ifneq ($(LOSCFG_MNT_CONTAINER), y)
LOCAL_SRCS += $(filter-out los_mnt_container.c, $(LOCAL_SRCS))
endif
ifneq ($(LOSCFG_NET_CONTAINER), y)
LOCAL_SRCS += $(filter-out los_net_container.c, $(LOCAL_SRCS))
endif
ifneq ($(LOSCFG_PID_CONTAINER), y)
LOCAL_SRCS += $(filter-out los_pid_container.c, $(LOCAL_SRCS))
endif
ifneq ($(LOSCFG_TIME_CONTAINER), y)
LOCAL_SRCS += $(filter-out los_time_container.c, $(LOCAL_SRCS))
endif
ifneq ($(LOSCFG_USER_CONTAINER), y)
LOCAL_SRCS += $(filter-out los_credentials.c los_user_container.c, $(LOCAL_SRCS))
endif
ifneq ($(LOSCFG_UTS_CONTAINER), y)
LOCAL_SRCS += $(filter-out los_uts_container.c, $(LOCAL_SRCS))
endif
include $(MODULE)

View File

@@ -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';
}

View File

@@ -94,9 +94,15 @@ int SysMqClose(mqd_t personal)
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();
}

View File

@@ -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) {

View File

@@ -26,9 +26,6 @@
# 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")
import("./config.gni")
config("container_config") {

View File

@@ -26,6 +26,8 @@
# 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")
common_include_dirs = [

View File

@@ -53,7 +53,7 @@ static UINT32 Testcase(VOID)
ret = write(pipeFd[1], "hello world", 12); // 12, "hello world" length and '\0'
printf("write first status: %d\n", ret);
if (ret != 12) { // 12, "hello world" length and '\0'
exit(11); // 11, the value of son process unexpect exit, convenient to debug
exit(11); // 11, the value of son process unexpected exit, convenient to debug
}
*sharedflag = 1;
close(pipeFd[1]);

View File

@@ -55,7 +55,7 @@ static UINT32 Testcase(VOID)
ret = write(pipeFd[1], "Hello world", TAR_STR_LEN);
printf("write first status: %d\n", ret);
if (ret != TAR_STR_LEN) {
exit(11); // 11, the value of son process unexpect exit, convenient to debug
exit(11); // 11, the value of son process unexpected exit, convenient to debug
}
*sharedflag = 1;
close(pipeFd[1]);

View File

@@ -69,7 +69,7 @@ static UINT32 Testcase(VOID)
ret = sigaction(SIGCHLD, &oldact, NULL);
if (ret == -1) {
exit(6); // 6, the value of son process unexpect exit, convenient to debug
exit(6); // 6, the value of son process unexpected exit, convenient to debug
}
sleep(1);
printf("---son--cnt check----%d--------\n", g_actionCnt1);

View File

@@ -90,31 +90,31 @@ static int TestCase(void)
printf("errline = %d\n", __LINE__);
exit(-1);
}
ret = kill(10, 31); // 10, kill process pid; 31, sigal.
ret = kill(10, 31); // 10, kill process pid; 31, signal.
if (retValue != -1 || errno != EINVAL) {
printf("errline = %d\n", __LINE__);
exit(-1);
}
ret = kill(10, 32); // 10, kill process pid; 32, sigal.
ret = kill(10, 32); // 10, kill process pid; 32, signal.
if (retValue != -1 || errno != EINVAL) {
printf("errline = %d\n", __LINE__);
exit(-1);
}
ret = kill(2, 32); // 2, kill process pid; 32, sigal.
ret = kill(2, 32); // 2, kill process pid; 32, signal.
if (retValue != -1 || errno != EINVAL) {
printf("errline = %d\n", __LINE__);
exit(-1);
}
printf("test EPERM begin\n");
ret = kill(2, 5); // 2, kill process pid; 5, sigal.
ret = kill(2, 5); // 2, kill process pid; 5, signal.
if (retValue != -1 || errno != EPERM) {
printf("errline = %d\n", __LINE__);
exit(-1);
}
ret = kill(3, 5); // 3, kill process pid; 5, sigal.
ret = kill(3, 5); // 3, kill process pid; 5, signal.
if (retValue != -1 || errno != EPERM) {
printf("errline = %d\n", __LINE__);
exit(-1);
@@ -126,7 +126,7 @@ static int TestCase(void)
exit(-1);
}
ret = kill(1, 5); // 5, kill sigal num .
ret = kill(1, 5); // 5, kill signal num .
if (retValue != -1 || errno != EPERM) {
printf("errline = %d\n", __LINE__);
exit(-1);

View File

@@ -40,7 +40,7 @@ static void SigChildResponse(int signo)
wait(nullptr);
}
/* Register SIGCHLD, through signal to restore the child memery */
/* Register SIGCHLD, through signal to restore the child memory */
static int TestSigKillResp()
{
void (*ret)(int) = nullptr;

View File

@@ -38,7 +38,7 @@ void SigChildResponse(int signo)
wait(nullptr);
}
/* Register SIGCHLD, through signal to restore the child memery */
/* Register SIGCHLD, through signal to restore the child memory */
static int TestSigKillWaitFromSigChild()
{
void (*ret)(int);

View File

@@ -88,7 +88,7 @@ static int TestBlock()
printf("\n\n");
printf("Signal Pause(2)\n");
printf("To test whether pause can relese the signal\n");
printf("To test whether pause can release the signal\n");
alarm(clock);
retValue = sighold(sig);
if (retValue != 0) {

View File

@@ -67,7 +67,7 @@ static UINT32 TestCase()
sigemptyset(&set);
sigprocmask(SIG_SETMASK, &set, NULL);
printf("check invlid sigset ...\n");
printf("check invalid sigset ...\n");
int rt = sigaddset(&set, 0);
ICUNIT_ASSERT_EQUAL(rt, -1, rt);
ICUNIT_ASSERT_EQUAL(errno, EINVAL, errno);
@@ -79,19 +79,19 @@ static UINT32 TestCase()
siginfo_t si;
time1.tv_sec = -1;
printf("check invlid timespec: tv_sec=-1 ...\n");
printf("check invalid timespec: tv_sec=-1 ...\n");
ret = SigtimedwaitFailTest(&set, &si, &time1, EINVAL);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
time1.tv_sec = 1;
time1.tv_nsec = -1;
printf("check invlid timespec: tv_nsec=-1 ...\n");
printf("check invalid timespec: tv_nsec=-1 ...\n");
ret = SigtimedwaitFailTest(&set, &si, &time1, EINVAL);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);
time1.tv_sec = 1;
time1.tv_nsec = 1000 * 1000 * 1000 + 1; // 1000, set the nsec of time.
printf("check invlid timespec: tv_nsec overflow ...\n");
printf("check invalid timespec: tv_nsec overflow ...\n");
ret = SigtimedwaitFailTest(&set, &si, &time1, EINVAL);
ICUNIT_ASSERT_EQUAL(ret, 0, ret);

View File

@@ -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.

View File

@@ -46,7 +46,7 @@ void child1(void)
while (1) {
ret = pthread_getschedparam(pthread, &newPolicy, &param);
if (ret != 0) {
printf("pthread_getschedparam failed ! %d erro: %d\n", __LINE__, errno);
printf("pthread_getschedparam failed ! %d error: %d\n", __LINE__, errno);
exit(255); // 255, set a special exit code.
}

View File

@@ -26,9 +26,6 @@
# 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")
import("./config.gni")
if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_LOW) {

View File

@@ -27,6 +27,7 @@
# 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")
common_include_dirs = [

View File

@@ -26,9 +26,6 @@
# 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")
import("./config.gni")
if (LOSCFG_USER_TEST_LEVEL >= TEST_LEVEL_LOW) {

View File

@@ -27,6 +27,7 @@
# 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")
common_include_dirs = [
@@ -92,7 +93,7 @@ process_plimits_sources_smoke = [
process_plimits_sources_full = []
# plimits module
if (LOSCFG_USER_TEST_PROCESS == true) {
if (LOSCFG_USER_TEST_PROCESS_PLIMITS == true) {
common_include_dirs += process_plimits_include_dirs
sources_entry += process_plimits_sources_entry
sources_smoke += process_plimits_sources_smoke

View File

@@ -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" ]
}

View File

@@ -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个。

View File

@@ -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 <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <cstdlib>
#include <cstdio>
#include <dirent.h>
#include <unistd.h>
#include <sys/wait.h>
#include <securec.h>
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<string> GetAllTestsuites(string testsuitesDir)
{
vector<string> 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<char *>(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<string> 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<const char *>(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<string> 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<string> 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<string> 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;
}