Compare commits
20 Commits
weekly_202
...
weekly_202
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8fe4080d08 | ||
|
|
cfa0209c14 | ||
|
|
c2cb0435b2 | ||
|
|
4fbb41b7d5 | ||
|
|
04f971084b | ||
|
|
6daecc8d26 | ||
|
|
173cdeb077 | ||
|
|
e28271d650 | ||
|
|
27eb4e2334 | ||
|
|
bd57ef7e2c | ||
|
|
342a3eb5c1 | ||
|
|
63885154d2 | ||
|
|
95d1eb890a | ||
|
|
0bc453c2cd | ||
|
|
73bcf0ec9a | ||
|
|
49bfc90a63 | ||
|
|
b0708886fa | ||
|
|
a388a3f565 | ||
|
|
145ff76ab6 | ||
|
|
24aa6858ee |
@@ -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)
|
||||
|
||||
@@ -27,9 +27,6 @@
|
||||
"component": {
|
||||
"name": "liteos_a",
|
||||
"subsystem": "kernel",
|
||||
"syscap": [
|
||||
"SystemCapability.Kernel.Liteos-A"
|
||||
],
|
||||
"features": [],
|
||||
"adapted_system_type": [
|
||||
"small"
|
||||
|
||||
@@ -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 */
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
- }
|
||||
-
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
65
kernel/extended/container/BUILD.gn
Normal file
65
kernel/extended/container/BUILD.gn
Normal 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 = [ "." ]
|
||||
}
|
||||
63
kernel/extended/container/Makefile
Normal file
63
kernel/extended/container/Makefile
Normal 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)
|
||||
@@ -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';
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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") {
|
||||
|
||||
@@ -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 = [
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -46,7 +46,7 @@ void child1(void)
|
||||
while (1) {
|
||||
ret = pthread_getschedparam(pthread, &newPolicy, ¶m);
|
||||
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.
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 = [
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
38
testsuites/unittest/tools/BUILD.gn
Normal file
38
testsuites/unittest/tools/BUILD.gn
Normal 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" ]
|
||||
}
|
||||
63
testsuites/unittest/tools/README.md
Normal file
63
testsuites/unittest/tools/README.md
Normal 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个。
|
||||
468
testsuites/unittest/tools/unittest_tools.cpp
Normal file
468
testsuites/unittest/tools/unittest_tools.cpp
Normal 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;
|
||||
}
|
||||
Reference in New Issue
Block a user