提交 beed5e1d 编写于 作者: Y Yilu Mao 提交者: YiluMao

Add testcases for interface check

上级 06e7107e
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef YTS_H
#define YTS_H
int yts_get_args(const char ***argv);
void yts_run(int argc, char **argv);
void osupdate_online_test_run(char *bin, int id2);
#define check_cond_wait(cond, seconds) \
do { \
unsigned int i; \
for (i = 0; i < (unsigned int)seconds && !(cond); i++) { \
aos_msleep(1000); \
} \
YUNIT_ASSERT(cond); \
} while(0);
#define run_times(func, times) \
do { \
int i; \
for (i = 0; i < times; i++, func); \
} while(0);
#endif /* YTS_H */
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#ifndef YUNIT_H
#define YUNIT_H
#include <stddef.h>
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifndef AOS_EXPORTX
#define AOS_EXPORT(ret, fun, ...)
#endif
#ifndef AOS_COMPONENT_INIT
#define AOS_COMPONENT_INIT(fun, ...)
#endif
#ifndef AOS_TESTCASE
#define AOS_TESTCASE(fun, ...)
#endif
typedef void (*yunit_test_case_proc)(void);
typedef struct {
const char *name;
yunit_test_case_proc test_proc;
} yunit_test_case_t;
#define YUNIT_TEST_CASE_NULL { 0 }
typedef int (*yunit_test_suit_init)(void);
typedef int (*yunit_test_suit_deinit)(void);
typedef void (*yunit_test_case_setup)(void);
typedef void (*yunit_test_case_teardown)(void);
typedef struct {
const char *name;
yunit_test_suit_init init;
yunit_test_suit_deinit deinit;
yunit_test_case_setup setup;
yunit_test_case_teardown teardown;
yunit_test_case_t *test_case_array;
} yunit_test_suite_t;
#define YUNIT_TEST_SUITE_NULL { 0 }
void *yunit_add_test_suite(const char *name, yunit_test_suit_init init,
yunit_test_suit_deinit deinit,
yunit_test_case_setup setup,
yunit_test_case_teardown teardown);
int yunit_add_test_case(void *test_suite, const char *name, yunit_test_case_proc proc);
int yunit_add_test_suites(yunit_test_suite_t *test_suite_array);
void *yunit_get_test_suite(const char *name);
void *yunit_get_test_case(void *test_suite, const char *name);
void yunit_test_init(void);
void yunit_test_deinit(void);
int yunit_test_run(void);
int yunit_run_test_suite(void *test_suite);
int yunit_run_test_case(void *test_suite, void *test_case);
void yunit_test_print_result(void);
enum {
TEST_RESULT_SUCCESS = 0,
TEST_RESULT_FAILURE,
TEST_RESULT_FATAL
};
void yunit_add_test_case_result(int result_type, const char *file, size_t line,
const char *fmt, ...);
#define YUNIT_FAIL(msg) yunit_add_test_case_result(TEST_RESULT_FAILURE, __FILE__, __LINE__, "%s", msg);
#define YUNIT_FAIL_FATAL(msg) yunit_add_test_case_result(TEST_RESULT_FATAL, __FILE__, __LINE__, "%s", msg);
#define YUNIT_ASSERT(expr) \
do { \
yunit_add_test_case_result((expr) ? TEST_RESULT_SUCCESS : TEST_RESULT_FAILURE, \
__FILE__, __LINE__, "%s", #expr); \
} while (0);
/* print msg if failure, else nothing */
#define YUNIT_ASSERT_MSG(expr, fmt, args...) \
do { \
yunit_add_test_case_result((expr) ? TEST_RESULT_SUCCESS : TEST_RESULT_FAILURE, \
__FILE__, __LINE__, "expect (%s) but actual ("fmt")", #expr, ##args); \
} while (0);
#define YUNIT_ASSERT_FETAL(expr) \
do { \
yunit_add_test_case_result((expr) ? TEST_RESULT_SUCCESS : TEST_RESULT_FATAL, \
__FILE__, __LINE__, "%s", #expr); \
} while (0);
#define YUNIT_ASSERT_TRUE(expr) YUNIT_ASSERT(expr)
#define YUNIT_ASSERT_FALSE(expr) YUNIT_ASSERT(!(expr))
#define YUNIT_ASSERT_TRUE_FATAL(expr) YUNIT_ASSERT_FETAL(expr)
#define YUNIT_ASSERT_EQUAL(expect, actual) \
do { \
int result = (expect == actual); \
yunit_add_test_case_result(result ? TEST_RESULT_SUCCESS : TEST_RESULT_FAILURE, \
__FILE__, __LINE__, "%s==%s", #expect, #actual); \
} while (0);
#define YUNIT_ASSERT_EQUAL_FATAL(expect, actual) \
do { \
yunit_add_test_case_result((expect == actual) ? TEST_RESULT_SUCCESS : TEST_RESULT_FATAL, \
__FILE__, __LINE__, "%s==%s", #expect, #actual); \
} while (0);
#define YUNIT_ASSERT_STR_EQUAL(expect, actual) \
do { \
int result = strcmp((const char *)expect, (const char *)actual) == 0; \
yunit_add_test_case_result(result ? TEST_RESULT_SUCCESS : TEST_RESULT_FAILURE, \
__FILE__, __LINE__, \
result ? "%s(%s)==%s(%s)" : "expect %s(%s) but actual is %s(%s)", \
#expect, (const char *)expect, #actual, (const char *)actual); \
} while (0);
#define YUNIT_ASSERT_STR_N_EQUAL(expect, actual, len) \
do { \
int result = strncmp((const char *)expect, (const char *)actual, len) == 0; \
yunit_add_test_case_result(result ? TEST_RESULT_SUCCESS : TEST_RESULT_FAILURE, \
__FILE__, __LINE__, \
result ? "%s(%s)==%s(%s) len=%d" : "expect %s(%s) but actual is %s(%s) len=%d", \
#expect, (const char *)expect, #actual, (const char *)actual, len); \
} while (0);
#define YUNIT_ASSERT_PTR_NULL(p) YUNIT_ASSERT_PTR_EQUAL(p, NULL)
#define YUNIT_ASSERT_PTR_NOT_NULL(p) YUNIT_ASSERT_PTR_NOT_EQUAL(p, NULL)
#define YUNIT_ASSERT_PTR_EQUAL(expect, actual) \
do { \
int result = (expect == actual); \
yunit_add_test_case_result(result ? TEST_RESULT_SUCCESS : TEST_RESULT_FAILURE, \
__FILE__, __LINE__, \
result ? "%s(%p)==%s(%p)" : "expect %s(%p) but actual is %s(%p)", \
#expect, expect, #actual, actual); \
} while (0);
#define YUNIT_ASSERT_PTR_NOT_EQUAL(expect, actual) \
do { \
int result = (expect != actual); \
yunit_add_test_case_result(result ? TEST_RESULT_SUCCESS : TEST_RESULT_FAILURE, \
__FILE__, __LINE__, \
result ? "%s(%p)!=%s(%p)" : "expect %s(%p) but actual is %s(%p)", \
#expect, expect, #actual, actual); \
} while (0);
#define PRINT_TASK_INFO(task) \
printf("\t%-40s%-10d%-20d\n", task->task_name, (int)task->task_state, \
(int)task->stack_size*sizeof(cpu_stack_t))
#define PRINT_ALL_TASK_INFO() \
do { \
klist_t *taskhead = &g_kobj_list.task_head; \
klist_t *taskend = taskhead; \
klist_t *tmp; \
ktask_t *task; \
printf("\t--------------------------------------------------------------\n"); \
printf("\t%-40s%-10s%-20s\n", "Name","State", "StackSize"); \
printf("\t--------------------------------------------------------------\n"); \
for (tmp = taskhead->next; tmp != taskend; tmp = tmp->next) { \
task = krhino_list_entry(tmp, ktask_t, task_stats_item); \
PRINT_TASK_INFO(task); \
} \
printf("\t--------------------------------------------------------------\n"); \
} while (0)
#ifdef __cplusplus
}
#endif
#endif /* YUNIT_H */
/*
* Copyright (c) 2018 Intel Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <dirent.h>
#include "fs_test.h"
#include "aos/vfs.h"
#include "aos/errno.h"
extern int test_file_write(void);
extern int test_file_close(void);
static int file;
static int test_mkdir(void)
{
int res;
int fd;
TC_PRINT("\nmkdir tests:\n");
/* Verify mkdir() */
res = aos_mkdir(TEST_DIR);
if (res) {
TC_PRINT("Error creating dir[%d]\n", res);
return res;
}
res = aos_open(TEST_DIR_FILE, O_CREAT | O_RDWR);
if (res < 0) {
TC_PRINT("Failed opening file [%d]\n", res);
return res;
}
file = res;
fd = aos_open(TEST_DIR_FILE1, O_CREAT | O_RDWR);
if (fd < 0) {
TC_PRINT("Failed opening file %s, ret: [%d]\n", TEST_DIR_FILE1, fd);
return fd;
}
res = test_file_write();
if (res) {
return res;
}
res = aos_close(file);
if (res) {
TC_PRINT("Error closing file [%d]\n", res);
return res;
}
res = aos_close(fd);
if (res) {
TC_PRINT("Error closing file %s, ret: [%d]\n", TEST_DIR_FILE1, res);
return res;
}
TC_PRINT("Created dir %s!\n", TEST_DIR);
return TC_PASS;
}
static int test_lsdir(const char *path)
{
aos_dir_t *dirp;
aos_dirent_t *entry;
char dirent1_name[256];
char dirent2_name[256];
long loc1;
long loc2;
TC_PRINT("\nreaddir test:\n");
/* Verify opendir() */
dirp = aos_opendir(path);
if (dirp == NULL) {
TC_PRINT("Error opening dir %s\n", path);
return -EIO;
}
TC_PRINT("\nListing dir %s:\n", path);
/* Verify readdir() */
entry = aos_readdir(dirp);
strcpy(dirent1_name, entry->d_name);
while (entry != NULL) {
/* Verify telldir() */
long location = aos_telldir(dirp);
TC_PRINT("[FILE] name: %s, location:%ld\n", entry->d_name, location);
entry = aos_readdir(dirp);
}
/* Verify rewinddir() */
aos_rewinddir(dirp);
entry = aos_readdir(dirp);
strcpy(dirent2_name, entry->d_name);
if (strcmp(dirent1_name, dirent2_name)) {
TC_PRINT("rewinddir failed, dirent1 name:%s != dirent2 name:%s\n", dirent1_name, dirent2_name);
return TC_FAIL;
}
/* Verify closedir() */
aos_closedir(dirp);
return 0;
}
static int test_seekdir(const char *path)
{
aos_dir_t *dirp;
aos_dirent_t *entry;
long loc1;
long loc2;
TC_PRINT("\nseekdir test:\n");
/* Verify opendir() */
dirp = aos_opendir(path);
if (dirp == NULL) {
TC_PRINT("Error opening dir %s\n", path);
return -EIO;
}
TC_PRINT("\nListing dir %s:\n", path);
/* Verify telldir() */
loc1 = aos_telldir(dirp);
if (loc1 < 0) {
TC_PRINT("telldir failed, ret:%ld\n", loc1);
return TC_FAIL;
}
/* Verify readdir() */
do {
entry = aos_readdir(dirp);
long location = aos_telldir(dirp);
if (entry)
TC_PRINT("[FILE] name: %s, location:%ld\n", entry->d_name, location);
} while (entry != NULL);
/* Seek to the beginning of the directory */
aos_seekdir(dirp, loc1);
loc2 = aos_telldir(dirp);
if (loc2 < 0) {
TC_PRINT("telldir failed, ret:%ld\n", loc2);
return TC_FAIL;
}
if (loc1 != loc2) {
TC_PRINT("seekdir failed, loc1:%ld != loc2:%ld\n", loc1, loc2);
return TC_FAIL;
}
/* Verify closedir() */
aos_closedir(dirp);
return 0;
}
#if 0
static int test_chdir(void)
{
int res;
char buf[256] = {0};
char *pres = NULL;
/*Verify chdir*/
res = chdir(ROOTFS_MNTP);
if (res < 0) {
TC_PRINT("Error change dir %s\n", ROOTFS_MNTP);
return TC_FAIL;
}
/*Verify getcwd*/
pres = getcwd(buf, sizeof(buf) - 1);
if (pres == NULL) {
TC_PRINT("Error getcwd.\n");
return TC_FAIL;
}
res = strcmp(buf, ROOTFS_MNTP);
if (res != 0) {
TC_PRINT("change dir failed.\n");
return TC_FAIL;
}
return TC_PASS;
}
#endif
static int test_rmdir(void)
{
int res;
int retn = TC_PASS;
TC_PRINT("\nrmdir tests:\n");
res = aos_remove(TEST_DIR_FILE);
if (res) {
TC_PRINT("Error deleting file [%d]\n", res);
retn = TC_FAIL;
}
res = aos_remove(TEST_DIR_FILE1);
if (res) {
TC_PRINT("Error deleting file [%d]\n", res);
retn = TC_FAIL;
}
/* Verify rmdir() */
res = aos_rmdir(TEST_DIR);
if (res) {
TC_PRINT("Error rmdir %s [%d]\n", TEST_DIR, res);
retn = TC_FAIL;
}
return retn;
}
#if 0
/**
* 测试标题:文件操作API(chdir/getcwd)功能测试
* 输入条件:/data/目录以挂载文件系统,创建目录TEST_DIR
* 测试步骤:
* 1. 切换目录到/data/
* 2. getcwd获取当前目录
* 3. 比较步骤2的结果是/data/
* 预期结果:所有调用API返回值正常, 且步骤3检查结果相等
*/
void test_fs_chdir(void)
{
YUNIT_ASSERT(test_chdir() == TC_PASS);
}
#endif
/**
* 测试标题:文件操作API(opendir/telldir/readdir/rewinddir/closedir)功能测试
* 输入条件:/data/目录以挂载文件系统,创建目录TEST_DIR
* 测试步骤:
* 1. opendir打开TEST_DIR目录
* 2. telldir获取位置1
* 3. 循环读目录数据直到结束
* 4. seekdir回到目录数据的开始处
* 5. telldir获取位置2
* 6. 检查位置1与位置2是否相等
* 7. 关闭TEST_DIR目录
* 预期结果:所有调用API返回值正常, 且步骤6结果是相等
*/
void test_fs_seekdir(void)
{
YUNIT_ASSERT(test_seekdir(TEST_DIR) == TC_PASS);
}
/**
* 测试标题:文件操作API(mkdir)功能测试
* 输入条件:/data/目录以挂载文件系统
* 测试步骤:
* 1. mkdir创建目录TEST_DIR
* 2. 创建文件打开并写入内容,然后关闭文件
* 预期结果:所有调用API返回值正常
*/
void test_fs_mkdir(void)
{
YUNIT_ASSERT(test_mkdir() == TC_PASS);
}
/**
* 测试标题:文件操作API(opendir/telldir/readdir/rewinddir/closedir)功能测试
* 输入条件:/data/目录以挂载文件系统,创建目录TEST_DIR
* 测试步骤:
* 1. opendir打开TEST_DIR目录
* 2. telldir获取位置1
* 3. 循环读目录数据直到结束
* 4. rewinddir回到目录数据的开始处
* 5. telldir获取位置2
* 6. 检查位置1与位置2是否相等
* 7. 关闭TEST_DIR目录
* 预期结果:所有调用API返回值正常, 且步骤6结果是相等
*/
void test_fs_readdir(void)
{
YUNIT_ASSERT(test_lsdir(TEST_DIR) == TC_PASS);
}
/**
* 测试标题:文件操作API(rmdir)功能测试
* 输入条件:/data/目录以挂载文件系统,创建目录TEST_DIR
* 测试步骤:
* 1. unlink删除TEST_DIR目录下的文件
* 2. rmdir删除目录TEST_DIR
* 预期结果:所有调用API返回值正常
*/
void test_fs_rmdir(void)
{
YUNIT_ASSERT(test_rmdir() == TC_PASS);
}
/*
* Copyright (c) 2018 Intel Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include "fs_test.h"
#include "aos/vfs.h"
const char test_str[] = "hello world!";
static int file;
static int test_file_open(void)
{
int res;
res = aos_open(TEST_FILE, O_CREAT | O_RDWR);
zassert_true(res >= 0, "Failed opening file: %d, errno=%d\n", res, errno);
file = res;
if (res < 0) {
return TC_FAIL;
} else {
return TC_PASS;
}
}
int test_file_write(void)
{
ssize_t brw;
off_t res;
int ret;
long file_size;
size_t str_len;
res = aos_lseek(file, 0, SEEK_SET);
if (res != 0) {
TC_PRINT("lseek failed [%d]\n", (int)res);
aos_close(file);
return TC_FAIL;
}
str_len = strlen(test_str);
brw = aos_write(file, (char *)test_str, str_len);
if (brw < 0) {
TC_PRINT("Failed writing to file [%d]\n", (int)brw);
aos_close(file);
return TC_FAIL;
}
ret = aos_sync(file);
if (ret < 0) {
TC_PRINT("Error fsync, ret:%d.\n", ret);
aos_close(file);
return TC_FAIL;
}
if (brw < str_len) {
TC_PRINT("Unable to complete write. Volume full.\n");
TC_PRINT("Number of bytes written: [%d]\n", (int)brw);
aos_close(file);
return TC_FAIL;
}
file_size = aos_fsize(file);
if (file_size != str_len) {
TC_PRINT("filesize [%ld] is not right. It should be %u\n", filesize, str_len);
aos_close(file);
return TC_FAIL;
}
return TC_PASS;
}
static int test_file_read(void)
{
ssize_t brw;
off_t res;
char read_buff[80] = { 0 };
size_t sz = strlen(test_str);
aos_sync(file);
res = aos_lseek(file, 0, SEEK_SET);
if (res != 0) {
TC_PRINT("lseek failed [%d]\n", (int)res);
aos_close(file);
return TC_FAIL;
}
brw = aos_read(file, read_buff, sz);
if (brw < 0) {
TC_PRINT("Failed reading file [%d]\n", (int)brw);
aos_close(file);
return TC_FAIL;
}
read_buff[brw] = 0;
if (strcmp(test_str, read_buff)) {
TC_PRINT("Error - Data read does not match data written\n");
TC_PRINT("Data read:\"%s\"\n\n", read_buff);
return TC_FAIL;
}
memset(read_buff, 0, 80);
/* Now test after non-zero lseek. */
res = aos_lseek(file, 2, SEEK_SET);
if (res != 2) {
TC_PRINT("lseek failed [%d]\n", (int)res);
aos_close(file);
return TC_FAIL;
}
brw = aos_read(file, read_buff, sizeof(read_buff));
if (brw < 0) {
TC_PRINT("Failed reading file [%d]\n", (int)brw);
aos_close(file);
return TC_FAIL;
}
/* Check for array overrun */
brw = (brw < 80) ? brw : brw - 1;
read_buff[brw] = 0;
if (strcmp(test_str + 2, read_buff)) {
TC_PRINT("Error - Data read does not match data written\n");
TC_PRINT("Data read:\"%s\"\n\n", read_buff);
return TC_FAIL;
}
return TC_PASS;
}
static int test_file_close(void)
{
int res;
res = aos_close(file);
zassert_true(res == 0, "Failed closing file: %d, errno=%d\n", res, errno);
return res;
}
static int test_file_stat(void)
{
int ret;
struct aos_stat test_file_stat_buf = {0};
//int old_size;
ret = aos_access(TEST_FILE, F_OK | R_OK | W_OK);
if (ret < 0) {
TC_PRINT("Error access %s, ret:%d, errno:%d.\n", TEST_FILE, ret, errno);
return TC_FAIL;
}
memset(&test_file_stat_buf, 0, sizeof(test_file_stat_buf));
ret = aos_stat(TEST_FILE, &test_file_stat_buf);
if (ret < 0) {
TC_PRINT("Error stat file: %s, ret: [%d], errno:%d\n", TEST_FILE, ret, errno);
return TC_FAIL;
}
TC_PRINT("%s file size: %ld\n", TEST_FILE, test_file_stat_buf.st_size);
/*
old_size = test_file_stat_buf.st_size;
memset(&test_file_stat_buf, 0, sizeof(test_file_stat_buf));
ret = fstat(file, &test_file_stat_buf);
if (ret < 0) {
TC_PRINT("Error fstat fd: %d, ret: [%d], errno:%d\n", file, ret, errno);
return TC_FAIL;
}
TC_PRINT("%s file size: %ld\n", TEST_FILE, test_file_stat_buf.st_size);
if (old_size != test_file_stat_buf.st_size) {
TC_PRINT("Error returned file size of stat: %d != fstat: %d.\n", old_size, test_file_stat_buf.st_size);
return TC_FAIL;
}
*/
return TC_PASS;
}
static int test_file_statfs(void)
{
int res;
struct aos_statfs test_file_statfs_buf = { 0 };
res = aos_statfs(TEST_FILE, &test_file_statfs_buf);
if (res < 0) {
TC_PRINT("Error statfs file system, ret: [%d], errno:%d\n", res, errno);
return TC_FAIL;
}
if (test_file_statfs_buf.f_blocks == 0) {
TC_PRINT("Error statfs file system, f_blocks is 0.\n");
return TC_FAIL;
}
TC_PRINT("file system total blocks: %d\n", test_file_statfs_buf.f_blocks);
return TC_PASS;
}
static int test_file_link(void)
{
int res;
int fd;
const char *new_file_path = ROOTFS_MNTP "/test_file_temp.txt";
/* littlefs do not support link. */
errno = 0;
res = aos_link(TEST_FILE, TEST_FILE1);
if ((res < 0)) {
if (errno == ENOSYS) {
TC_PRINT("Error link is not supported by the underlying fs.\n");
/* Create TEST_FILE1 to continue testing. */
fd = open(TEST_FILE1, O_CREAT | O_RDWR);
if (fd < 0) {
TC_PRINT("Error create file %s , ret:%d, errno:%d\n", TEST_FILE1, fd, errno);
return TC_FAIL;
}
close(fd);
return TC_PASS;
} else {
TC_PRINT("Error link %s to %s, ret:%d, errno:%d\n", TEST_FILE, TEST_FILE1, res, errno);
return TC_FAIL;
}
}
res = aos_rename(TEST_FILE1, new_file_path);
if (res < 0) {
TC_PRINT("Error rename %s to %s, ret:%d, errno:%d\n", TEST_FILE1, new_file_path, res, errno);
return TC_FAIL;
}
res = aos_remove(new_file_path);
if (res < 0) {
TC_PRINT("Error remove %s, ret:%d, errno:%d\n", TEST_FILE1, res, errno);
return TC_FAIL;
}
res = aos_access(new_file_path, F_OK);
if (res == 0) {
TC_PRINT("Error access %s, ret:%d\n", new_file_path, res);
return TC_FAIL;
}
return TC_PASS;
}
#if 0
static int test_file_fcntl(void)
{
int res;
long arg;
/* aos vfs fcntl do not support fcntl. */
errno = 0;
res = fcntl(file, F_GETFD, arg);
if (res < 0) {
TC_PRINT("Error fcntl fd:%d, ret:%d, errno: %d\n", file, res, errno);
return TC_FAIL;
}
return TC_PASS;
}
static int test_file_pathconf(void)
{
long res;
errno = 0;
/* littlefs do not support pathconf */
res = pathconf(TEST_FILE, _PC_LINK_MAX);
if (res < 0 && errno != ENOSYS) {
TC_PRINT("Error pathconf ret:%d\n", res);
return TC_FAIL;
}
return TC_PASS;
}
static int test_file_fpathconf(void)
{
long res;
errno = 0;
res = fpathconf(file, _PC_LINK_MAX);
/* littlefs do not support fpathconf */
if (res < 0 && errno != ENOSYS) {
TC_PRINT("Error pathconf ret:%d\n", res);
return TC_FAIL;
}
return TC_PASS;
}
static int test_file_utime(void)
{
int res;
res = utime(TEST_FILE, NULL);
if (res < 0) {
TC_PRINT("Error utime ret:%d, errno:%d\n", res, errno);
return TC_FAIL;
}
return TC_PASS;
}
static int test_file_delete(void)
{
int res;
res = unlink(TEST_FILE);
if (res) {
TC_PRINT("Error deleting file [%d]\n", res);
return res;
}
return res;
}
#endif
/**
* 测试标题:文件操作API(open)功能测试
* 输入条件:无
* 测试步骤:1. 创建文件TEST_FILE并打开
* 预期结果:返回的正常的fd
*/
void test_fs_open(void)
{
YUNIT_ASSERT(test_file_open() == TC_PASS);
}
/**
* 测试标题:文件操作API(write/lseek/sync/fsize)功能测试
* 输入条件:TEST_FILE文件已存在并被打开
* 测试步骤:
* 1. seek到文件开头
* 2. 写入一段字符串
* 3. sync这个文件到存储设备
* 4. 检查write是否完全写入字符串
* 5. 检查fsize获取到的文件大小是否正确
* 预期结果:步骤1-3, 5返回值正常,步骤4 write完全写入了字符串
*/
void test_fs_write(void)
{
YUNIT_ASSERT(test_file_write() == TC_PASS);
}
/**
* 测试标题:文件操作API(read/sync)功能测试
* 输入条件:TEST_FILE文件已存在并被打开,并已经写入了内容
* 测试步骤:
* 1. seek到文件开头
* 2. 从文件中读取一段内容
* 3. 读取的内容与之前写入的内容比较
* 4. seek到文件偏移2字节的地方
* 5. 读取文件的内容
* 6. 读取的内容与之前写入内容偏移2字节后比较
* 预期结果:
* 1. 步骤3的比较结果相等,步骤6的比较结果相等
*/
void test_fs_read(void)
{
YUNIT_ASSERT(test_file_read() == TC_PASS);
}
/**
* 测试标题:文件操作API(access/stat/fstat)功能测试
* 输入条件:TEST_FILE文件已存在并被打开,并已经写入了内容
* 测试步骤:
* 1. access检查文件是否存在
* 2. stat获取文件的状态的信息包括大小
* 3. fstat获取文件的状态的信息包括大小
* 4. 判断2,3获取的大小是否相等
* 预期结果:
* 1. 步骤4的比较结果相等
*/
void test_fs_stat(void)
{
YUNIT_ASSERT(test_file_stat() == TC_PASS);
}
/**
* 测试标题:文件操作API(statfs)功能测试
* 输入条件:TEST_FILE文件已存在并被打开,并已经写入了内容
* 测试步骤:
* 1. statfs获取文件系统的状态信息
* 2. 检查获取的文件系统的blocks数目
* 预期结果:
* 1. 步骤2的blocks数组不为0
*/
void test_fs_statfs(void)
{
YUNIT_ASSERT(test_file_statfs() == TC_PASS);
}
/**
* 测试标题:文件操作API(link/remove/rename)功能测试
* 输入条件:TEST_FILE文件已存在并被打开,并已经写入了内容
* 测试步骤:
* 1. 创建TEST_FILE的hard link为TEST_FILE1
* 2. TEST_FILE1重命名为新的文件
* 3. 删除新的文件名
* 4. 检查改文件是否存在
* 预期结果:
* 1. 步骤4的结果应为不存在或者部分API底层文件系统不支持返回errno为ENOSYS
*/
void test_fs_link(void)
{
YUNIT_ASSERT(test_file_link() == TC_PASS);
}
#if 0
/**
* 测试标题:文件操作API(fcntl)功能测试
* 输入条件:TEST_FILE文件已存在并被打开,并已经写入了内容
* 测试步骤:
* 1. fcntl F_GETFD
* 预期结果:
* 1. fcntl api 在vfs层不支持,API返回0.
*/
void test_fs_fcntl(void)
{
YUNIT_ASSERT(test_file_fcntl() == TC_PASS);
}
/**
* 测试标题:文件操作API(pathconf)功能测试
* 输入条件:TEST_FILE文件已存在并被打开,并已经写入了内容
* 测试步骤:
* 1. pathconf _PC_LINK_MAX的获取最大link值
* 预期结果:
* 1. pathconf 在littlefs层不支持,pathconf返回值-1,errno为ENOSYS
*/
void test_fs_pathconf(void)
{
YUNIT_ASSERT(test_file_pathconf() == TC_PASS);
}
/**
* 测试标题:文件操作API(fpathconf)功能测试
* 输入条件:TEST_FILE文件已存在并被打开,并已经写入了内容
* 测试步骤:
* 1. fpathconf _PC_LINK_MAX的获取最大link值
* 预期结果:
* 1. fpathconf 在littlefs层不支持,fpathconf返回值-1,errno为ENOSYS
*/
void test_fs_fpathconf(void)
{
YUNIT_ASSERT(test_file_fpathconf() == TC_PASS);
}
#endif
/**
* 测试标题:文件操作API(close)功能测试
* 输入条件:TEST_FILE文件已存在并被打开,并已经写入了内容
* 测试步骤:
* 1. close 关闭文件
* 预期结果:
* 1. close返回值0
*/
void test_fs_close(void)
{
YUNIT_ASSERT(test_file_close() == TC_PASS);
}
#if 0
/**
* 测试标题:文件操作API(utime)功能测试
* 输入条件:TEST_FILE文件已存在
* 测试步骤:
* 1. utime设置文件的时间为当前系统时间
* 预期结果:
* 1. utime返回值正常
*/
void test_fs_utime(void)
{
YUNIT_ASSERT(test_file_utime() == TC_PASS);
}
/**
* 测试标题:文件操作API(unlink)功能测试
* 输入条件:TEST_FILE文件已存在
* 测试步骤:
* 1. unlink删除文件
* 预期结果:
* 1. unlink返回值正常
*/
void test_fs_unlink(void)
{
YUNIT_ASSERT(test_file_delete() == TC_PASS);
}
#endif
/**
* 测试标题:文件操作API(fd_leak)功能测试
* 输入条件:
* 测试步骤:
* 预期结果:
*/
void test_fs_fd_leak(void)
{
YUNIT_ASSERT(TC_PASS == TC_PASS);
}
/*
* Copyright (C) 2020-2021 Alibaba Group Holding Limited
*/
#include <stdio.h>
#include "yunit/yunit.h"
#include "fs_test.h"
static int init(void)
{
return 0;
}
static int cleanup(void)
{
return 0;
}
static void setup(void)
{
}
static void teardown(void)
{
}
void aos_fs_test(void)
{
yunit_test_suite_t *suite;
suite = yunit_add_test_suite("fsapi", init, cleanup, setup, teardown);
yunit_add_test_case(suite, "fs.open", test_fs_open);
yunit_add_test_case(suite, "fs_write", test_fs_write);
yunit_add_test_case(suite, "fs_read", test_fs_read);
yunit_add_test_case(suite, "fs_stat", test_fs_stat);
yunit_add_test_case(suite, "fs_statfs", test_fs_statfs);
yunit_add_test_case(suite, "fs_link", test_fs_link);
// yunit_add_test_case(suite, "fs_fcntl", test_fs_fcntl);
//yunit_add_test_case(suite, "fs_pathconf", test_fs_pathconf);
//yunit_add_test_case(suite, "fs_fpathconf", test_fs_fpathconf);
//yunit_add_test_case(suite, "fs_utime", test_fs_utime);
yunit_add_test_case(suite, "fs_close", test_fs_close);
//yunit_add_test_case(suite, "fs_unlink", test_fs_unlink);
yunit_add_test_case(suite, "fs_fd_leak", test_fs_fd_leak);
yunit_add_test_case(suite, "fs_mkdir", test_fs_mkdir);
yunit_add_test_case(suite, "fs_readdir", test_fs_readdir);
//yunit_add_test_case(suite, "fs_chdir", test_fs_chdir);
yunit_add_test_case(suite, "fs_seekdir", test_fs_seekdir);
yunit_add_test_case(suite, "fs_rmdir", test_fs_rmdir);
// yunit_add_test_case(suite, "fs_mount", test_fs_mount);
}
AOS_TESTCASE(aos_fs_test);
/*
* Copyright (c) 2018 Intel Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <ztest.h>
#define ROOTFS_MNTP "/jsamp"
#define TEST_FILE ROOTFS_MNTP"/testfile.txt"
#define TEST_FILE1 ROOTFS_MNTP"/testfile1.txt"
#define TEST_DIR ROOTFS_MNTP"/testdir"
#define TEST_DIR_FILE ROOTFS_MNTP"/testdir/testfile.txt"
#define TEST_DIR_FILE1 ROOTFS_MNTP"/testdir/testfile1.txt"
extern const char test_str[];
void test_fs_mount(void);
void test_fs_open(void);
void test_fs_write(void);
void test_fs_read(void);
void test_fs_stat(void);
void test_fs_statfs(void);
void test_fs_link(void);
void test_fs_fcntl(void);
void test_fs_pathconf(void);
void test_fs_fpathconf(void);
void test_fs_utime(void);
void test_fs_close(void);
void test_fs_fd_leak(void);
void test_fs_unlink(void);
void test_fs_mkdir(void);
void test_fs_readdir(void);
void test_fs_chdir(void);
void test_fs_seekdir(void);
void test_fs_rmdir(void);
/*
* Copyright (c) 2016 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
*
* @brief Zephyr testing suite
*/
/**
* @brief Zephyr Tests
* @defgroup all_tests Zephyr Tests
* @{
* @}
*/
#ifndef __ZTEST_H__
#define __ZTEST_H__
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <yunit/yunit.h>
#define TC_PASS 0
#define TC_FAIL 1
#define TC_SKIP 2
#define TC_PRINT(x, ...) do { } while (0)
//#define TC_PRINT printf
#ifdef __cplusplus
extern "C" {
#endif
static inline void z_zassert(int cond,
const char *default_msg,
const char *file,
int line, const char *func,
const char *msg, ...)
{
if (!(cond)) {
va_list vargs;
va_start(vargs, msg);
printf("\n Assertion failed at %s:%d: %s: %s\n",
file, line, func, default_msg);
//vprintk(msg, vargs);
printf("\n");
va_end(vargs);
//ztest_test_fail();
}
#if CONFIG_ZTEST_ASSERT_VERBOSE == 2
else {
printf("\n Assertion succeeded at %s:%d (%s)\n",
file, line, func);
}
#endif
}
/**
* @defgroup ztest_assert Ztest assertion macros
* @ingroup ztest
*
* This module provides assertions when using Ztest.
*
* @{
*/
/**
* @brief Fail the test, if @a cond is false
*
* You probably don't need to call this macro directly. You should
* instead use zassert_{condition} macros below.
*
* @param cond Condition to check
* @param msg Optional, can be NULL. Message to print if @a cond is false.
* @param default_msg Message to print if @a cond is false
*/
#define zassert(cond, default_msg, msg, ...) \
z_zassert(cond, msg ? ("(" default_msg ")") : (default_msg), \
__FILE__, __LINE__, __func__, msg ? msg : "", ##__VA_ARGS__)
/**
* @brief Assert that this function call won't be reached
* @param msg Optional message to print if the assertion fails
*/
#define zassert_unreachable(msg, ...) zassert(0, "Reached unreachable code", \
msg, ##__VA_ARGS__)
/**
* @brief Assert that @a cond is true
* @param cond Condition to check
* @param msg Optional message to print if the assertion fails
*/
#define zassert_true(cond, msg, ...) zassert(cond, #cond " is false", \
msg, ##__VA_ARGS__)
/**
* @brief Assert that @a cond is false
* @param cond Condition to check
* @param msg Optional message to print if the assertion fails
*/
#define zassert_false(cond, msg, ...) zassert(!(cond), #cond " is true", \
msg, ##__VA_ARGS__)
/**
* @brief Assert that @a ptr is NULL
* @param ptr Pointer to compare
* @param msg Optional message to print if the assertion fails
*/
#define zassert_is_null(ptr, msg, ...) zassert((ptr) == NULL, \
#ptr " is not NULL", \
msg, ##__VA_ARGS__)
/**
* @brief Assert that @a ptr is not NULL
* @param ptr Pointer to compare
* @param msg Optional message to print if the assertion fails
*/
#define zassert_not_null(ptr, msg, ...) zassert((ptr) != NULL, \
#ptr " is NULL", msg, \
##__VA_ARGS__)
/**
* @brief Assert that @a a equals @a b
*
* @a a and @a b won't be converted and will be compared directly.
*
* @param a Value to compare
* @param b Value to compare
* @param msg Optional message to print if the assertion fails
*/
#define zassert_equal(a, b, msg, ...) zassert((a) == (b), \
#a " not equal to " #b, \
msg, ##__VA_ARGS__)
/**
* @brief Assert that @a a does not equal @a b
*
* @a a and @a b won't be converted and will be compared directly.
*
* @param a Value to compare
* @param b Value to compare
* @param msg Optional message to print if the assertion fails
*/
#define zassert_not_equal(a, b, msg, ...) zassert((a) != (b), \
#a " equal to " #b, \
msg, ##__VA_ARGS__)
/**
* @brief Assert that @a a equals @a b
*
* @a a and @a b will be converted to `void *` before comparing.
*
* @param a Value to compare
* @param b Value to compare
* @param msg Optional message to print if the assertion fails
*/
#define zassert_equal_ptr(a, b, msg, ...) \
zassert((void *)(a) == (void *)(b), #a " not equal to " #b, \
msg, ##__VA_ARGS__)
/**
* @brief Assert that @a a is within @a b with delta @a d
*
* @param a Value to compare
* @param b Value to compare
* @param d Delta
* @param msg Optional message to print if the assertion fails
*/
#define zassert_within(a, b, d, msg, ...) \
zassert(((a) > ((b) - (d))) && ((a) < ((b) + (d))), \
#a " not within " #b " +/- " #d, \
msg, ##__VA_ARGS__)
/**
* @brief Assert that 2 memory buffers have the same contents
*
* This macro calls the final memory comparison assertion macro.
* Using double expansion allows providing some arguments by macros that
* would expand to more than one values (ANSI-C99 defines that all the macro
* arguments have to be expanded before macro call).
*
* @param ... Arguments, see @ref zassert_mem_equal__
* for real arguments accepted.
*/
#define zassert_mem_equal(...) \
zassert_mem_equal__(__VA_ARGS__)
/**
* @brief Internal assert that 2 memory buffers have the same contents
*
* @note This is internal macro, to be used as a second expansion.
* See @ref zassert_mem_equal.
*
* @param buf Buffer to compare
* @param exp Buffer with expected contents
* @param size Size of buffers
* @param msg Optional message to print if the assertion fails
*/
#define zassert_mem_equal__(buf, exp, size, msg, ...) \
zassert(memcmp(buf, exp, size) == 0, #buf " not equal to " #exp, \
msg, ##__VA_ARGS__)
#ifdef __cplusplus
}
#endif
#endif /* __ZTEST_H__ */
/*
* Copyright (C) 2015-2023 Alibaba Group Holding Limited
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <yunit/yunit.h>
#include <aos/kernel.h>
#include "aos_hal_flash.h"
#include "kv_adapt.h"
#include "aos_system.h"
/* module name used by log print*/
#define MODULE_NAME "kv_test"
/* module parameters */
const char *test_key = "test_kv_key";
const char *test_val = "test_kv_value";
static void *kv_test_sem = NULL;
static uint8_t sem_flag = 0;
/* test kv init */
void kv_test_init(void)
{
int ret;
//ret=aos_hal_flash_init(HAL_PARTITION_APPLICATION);
YUNIT_ASSERT_EQUAL(ret, 0);
}
#if 0
/* test kv item */
void kv_test_item(void)
{
int ret;
int set_len = strlen(test_val);
int get_len;
char get_value[32] = {0};
ret = kv_item_set(test_key, test_val, set_len, 1); /* set kv item */
YUNIT_ASSERT_EQUAL(ret, 0);
ret = kv_item_get(test_key, get_value, &get_len); /* get kv item */
YUNIT_ASSERT_EQUAL(ret, 0);
YUNIT_ASSERT_EQUAL(get_len, set_len);
ret = strcmp(get_value, test_val);
YUNIT_ASSERT_EQUAL(ret, 0);
ret = kv_item_delete(test_key); /* del kv item */
YUNIT_ASSERT_EQUAL(ret, 0);
}
#endif
/* test kv flash */
void kv_test_flash(void)
{
int ret;
uint8_t txdata = 0x5a;
uint8_t rxdata;
uint8_t offset = 0;
ret = kv_flash_write(0, &txdata, 1);
YUNIT_ASSERT_EQUAL(ret, 0);
kv_flash_read(offset, &rxdata, 1);
YUNIT_ASSERT_EQUAL(rxdata, txdata);
ret = kv_flash_erase(0, 1);
YUNIT_ASSERT_EQUAL(ret, 0);
kv_flash_read(offset, &rxdata, 1);
YUNIT_ASSERT_EQUAL(rxdata, 0xff);
}
/* test kv lock */
void kv_test_lock(void)
{
int ret;
void *lock_pin = NULL;
lock_pin = kv_lock_create();
YUNIT_ASSERT_TRUE(lock_pin != NULL);
ret = kv_lock(lock_pin);
YUNIT_ASSERT_EQUAL(ret, 0);
ret = kv_unlock(lock_pin);
YUNIT_ASSERT_EQUAL(ret, 0);
ret = kv_lock_free(lock_pin);
YUNIT_ASSERT_EQUAL(ret, 0);
}
/* test kv malloc */
void kv_test_malloc(void)
{
int ret;
void *malloc_pin = NULL;
malloc_pin = kv_malloc(1);
YUNIT_ASSERT_TRUE(malloc_pin != NULL);
kv_free(malloc_pin);
}
/* test kv task */
void _kv_test_process(void *arg)
{
while (1)
{
aos_printf("[yunit test]test kc task\n");
kv_sem_wait(kv_test_sem);
sem_flag = 1;
aos_msleep(100);
break;
}
kv_delete_task();
}
void kv_test_task(void)
{
int ret;
kv_test_sem = kv_sem_create(); /* test kv sem */
YUNIT_ASSERT_TRUE(kv_test_sem != NULL);
ret = kv_start_task("kv_test", _kv_test_process, NULL, 4096); /* test kv task */
YUNIT_ASSERT_EQUAL(ret, 0);
if (ret == 0)
{
ret = kv_sem_post_all(kv_test_sem);
YUNIT_ASSERT_EQUAL(ret, 0);
}
}
\ No newline at end of file
/*
* Copyright (C) 2020-2023 Alibaba Group Holding Limited
*/
#include <stdio.h>
#include <sched.h>
#include <pthread.h>
#include <yunit/yunit.h>
extern void kv_test_init(void);
extern void kv_test_flash(void);
extern void kv_test_lock(void);
extern void kv_test_malloc(void);
extern void kv_test_task(void);
static int init(void)
{
return 0;
}
static int cleanup(void)
{
return 0;
}
static void setup(void)
{
}
static void teardown(void)
{
}
static void setup_pri_save(void)
{
}
static void teardown_pri_restore(void)
{
}
static yunit_test_case_t aos_kv_testcases[] = {
//{ "kv_test_init", kv_test_init},
//{ "kv_test_flash", kv_test_flash},
//{ "kv_test_lock", kv_test_lock},
//{ "kv_test_malloc", kv_test_malloc},
{ "kv_test_task", kv_test_task},
YUNIT_TEST_CASE_NULL
};
static yunit_test_suite_t suites[] = {
{ "kv", init, cleanup, setup, teardown, aos_kv_testcases },
YUNIT_TEST_SUITE_NULL
};
void aos_kv_test(void)
{
yunit_add_test_suites(suites);
}
AOS_TESTCASE(aos_kv_test);
\ No newline at end of file
/*
* Copyright (C) 2015-2023 Alibaba Group Holding Limited
*/
#include <stdio.h>
#include <stdlib.h>
#include <aos/kernel.h>
#include "yunit/yunit.h"
//#include <stdio.h>
//#include <string.h>
//#include <stdint.h>
//#include <aos/kernel.h>
//
/**
* The use case allocates the same memory in three different ways.
*/
/* module name used by ulog */
#define MODULE_NAME "aos_mem_test"
/* four of these types of structures are allocated in the use case */
struct message {
uint8_t type;
uint16_t length;
uint8_t data[10];
};
int mem_alloc(void)
{
struct message *messages_ptr = NULL;
/* way-1 */
/* allocate four message structures using aos_malloc */
messages_ptr = (struct message *)aos_malloc(sizeof(struct message) * 4);
/**
* after allocating memory, you need to determine whether the return value is NULL.
* NULL means the allocation failed.
*/
if (messages_ptr == NULL) {
printf("[%s]aos_malloc error\n", MODULE_NAME);
return -1;
}
printf("[%s]aos_malloc success!\n", MODULE_NAME);
/* all newly allocated memory areas are set to 0 */
memset(messages_ptr, 0, sizeof(struct message) * 4);
/* free memory when memory is used up */
aos_free(messages_ptr);
messages_ptr = NULL;
/* way-2 */
/* allocate four message structures using aos_zalloc. This function clears memory automatically. */
messages_ptr = (struct message *)aos_zalloc(sizeof(struct message) * 4);
/**
* after allocating memory, you need to determine whether the return value is NULL.
* NULL means the allocation failed.
*/
if (messages_ptr == NULL) {
printf("[%s]aos_zalloc error\n", MODULE_NAME);
return -1;
}
printf("[%s]aos_zalloc success!\n", MODULE_NAME);
/* free memory when memory is used up */
aos_free(messages_ptr);
messages_ptr = NULL;
/* way-3 */
/* allocate four message structures using aos_calloc. This function clears memory automatically.*/
messages_ptr = (struct message *)aos_calloc(4, sizeof(struct message));
/**
* after allocating memory, you need to determine whether the return value is NULL.
* NULL means the allocation failed.
*/
if (messages_ptr == NULL) {
printf("[%s]aos_calloc error\n", MODULE_NAME);
return -1;
}
printf("[%s]aos_calloc success!\n", MODULE_NAME);
/* free memory when memory is used up */
aos_free(messages_ptr);
messages_ptr = NULL;
return 0;
}
/**
* This use case demonstrates that the dynamically allocated memory is out of use
* and aos_realloc is called to expand the memory.
*/
int mem_realloc(void)
{
struct message *old_ptr = NULL, *new_ptr = NULL;
/* allocate four message structures using aos_malloc */
old_ptr = (struct message *)aos_malloc(sizeof(struct message) * 4);
/**
* after allocating memory, you need to determine whether the return value is NULL.
* NULL means the allocation failed.
*/
if (old_ptr == NULL) {
printf("[%s]aos_malloc error\n", MODULE_NAME);
return -1;
}
/* all newly allocated memory areas are set to 0 */
memset(old_ptr, 0, sizeof(struct message) * 4);
/**
* in the process of use, it was found that 4 structures were not enough,
* so we need to expand to 6
*/
new_ptr = aos_realloc(old_ptr, sizeof(struct message) * 6);
if (new_ptr == NULL) {
/* The memory pointed to by old_ptr is not automatically freed when aos_realloc fails */
aos_free(old_ptr);
old_ptr = NULL;
printf("[%s]aos_realloc task1 error\n", MODULE_NAME);
return -1;
}
printf("[%s]aos_realloc success!\n", MODULE_NAME);
/**
* When aos_realloc executes successfully, the contents of old_ptr are automatically copied
* to new_ptr, and old_ptr is freed, after which the user can use new_ptr's new memory.
*/
/* free memory when memory is used up */
aos_free(new_ptr);
new_ptr = NULL;
return 0;
}
void kernel_test_mem_1(void)
{
YUNIT_ASSERT(mem_alloc() == 0);
}
void kernel_test_mem_2(void)
{
YUNIT_ASSERT(mem_realloc() == 0);
}
static void CASE_aosapi_kernel_mm_param()
{
/* dumpsys_mm_info_func here */
aos_malloc(0);
/* coredump here */
#if 0
aos_free(NULL);
#endif
}
static void CASE_aosapi_kernel_mm_allocfree()
{
const int COUNT = 1024;
int *ptr = aos_malloc(sizeof(int)*COUNT);
memset(ptr, 0, COUNT);
int i = 0;
for(; i<COUNT; i++) {
*(ptr+i) = i;
}
i = 0;
for(; i<COUNT; i++) {
YUNIT_ASSERT_MSG((int)*(ptr+i)==i, "*(ptr+i)=%d", i);
}
aos_free(ptr);
ptr = NULL;
}
void aosapi_kernel_mm_test_entry(yunit_test_suite_t *suite)
{
yunit_add_test_case(suite, "kernel.mm.param", CASE_aosapi_kernel_mm_param);
yunit_add_test_case(suite, "kernel.mm.allocfree", CASE_aosapi_kernel_mm_allocfree);
yunit_add_test_case(suite, "kernel.mm.test1", kernel_test_mem_1);
yunit_add_test_case(suite, "kernel.mm.test2", kernel_test_mem_2);
}
/*
* Copyright (C) 2015-2023 Alibaba Group Holding Limited
*/
#include <stdio.h>
#include <stdlib.h>
#include "aos/kernel.h"
#include "yunit/yunit.h"
#include"aos_system.h"
static aos_mutex_t g_mutex1;
static aos_mutex_t g_mutex2;
static aos_sem_t sync_sem;
static const uint32_t LOOP_COUNT = 1000000;
#define TEST_TASK_STACK_SIZE (8192)
///////////////////////////////////////////////////////////////////////////////////////////////
static void CASE_aosapi_kernel_mutex_param()
{
#if 0
int ret;
aos_mutex_t mutex;
// FIXME: null pointer:coredump
ret = aos_mutex_new(NULL);
YUNIT_ASSERT_MSG(ret==RHINO_NULL_PTR, "ret=%d", ret);
#endif
#if 0
// FIXME: null pointer:coredump
ret = aos_mutex_lock(NULL, AOS_WAIT_FOREVER);
YUNIT_ASSERT_MSG(ret==RHINO_NULL_PTR, "ret=%d", ret);
#endif
#if 0
// FIXME: null pointer:coredump
ret = aos_mutex_unlock(NULL);
YUNIT_ASSERT_MSG(ret==RHINO_NULL_PTR, "ret=%d", ret);
#endif
#if 0
ret = aos_mutex_free(NULL);
YUNIT_ASSERT_MSG(ret==RHINO_NULL_PTR, "ret=%d", ret);
#endif
}
///////////////////////////////////////////////////////////////////////////////////////////////
void TASK_aosapi_kernel_mutex_lock1(void *arg)
{
int ret, i;
int *pflag = (int*)arg;
for(i = 0; i < LOOP_COUNT; i++) {
ret = aos_mutex_lock(&g_mutex1, AOS_WAIT_FOREVER);
YUNIT_ASSERT_MSG(ret==0, "ret=%d", ret);
(*pflag)++;
ret = aos_mutex_unlock(&g_mutex1);
YUNIT_ASSERT_MSG(ret==0, "ret=%d", ret);
}
aos_sem_signal(&sync_sem);
aos_task_exit(0);
}
void TASK_aosapi_kernel_mutex_lock2(void *arg)
{
int ret, i;
int *pflag = (int*)arg;
for(i = 0; i < LOOP_COUNT; i++) {
ret = aos_mutex_lock(&g_mutex1, AOS_WAIT_FOREVER);
YUNIT_ASSERT_MSG(ret==0, "ret=%d", ret);
(*pflag)--;
ret= aos_mutex_unlock(&g_mutex1);
YUNIT_ASSERT_MSG(ret==0, "ret=%d", ret);
}
aos_sem_signal(&sync_sem);
aos_task_exit(0);
}
static void CASE_aosapi_kernel_mutex_lock()
{
int ret = 0;
ret = aos_mutex_new(&g_mutex1);
YUNIT_ASSERT_MSG(ret==0, "ret=%d", ret);
ret = aos_sem_new(&sync_sem, 0);
YUNIT_ASSERT_MSG(ret==0, "ret=%d", ret);
int flag = 0;
ret = aos_task_new("TASK_aosapi_kernel_mutex_lock_wait1",
TASK_aosapi_kernel_mutex_lock1, &flag, TEST_TASK_STACK_SIZE);
YUNIT_ASSERT_MSG(ret==0, "ret=%d", ret);
ret = aos_task_new("TASK_aosapi_kernel_mutex_lock_wait2",
TASK_aosapi_kernel_mutex_lock2, &flag, TEST_TASK_STACK_SIZE);
YUNIT_ASSERT_MSG(ret==0, "ret=%d", ret);
ret = aos_sem_wait(&sync_sem, AOS_WAIT_FOREVER);
YUNIT_ASSERT_MSG(ret==0, "ret=%d", ret);
ret = aos_sem_wait(&sync_sem, AOS_WAIT_FOREVER);
YUNIT_ASSERT_MSG(ret==0, "ret=%d", ret);
aos_mutex_free(&g_mutex1);
aos_sem_free(&sync_sem);
YUNIT_ASSERT_MSG(flag==0, "flag=%d", flag);
}
///////////////////////////////////////////////////////////////////////////////////////////////
void TASK_aosapi_kernel_mutex_deadlock1(void *arg)
{
int ret;
ret = aos_mutex_lock(&g_mutex1, AOS_WAIT_FOREVER);
YUNIT_ASSERT_MSG(ret==0, "ret=%d", ret);
ret = aos_mutex_lock(&g_mutex2, AOS_WAIT_FOREVER);
YUNIT_ASSERT_MSG(ret==0, "ret=%d", ret);
aos_mutex_unlock(&g_mutex1);
aos_sem_signal(&sync_sem);
}
void TASK_aosapi_kernel_mutex_deadlock2(void *arg)
{
int ret;
ret = aos_mutex_lock(&g_mutex2, AOS_WAIT_FOREVER);
YUNIT_ASSERT_MSG(ret==0, "ret=%d", ret);
ret = aos_mutex_lock(&g_mutex1, AOS_WAIT_FOREVER);
YUNIT_ASSERT_MSG(ret==0, "ret=%d", ret);
aos_mutex_unlock(&g_mutex2);
aos_sem_signal(&sync_sem);
}
static void CASE_aosapi_kernel_mutex_deadlock()
{
int ret = 0;
ret = aos_mutex_new(&g_mutex1);
YUNIT_ASSERT_MSG(ret==0, "ret=%d", ret);
ret = aos_mutex_new(&g_mutex2);
YUNIT_ASSERT_MSG(ret==0, "ret=%d", ret);
ret = aos_sem_new(&sync_sem, 0);
ret = aos_task_new("TASK_aosapi_kernel_mutex_deadlock1",
TASK_aosapi_kernel_mutex_deadlock1, NULL, TEST_TASK_STACK_SIZE);
YUNIT_ASSERT_MSG(ret==0, "ret=%d", ret);
ret = aos_task_new("TASK_aosapi_kernel_mutex_deadlock2",
TASK_aosapi_kernel_mutex_deadlock2, NULL, TEST_TASK_STACK_SIZE);
YUNIT_ASSERT_MSG(ret==0, "ret=%d", ret);
ret = aos_sem_wait(&sync_sem, AOS_WAIT_FOREVER);
YUNIT_ASSERT_MSG(ret==0, "ret=%d", ret);
ret = aos_sem_wait(&sync_sem, AOS_WAIT_FOREVER);
YUNIT_ASSERT_MSG(ret==0, "ret=%d", ret);
aos_mutex_free(&g_mutex1);
aos_sem_free(&sync_sem);
}
///////////////////////////////////////////////////////////////////////////////////////////////
static void CASE_aosapi_kernel_mutex_repeatlock()
{
int ret;
ret = aos_mutex_new(&g_mutex1);
YUNIT_ASSERT_MSG(ret==0, "ret=%d", ret);
ret = aos_mutex_lock(&g_mutex1,AOS_WAIT_FOREVER);
YUNIT_ASSERT_MSG(ret==0, "ret=%d", ret);
// TODO: test fail
ret = aos_mutex_lock(&g_mutex1,AOS_WAIT_FOREVER);
YUNIT_ASSERT_MSG(ret==0, "ret=%d", ret);
aos_mutex_free(&g_mutex1);
}
///////////////////////////////////////////////////////////////////////////////////////////////
void TASK_aosapi_kernel_mutex_lock_timeout(void *arg)
{
int ret;
ret = aos_mutex_lock(&g_mutex1, 2000);
YUNIT_ASSERT_MSG(ret==0, "ret=%d", ret);
ret = aos_mutex_lock(&g_mutex1, AOS_NO_WAIT);
YUNIT_ASSERT_MSG(ret==0, "ret=%d", ret);
aos_sem_signal(&sync_sem);
aos_task_exit(0);
}
static void CASE_aosapi_kernel_mutex_lock_timeout()
{
int ret;
ret = aos_sem_new(&sync_sem, 0);
YUNIT_ASSERT_MSG(ret==0, "ret=%d", ret);
ret = aos_mutex_new(&g_mutex1);
YUNIT_ASSERT_MSG(ret==0, "ret=%d", ret);
ret = aos_mutex_lock(&g_mutex1, AOS_WAIT_FOREVER);
YUNIT_ASSERT_MSG(ret==0, "ret=%d", ret);
ret = aos_task_new("TASK_aosapi_kernel_mutex_lock_timeout",
TASK_aosapi_kernel_mutex_lock_timeout, NULL, TEST_TASK_STACK_SIZE);
YUNIT_ASSERT_MSG(ret==0, "ret=%d", ret);
ret = aos_sem_wait(&sync_sem,AOS_WAIT_FOREVER);
YUNIT_ASSERT_MSG(ret==0, "ret=%d", ret);
aos_sem_free(&sync_sem);
aos_mutex_free(&g_mutex1);
}
/**
* 该示例使用互斥量实现共享资源的互斥访问,具体场景为创建任务A和认为B,以及一互斥量。任务A和任务B使用互斥量同时访问共享数据区,访问共享数据区时使用互斥量做保护。
* 示例说明如下:
* 1. t0时刻,任务T调用aos_mutex_create()创建一互斥量。任务T然后调用aos_task_create()创建任务A和任务B。任务A得到运行,并获取互斥量对数据区record_status进行读写操作。
* 2. t1时刻,任务A因时间片耗尽,让出CPU,任务B得到运行。
* 3. t2时刻,任务B因无法获得互斥量,进入阻塞状态,任务A得到运行。
* 4. t3时刻,任务A对数据区record_status的操作完成,释放互斥量,任务B获得互斥量开始对数据区record_status进行读写操作。
*/
/* module name used by log print*/
#define MODULE_NAME "aos_mutex_test"
/* taskA parameters */
#define TASKA_NAME "taskA"
#define TASKA_PRI 50
#define TASKA_STACKSIZE 4096
/* taskB parameters */
#define TASKB_NAME "taskB"
#define TASKB_PRI 50
#define TASKB_STACKSIZE 4096
/* mutex handle */
static aos_mutex_t mutex_handle;
static int test_cnt_A = 0;
static int test_cnt_B = 0;
/*
* simulated critical section resources.
* The critical resource consistency condition is that all four fields are equal,
* otherwise the critical resource is destroyed.
*/
static struct record {
uint32_t field1;
uint32_t field2;
uint32_t field3;
uint32_t field4;
} record_status;
/* task entry */
static void task_entry(void *arg)
{
uint32_t i = 0;
aos_status_t status;
int test_count = 10;
int *run_count = arg;
while (test_count--) {
/**
* In order to ensure the consistency of the critical resource,
* the task must obtain a mutex to access the critical resource.
*/
status = aos_mutex_lock(&mutex_handle, AOS_WAIT_FOREVER);
if (status != 0) {
printf("[%s] %p mutex lock error\n", MODULE_NAME, (void *)aos_task_self());
continue;
}
/**
* read critical resource.
* If the four fields are not equal, the critical resource is destroyed.
*/
printf("[%s] %p field1=%ld, field2=%ld, field3=%ld, field4=%ld\n", MODULE_NAME,(void *)aos_task_self(), record_status.field1,
record_status.field2, record_status.field3, record_status.field4);
printf("[%s] priority=%x \n",MODULE_NAME,aos_get_default_task_priority());
/* modify critical resources */
i = rand();
record_status.field1 = i;
record_status.field2 = i;
record_status.field3 = i;
record_status.field4 = i;
status = aos_mutex_unlock(&mutex_handle);
if (status != 0) {
printf("[%s]%p mutex unlock error\n", MODULE_NAME, (void *)aos_task_self());
return;
}
(*run_count)++;
aos_msleep(10); /* sleep 1000ms */
}
}
static int aos_mutex_test(void)
{
aos_status_t status;
bool is_valid;
test_cnt_A = 0;
test_cnt_B = 0;
/* create mutex statically */
status = aos_mutex_create(&mutex_handle, 0);
if (status != 0) {
printf("[%s]create mutex error\n", MODULE_NAME);
return -1;
}
is_valid = aos_mutex_is_valid(&mutex_handle);
YUNIT_ASSERT_MSG(is_valid==true, "is_valid=%d", is_valid);
/* Task1 and task2 both acess critical resources. */
status = aos_task_new(TASKA_NAME, task_entry, &test_cnt_A, TASKA_STACKSIZE);
if (status != 0) {
aos_mutex_free(&mutex_handle);
printf("[%s]create %s error\n", MODULE_NAME, TASKA_NAME);
return -1;
}
status = aos_task_new(TASKB_NAME, task_entry, &test_cnt_B, TASKB_STACKSIZE);
if (status != 0) {
aos_mutex_free(&mutex_handle);
printf("[%s]create %s error\n", MODULE_NAME, TASKB_NAME);
return -1;
}
aos_msleep(500);
if ((test_cnt_A == 10) && (test_cnt_B == 10)) {
return 0;
}
return -1;
}
void kernel_test_mutex(void)
{
YUNIT_ASSERT(aos_mutex_test() == 0);
}
void aosapi_kernel_mutex_test_entry(yunit_test_suite_t* suite)
{
yunit_add_test_case(suite, "kernel.mutex.new", kernel_test_mutex);
yunit_add_test_case(suite, "kernel.mutex.param", CASE_aosapi_kernel_mutex_param);
yunit_add_test_case(suite, "kernel.mutex.lockwait", CASE_aosapi_kernel_mutex_lock);
// yunit_add_test_case(suite, "kernel.mutex.locktimeout", CASE_aosapi_kernel_mutex_lock_timeout);
// yunit_add_test_case(suite, "kernel.mutex.repeat", CASE_aosapi_kernel_mutex_repeatlock);
// yunit_add_test_case(suite, "kernel.mutex.deadlock", CASE_aosapi_kernel_mutex_deadlock);
(void)CASE_aosapi_kernel_mutex_deadlock;
(void)CASE_aosapi_kernel_mutex_lock;
(void)CASE_aosapi_kernel_mutex_lock_timeout;
(void)CASE_aosapi_kernel_mutex_deadlock;
}
/*
* Copyright (C) 2015-2023 Alibaba Group Holding Limited
*/
#include <stdio.h>
#include <stdlib.h>
#include <aos/kernel.h>
#include <assert.h>
#include "yunit/yunit.h"
#include <errno.h>
#define TEST_TASK_STACK_SIZE (8192)
typedef struct
{
int id;
int len;
char msg[32];
} Message;
#define TEST_QUEUE_MAX_MSG_SIZE (sizeof(Message))
#define TEST_QUEUE_MAX_MSG_COUNT (8)
#define TEST_QUEUE_SIZE (TEST_QUEUE_MAX_MSG_SIZE * TEST_QUEUE_MAX_MSG_COUNT)
static char queue_buf[TEST_QUEUE_SIZE] = { 0 };
static aos_queue_t g_queue;
static aos_sem_t sync_sem;
static Message send_msg;
static Message recv_msg;
static unsigned int recv_size = 0;
static aos_sem_t tmp_sem;
static aos_queue_t queue;
static void CASE_aosapi_kernel_queue_param()
{
int ret;
bool is_valid;
/* aos_queue_new invalid param test */
#if 0
// TODO: coredump
ret = aos_queue_new(NULL, queue_buf, TEST_QUEUE_SIZE, TEST_QUEUE_MAX_MSG_SIZE);
YUNIT_ASSERT_MSG(ret==RHINO_NULL_PTR, "ret=%d", ret);
#endif
ret = aos_queue_new(&queue, NULL, TEST_QUEUE_SIZE, TEST_QUEUE_MAX_MSG_SIZE);
YUNIT_ASSERT_MSG(ret == 0, "ret=%d", ret);
is_valid = aos_queue_is_valid(&queue);
YUNIT_ASSERT_MSG(is_valid==true, "is_valid=%d", is_valid);
ret = aos_queue_new(&queue, queue_buf, 0, TEST_QUEUE_MAX_MSG_SIZE);
YUNIT_ASSERT_MSG(ret == 0, "ret=%d", ret);
ret = aos_queue_new(&queue, queue_buf, TEST_QUEUE_SIZE, 0);
YUNIT_ASSERT_MSG(ret == 0, "ret=%d", ret);
/* aos_queue_send invalid param test */
#if 0
// TODO: coredump
ret = aos_queue_send(NULL, &send_msg, sizeof(send_msg));
YUNIT_ASSERT_MSG(ret==RHINO_NULL_PTR, "ret=%d", ret);
#endif
// create fail
ret = aos_queue_new(&queue, queue_buf, TEST_QUEUE_SIZE,
TEST_QUEUE_MAX_MSG_SIZE);
YUNIT_ASSERT_MSG(ret == 0, "ret=%d", ret);
ret = aos_queue_send(&queue, NULL, sizeof(send_msg));
YUNIT_ASSERT_MSG(ret == 0, "ret=%d", ret);
ret = aos_queue_send(&queue, &send_msg, 0);
YUNIT_ASSERT_MSG(ret == 0, "ret=%d", ret);
ret = aos_queue_send(&queue, &send_msg, TEST_QUEUE_MAX_MSG_SIZE);
YUNIT_ASSERT_MSG(ret == 0, "ret=%d", ret);
ret = aos_sem_new(&tmp_sem, 0);
YUNIT_ASSERT_MSG(ret == 0, "ret=%d", ret);
ret = aos_queue_send((aos_queue_t *)&tmp_sem, &send_msg, sizeof(send_msg));
YUNIT_ASSERT_MSG(ret == 0, "ret=%d", ret);
aos_sem_free(&tmp_sem);
/* aos_queue_recv invalid param test */
#if 0
// TODO: coredump
ret = aos_queue_recv(NULL, 10, &recv_msg, &recv_size);
YUNIT_ASSERT(ret == RHINO_NULL_PTR);
#endif
ret = aos_queue_recv(&queue, 0, &recv_msg, &recv_size);
YUNIT_ASSERT_MSG(ret == 0, "ret=%d", ret);
ret = aos_queue_recv(&queue, AOS_WAIT_FOREVER, NULL, &recv_size);
YUNIT_ASSERT_MSG(ret != 0, "ret=%d", ret);
ret = aos_queue_recv(&queue, AOS_WAIT_FOREVER, &recv_msg, NULL);
YUNIT_ASSERT_MSG(ret != 0, "ret=%d", ret);
aos_sem_new(&tmp_sem, 0);
ret = aos_queue_recv((aos_queue_t *)&tmp_sem, AOS_WAIT_FOREVER, &recv_msg,
&recv_size);
YUNIT_ASSERT_MSG(ret != 0, "ret=%d", ret);
aos_sem_free(&tmp_sem);
aos_queue_free(&queue);
/* aos_queue_free invalid param test */
#if 0
aos_queue_free(NULL);
#endif
#if 0
aos_sem_new(&tmp_sem, 0);
aos_queue_free((aos_queue_t*)&tmp_sem);
YUNIT_ASSERT_MSG(ret==RHINO_KOBJ_TYPE_ERR, "ret=%d", ret);
// aos_sem_free(&tmp_sem); // already free
#endif
}
static void TASK_aosapi_kernel_queue_recv(void *arg)
{
int ret;
int i = 1;
for (; i < 10; i++) {
memset(&recv_msg, 0, sizeof(recv_msg));
ret = aos_queue_recv(&g_queue, 500, &recv_msg, &recv_size);
YUNIT_ASSERT_MSG(ret == 0, "ret=%d", ret);
YUNIT_ASSERT_MSG(recv_size == TEST_QUEUE_MAX_MSG_SIZE, "recv_size=%d",
recv_size);
YUNIT_ASSERT_MSG(recv_msg.id == i, "recv_msg.id=%d", i);
YUNIT_ASSERT_MSG(recv_msg.len == 5, "recv_msg.leb=5");
YUNIT_ASSERT_MSG(strcmp(recv_msg.msg, "hello") == 0, "recv_msg.msg=%s",
"hello");
}
aos_sem_signal(&sync_sem);
}
static void TASK_aosapi_kernel_queue_send(void *arg)
{
int ret;
int i = 1;
for (; i < 10; i++) {
memset(&send_msg, 0, sizeof(send_msg));
send_msg.id = i;
send_msg.len = 5;
strcpy(send_msg.msg, "hello");
ret = aos_queue_send(&g_queue, &send_msg, sizeof(send_msg));
YUNIT_ASSERT_MSG(ret == 0, "ret=%d", ret);
aos_msleep(50);
}
aos_sem_signal(&sync_sem);
}
static void CASE_aosapi_kernel_queue_send_recv()
{
int ret;
ret = aos_sem_new(&sync_sem, 0);
YUNIT_ASSERT_MSG(ret == 0, "ret=%d", ret);
// TODO: nullptr coredump
ret = aos_queue_new(&g_queue, queue_buf, TEST_QUEUE_SIZE,
TEST_QUEUE_MAX_MSG_SIZE);
YUNIT_ASSERT_MSG(ret == 0, "ret=%d", ret);
assert(ret == 0);
ret =
aos_task_new("TASK_aosapi_kernel_queue_send_testcase",
TASK_aosapi_kernel_queue_send, NULL, TEST_TASK_STACK_SIZE);
YUNIT_ASSERT_MSG(ret == 0, "ret=%d", ret);
ret =
aos_task_new("TASK_aosapi_kernel_queue_recv_testcase",
TASK_aosapi_kernel_queue_recv, NULL, TEST_TASK_STACK_SIZE);
YUNIT_ASSERT_MSG(ret == 0, "ret=%d", ret);
assert(ret == 0);
ret = aos_sem_wait(&sync_sem, AOS_WAIT_FOREVER);
YUNIT_ASSERT_MSG(ret == 0, "ret=%d", ret);
ret = aos_sem_wait(&sync_sem, AOS_WAIT_FOREVER);
YUNIT_ASSERT_MSG(ret == 0, "ret=%d", ret);
aos_sem_free(&sync_sem);
aos_queue_free(&g_queue);
}
static void CASE_aosapi_kernel_queue_full()
{
int ret, i;
// create fail
ret = aos_queue_new(&g_queue, queue_buf, TEST_QUEUE_SIZE,
TEST_QUEUE_MAX_MSG_SIZE);
YUNIT_ASSERT_MSG(ret == 0, "ret=%d", ret);
for (i = 0; i < TEST_QUEUE_MAX_MSG_COUNT - 1; i++) {
ret = aos_queue_send(&g_queue, &send_msg, sizeof(send_msg));
YUNIT_ASSERT_MSG(ret == 0, "ret=%d", ret);
}
ret = aos_queue_send(&g_queue, &send_msg, sizeof(send_msg));
YUNIT_ASSERT_MSG(ret == 0, "ret=%d", ret);
aos_queue_free(&g_queue);
}
/**
* 该示例使用消息队列实现任务间数据同步,具体场景为创建任务A和认为B,以及一消息队列。\n\r
* 任务A作为生产者循环向消息队列发送消息,任务B作为消费者循环从消息队列接收消息,
* 一般情况下,消费者处理数据是要花费很长时间,所以会导致消息产生的速度大于消息处理的速度,使得消息队列溢出。
* 所以可以通过调整任务B优先级大于任务A来避免这种情况,或者使用信号量来控制数据收发同步。
* 示例说明如下:
* 1. t0时刻,任务T调用aos_queue_new()创建一互斥量。任务T然后调用aos_task_create()创建任务A和任务B,任务A优先级设置为31,任务B优先级设置为30。任务B因消息队列无消息而阻塞,任务A得到运行向消息队列发送消息。
* 2. t1时刻,任务B因从消息队列读取到消息而解除阻塞,任务B对消息进行处理后继续等待新的消息到来。
* 3. t2时刻,任务A向消息队列发送消息。
* 4. t3时刻,重复t1时刻的操作。
*/
/* module name used by log print */
#define MODULE_NAME "aos_queue_test"
/* taskA parameters */
#define TASKA_NAME "taskA"
#define TASKA_PRIO 31
#define TASKA_STACKSIZE 4096
/* taskB parameters */
#define TASKB_NAME "taskB"
#define TASKB_PRIO 30
#define TASKB_STACKSIZE 4096
/* queue resource */
#define MESSAGE_MAX_LENGTH 10 /* maximum message length */
/* Static memory for static creation */
static aos_queue_t queue_handle; /* queue handle */
static char queue_buffer[MESSAGE_MAX_LENGTH * 10]; /* for the internal buffer of the queue */
static uint8_t message_id = 0;
static int send_cnt = 0;
static int recv_cnt = 0;
/* task entry for taskA*/
static void taskA_entry(void *arg)
{
uint32_t i;
aos_status_t status;
char message_buf[MESSAGE_MAX_LENGTH]; /* buffer used to send message */
int test_count = 10;
while (test_count--) {
/**
* generate message. The sequence of messages is as follows:
* 0123456789
* 1234567890
* 2345678901
* ......
*/
for (i = 0; i < sizeof(message_buf); i++) {
message_buf[i] = (message_id + i) % 10;
}
message_id++;
/* send message. The message length must not exceed the maximum message length */
status = aos_queue_send(&queue_handle, (void *)message_buf, sizeof(message_buf));
if (status != 0) {
printf("[%s]send buf queue error\n", MODULE_NAME);
continue;
}
send_cnt++;
aos_msleep(10); /* sleep 1000ms */
}
}
/* task entry for taskB*/
static void taskB_entry(void *arg)
{
uint32_t i;
aos_status_t status;
/* The buffer must be greater than or equal to the maximum message length */
char message_buf[MESSAGE_MAX_LENGTH];
size_t rev_size = 0;
int test_count = 10;
while (test_count--) {
/**
* receive message. The task will wait until it receives the message.
* rev_size is set to the actual length of the received message.
*/
status = aos_queue_recv(&queue_handle, AOS_WAIT_FOREVER, (void *)message_buf, &rev_size);
if (status == 0) {
/* show message data */
printf("[%s]%d recv message : ", MODULE_NAME, rev_size);
if (rev_size != MESSAGE_MAX_LENGTH) {
continue;
}
for (i = 0; i < rev_size; i++) {
printf("%d", message_buf[i]);
if (message_buf[i] != (((message_id - 1) + i) % 10)) {
printf("\r\n");
continue;
}
}
printf("\r\n");
recv_cnt++;
} else {
printf("[%s]recv buf queue error\n", MODULE_NAME);
}
}
}
static int aos_queue_test(void)
{
aos_status_t status;
aos_task_t taskA_handle;
aos_task_t taskB_handle;
recv_cnt = 0;
send_cnt = 0;
/**
* create a queue.
* queue: queue_handle(aos_queue_t struct variable)
* buf: queue_buffer(for the internal buffer of the queue)
* size: sizeof(queue_buffer) is the length of buf
* max_msg: MESSAGE_MAX_LENGTH(maximum message length, here is 10 byte)
*/
status = aos_queue_new(&queue_handle, (void *)queue_buffer, sizeof(queue_buffer),
MESSAGE_MAX_LENGTH);
if (status != 0) {
printf("[%s]create queue error\n", MODULE_NAME);
return -1;
}
/* TaskA is a producer that produces a set of data every second. */
status = aos_task_create(&taskA_handle, TASKA_NAME, taskA_entry, NULL, NULL, TASKA_STACKSIZE, TASKA_PRIO, AOS_TASK_AUTORUN);
if (status != 0) {
aos_queue_free(&queue_handle);
printf("[%s]create %s error\n", MODULE_NAME, TASKA_NAME);
return -1;
}
/* TaskB is the consumer that processes the data sent by taskA. */
status = aos_task_create(&taskB_handle, TASKB_NAME, taskB_entry, NULL, NULL, TASKB_STACKSIZE, TASKB_PRIO, AOS_TASK_AUTORUN);
if (status != 0) {
aos_queue_free(&queue_handle);
printf("[%s]create %s error\n", MODULE_NAME, TASKB_NAME);
return -1;
}
aos_msleep(500); /* sleep 500ms */
if ((recv_cnt == 10) && (send_cnt == 10)) {
return 0;
}
return -1;
}
void kernel_test_queue(void)
{
YUNIT_ASSERT(aos_queue_test() == 0);
}
void aosapi_kernel_queue_test_entry(yunit_test_suite_t *suite)
{
yunit_add_test_case(suite, "kernel.queue.new", kernel_test_queue);
yunit_add_test_case(suite, "kernel.queue.param",
CASE_aosapi_kernel_queue_param);
// yunit_add_test_case(suite, "kernel.queue.sendrecv",
//CASE_aosapi_kernel_queue_send_recv);
yunit_add_test_case(suite, "kernel.queue.full",
CASE_aosapi_kernel_queue_full);
(void)CASE_aosapi_kernel_queue_send_recv;
}
/*
* Copyright (C) 2015-2023 Alibaba Group Holding Limited
*/
#include <stdio.h>
#include <stdlib.h>
#include <aos/kernel.h>
#include "yunit/yunit.h"
#include <errno.h>
static aos_sem_t sem;
static void CASE_aosapi_kernel_sem_param()
{
int ret;
aos_mutex_t mutex;
bool is_valid;
#if 0
// TODO: nullptr coredump
ret = aos_sem_new(NULL, 0);
YUNIT_ASSERT_MSG(ret==RHINO_NULL_PTR, "ret=%d", ret);
#endif
// TODO: test fail
ret = aos_sem_new(&sem, -1);
YUNIT_ASSERT_MSG(ret == 0, "ret=%d", ret);
if (ret == 0) {
aos_sem_free(&sem);
}
is_valid = aos_sem_is_valid(&sem);
YUNIT_ASSERT_MSG(is_valid==true, "is_valid=%d", is_valid);
ret = aos_sem_new(&sem, -2);
YUNIT_ASSERT_MSG(ret == 0, "ret=%d", ret);
if (ret == 0) {
aos_sem_free(&sem);
}
ret = aos_sem_new(&sem, 0x7FFFFFFF);
YUNIT_ASSERT_MSG(ret == 0, "ret=%d", ret);
if (ret == 0) {
aos_sem_free(&sem);
}
// TODO: test fail
ret = aos_sem_new(&sem, 0xFFFFFFFF);
YUNIT_ASSERT_MSG(ret == 0, "ret=%d", ret);
if (ret == 0) {
aos_sem_free(&sem);
}
#if 0
// TODO: nullptr param
aos_sem_signal(NULL);
#endif
#if 0
aos_mutex_new(&mutex);
aos_sem_signal((aos_sem_t*)&mutex);
aos_mutex_free(&mutex);
#endif
#if 0
// TODO: nullptr param
ret = aos_sem_wait(NULL, AOS_WAIT_FOREVER);
YUNIT_ASSERT_MSG(ret==0, "ret=%d", ret);
#endif
#if 0
aos_mutex_new(&mutex);
ret = aos_sem_wait((aos_sem_t *)&mutex, AOS_WAIT_FOREVER);
YUNIT_ASSERT_MSG(ret != 0, "ret=%d", ret);
aos_mutex_free(&mutex);
#endif
ret = aos_sem_new(&sem, 0);
YUNIT_ASSERT_MSG(ret == 0, "ret=%d", ret);
ret = aos_sem_wait(&sem, AOS_NO_WAIT);
YUNIT_ASSERT_MSG(ret != 0, "ret=%d", ret);
aos_sem_free(&sem);
ret = aos_sem_new(&sem, 0);
YUNIT_ASSERT_MSG(ret == 0, "ret=%d", ret);
ret = aos_sem_wait(&sem, 1000);
YUNIT_ASSERT_MSG(ret != 0, "ret=%d", ret);
aos_sem_free(&sem);
ret = aos_sem_new(&sem, 0);
YUNIT_ASSERT_MSG(ret == 0, "ret=%d", ret);
ret = aos_sem_wait(&sem, 0);
YUNIT_ASSERT_MSG(ret != 0, "ret=%d", ret);
aos_sem_free(&sem);
}
static void CASE_aosapi_kernel_sem_normal() {}
/**
* 该示例使用信号量实现多任务同步,具体场景为创建一个高优先级任务A,一个低优先级任务B,任务A和任务B同时等待同一信号量,\n\r
* 此时测试任务T调用aos_sem_signal()释放信号量,任务A首先获得信号量,任务A操作完成后释放一次信号量,此时任务B获取信号量得到运行。
* 示例说明如下:
* 1. t0时刻,任务T调用aos_sem_new()创建一信号量,初始计数值为0。任务T然后调用aos_task_create()创建任务A和任务B,\n\r
* 任务A优先级为30,任务B优先级为31。任务A和任务B运行后因等待信号量而阻塞。
* 2. t1时刻,任务T调用aos_sem_signal()释放信号量,任务A获得信号量。
* 3. t2时刻,任务A调用aos_sem_signal()释放信号量,任务B获得信号量。
*/
/* module name used by log print */
#define MODULE_NAME "aos_sem_test"
/* taskA parameters */
#define TASKA_NAME "taskA"
#define TASKA_STACKSIZE 4096
#define TASKA_PRIO 30
/* taskB parameters */
#define TASKB_NAME "taskB"
#define TASKB_STACKSIZE 4096
#define TASKB_PRIO 31
/* Static memory for static creation */
static aos_sem_t sem_handle;
static int test_cnt_A = 0;
static int test_cnt_B = 0;
static int test_num=0;
/*
* simulated critical section resources.
* The critical resource consistency condition is that all four fields are equal,
* otherwise the critical resource is destroyed.
*/
static struct record {
uint32_t field1;
uint32_t field2;
uint32_t field3;
uint32_t field4;
} record_status;
/* task entry for taskA and taskB*/
static void task_entry(void *arg)
{
uint32_t i = 0;
aos_status_t status;
int test_count = 10;
int *test_cnt = (int *)arg;
while (test_count--) {
/**
* In order to ensure the consistency of the critical resource,
* the task must obtain a sem to access the critical resource.
*/
status = aos_sem_wait(&sem_handle, AOS_WAIT_FOREVER);
if (status != 0) {
printf("[%s] %p sem wait error\n", MODULE_NAME, (void *)aos_task_self());
continue;
}
/**
* read critical resource.
* If the four fields are not equal, the critical resource is destroyed.
*/
printf("[%s]%p field1=%ld, field2=%ld, field3=%ld, field4=%ld\n", MODULE_NAME, (void *)aos_task_self(), record_status.field1,
record_status.field2, record_status.field3, record_status.field4);
/* modify critical resources */
i = rand();
record_status.field1 = i;
record_status.field2 = i;
record_status.field3 = i;
record_status.field4 = i;
/* a semaphore is released when critical resource access is complete */
if(test_num==0) {
aos_sem_signal_all(&sem_handle);
} else {
aos_sem_signal(&sem_handle);
}
(*test_cnt)++;
aos_msleep(10); /* sleep 1000ms */
}
}
static int aos_sem_test(void)
{
aos_status_t status;
aos_task_t taskA_handle;
aos_task_t taskB_handle;
test_cnt_A = 0;
test_cnt_B = 0;
/**
* create sem. In this case, the sem is used to access the critical resource,
* so count is initialized to 0
*/
status = aos_sem_create(&sem_handle, 0, 0);
if (status != 0) {
printf("[%s]create sem error\n", MODULE_NAME);
return -1;
}
/* TaskA and taskB both acess critical resources. */
status = aos_task_create(&taskA_handle, TASKA_NAME, task_entry, &test_cnt_A, NULL, TASKA_STACKSIZE, TASKA_PRIO, AOS_TASK_AUTORUN);
if (status != 0) {
aos_sem_free(&sem_handle);
printf("[%s]create %s error\n", MODULE_NAME, TASKA_NAME);
return -1;
}
status = aos_task_create(&taskB_handle, TASKB_NAME, task_entry, &test_cnt_B, NULL, TASKB_STACKSIZE, TASKB_PRIO, AOS_TASK_AUTORUN);
if (status != 0) {
aos_sem_free(&sem_handle);
printf("[%s]create %s error\n", MODULE_NAME, TASKB_NAME);
return -1;
}
aos_msleep(100);
/* a semaphore is released when critical resource access is complete */
aos_sem_signal(&sem_handle);
aos_msleep(500);
if ((test_cnt_A == 10) && (test_cnt_A == 10)) {
return 0;
}
return -1;
}
void kernel_test_sem(void)
{
YUNIT_ASSERT(aos_sem_test() == 0);
}
void aosapi_kernel_sem_test_entry(yunit_test_suite_t *suite)
{
yunit_add_test_case(suite, "kernel.sem.new", kernel_test_sem);
yunit_add_test_case(suite, "kernel.sem.param",
CASE_aosapi_kernel_sem_param);
yunit_add_test_case(suite, "kernel.sem.normal",
CASE_aosapi_kernel_sem_normal);
}
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include "aos/kernel.h"
#include "yunit/yunit.h"
extern const char *aos_version_get(void);
extern int aos_printf(const char *fmt, ...);
extern int aos_snprintf(char *str, const int len, const char *fmt, ...);
extern int aos_vsnprintf(char *str, const int len, const char *format, va_list ap);
static void CASE_aosapi_kernel_sys_version()
{
const char *version = aos_version_get();
YUNIT_ASSERT(strcmp(version, aos_version_get())==0);
}
static void CASE_aosapi_kernel_sys_reboot()
{
YUNIT_ASSERT(1);
}
static void test_vsnprintf(const char *fmt, ...)
{
char str[100];
va_list args;
va_start(args, fmt);
aos_vsnprintf(str, 10, fmt, args);
va_end(args);
// 输出字符串
aos_printf("%s", str);
}
static void CASE_aosapi_aos_etc()
{
int32_t r_value1, r_value2, r_value3;
unsigned int seed = (unsigned int)aos_now();
char str[100];
int a = 10;
float b = 3.14;
aos_srand(seed);
r_value1 = aos_rand();
r_value2 = aos_rand();
seed = (unsigned int)aos_now_ms();
aos_srand(seed);
r_value3 = aos_rand();
YUNIT_ASSERT(r_value1 != r_value2);
YUNIT_ASSERT(r_value1 != r_value3);
// 使用snprintf将格式化字符串设置为最多10个字符
aos_snprintf(str, 10, "a=%d, b=%.2f", a, b);
// 输出字符串
aos_printf("%s", str);
test_vsnprintf("a=%d, b=%.2f", a, b);
aos_now_time_str(str, 15);
aos_printf("%s", str);
}
void aosapi_kernel_sys_test_entry(yunit_test_suite_t *suite)
{
yunit_add_test_case(suite, "kernel.sys.reboot", CASE_aosapi_kernel_sys_reboot);
yunit_add_test_case(suite, "kernel.sys.version", CASE_aosapi_kernel_sys_version);
yunit_add_test_case(suite, "kernel.aos_etc", CASE_aosapi_aos_etc);
}
/*
* Copyright (C) 2015-2023 Alibaba Group Holding Limited
*/
#include <stdio.h>
#include <stdlib.h>
#include <aos/kernel.h>
#include "yunit/yunit.h"
#include <errno.h>
static aos_sem_t sync_sem;
#define TEST_TASK_STACK_SIZE (8192)
////////////////////////////////////////////////////////////////////////////////////////////////
void TASK_aosapi_kernel_task_new_param(void *arg)
{
aos_task_exit(0);
}
static void CASE_aosapi_kernel_task_new_param()
{
int ret = 0;
ret = aos_task_new(NULL, TASK_aosapi_kernel_task_new_param, NULL, 1024);
YUNIT_ASSERT_MSG(ret != 0, "ret=%d", ret);
ret = aos_task_new("TASK_aosapi_kernel_task_new_param", NULL, NULL, 1024);
YUNIT_ASSERT_MSG(ret != 0, "ret=%d", ret);
#if 1
ret = aos_task_new("TASK_aosapi_kernel_task_new_param",
TASK_aosapi_kernel_task_new_param, NULL, 0);
YUNIT_ASSERT_MSG(ret != 0, "ret=%d", ret);
#endif
}
////////////////////////////////////////////////////////////////////////////////////////////////
void TASK_aosapi_kernel_task_new_batch(void *arg)
{
aos_sem_signal(&sync_sem);
aos_task_exit(0);
}
static void CASE_aosapi_kernel_task_new_batch()
{
int i = 0;
int success_count = 0;
int ret = 0;
const int TASK_COUNT = 10;
for (i = 0; i < TASK_COUNT; i++) {
ret = aos_sem_new(&sync_sem, 0);
YUNIT_ASSERT_MSG(ret == 0, "ret=%d", ret);
ret = aos_task_new("TASK_aosapi_kernel_task_new_batch",
TASK_aosapi_kernel_task_new_batch, NULL,
TEST_TASK_STACK_SIZE);
YUNIT_ASSERT_MSG(ret == 0, "ret=%d", ret);
if (ret != 0) {
aos_sem_signal(&sync_sem);
}
ret = aos_sem_wait(&sync_sem, AOS_WAIT_FOREVER);
YUNIT_ASSERT_MSG(ret == 0, "ret=%d", ret);
aos_sem_free(&sync_sem);
success_count += (ret == 0 ? 1 : 0);
printf("task %d\t", success_count);
}
YUNIT_ASSERT(success_count == TASK_COUNT);
}
////////////////////////////////////////////////////////////////////////////////////////////////
#if 0
void TASK_aosapi_kernel_task_new_stack(void *arg)
{
int array[2048];
memset(array, 0, sizeof(int) * 2048);
PRINT_TASK_INFO(krhino_cur_task_get());
aos_task_exit(0);
}
#endif
static void CASE_aosapi_kernel_task_new_stack()
{
#if 0
int ret = 0;
ret = aos_task_new("TASK_aosapi_kernel_task_new_stack",
TASK_aosapi_kernel_task_new_stack, NULL, 256);
YUNIT_ASSERT_MSG(ret==0, "ret=%d", ret);
aos_msleep(1000);
#endif
#if 0
ret = aos_task_new("TASK_aosapi_kernel_task_new_stack",
TASK_aosapi_kernel_task_new_stack, NULL, 10);
YUNIT_ASSERT_MSG(ret==0, "ret=%d", ret);
aos_msleep(1000);
#endif
#if 0
ret = aos_task_new("TASK_aosapi_kernel_task_new_stack",
TASK_aosapi_kernel_task_new_stack, NULL, 20480000);
YUNIT_ASSERT_MSG(ret==0, "ret=%d", ret);
aos_msleep(1000);
#endif
}
extern const char *aos_task_name(void);
////////////////////////////////////////////////////////////////////////////////////////////////
void TASK_aosapi_kernel_task_getname(void *arg)
{
YUNIT_ASSERT(0 ==
strcmp(aos_task_name(), "TASK_aosapi_kernel_task_getname"));
aos_sem_signal(&sync_sem);
aos_task_exit(0);
}
static void CASE_aosapi_kernel_task_getname()
{
int ret = 0;
ret = aos_sem_new(&sync_sem, 0);
YUNIT_ASSERT_MSG(ret == 0, "ret=%d", ret);
ret =
aos_task_new("TASK_aosapi_kernel_task_getname",
TASK_aosapi_kernel_task_getname, NULL, TEST_TASK_STACK_SIZE);
YUNIT_ASSERT_MSG(ret == 0, "ret=%d", ret);
if (ret != 0) {
aos_sem_signal(&sync_sem);
}
ret = aos_sem_wait(&sync_sem, AOS_WAIT_FOREVER);
YUNIT_ASSERT_MSG(ret == 0, "ret=%d", ret);
aos_sem_free(&sync_sem);
}
static aos_task_t task_handle;
void TASK_aosapi_kernel_task_new_ext(void *arg)
{
aos_sem_signal(&sync_sem);
aos_task_exit(0);
}
static void CASE_aosapi_kernel_task_new_ext()
{
int ret = 0;
int success_count = 0;
int i = 0;
/* */
ret = aos_sem_new(&sync_sem, 0);
YUNIT_ASSERT_MSG(ret==0, "ret=%d", ret);
ret = aos_task_new_ext(&task_handle, "TASK_aosapi_kernel_task_new_ext",
TASK_aosapi_kernel_task_new_ext, NULL,
TEST_TASK_STACK_SIZE, 50);
YUNIT_ASSERT_MSG(ret==0, "ret=%d", ret);
//if(ret == 0) {
// aos_sem_signal(&sync_sem);
// }
ret = aos_sem_wait(&sync_sem, AOS_WAIT_FOREVER);
YUNIT_ASSERT_MSG(ret==0, "ret=%d", ret);
aos_sem_free(&sync_sem);
}
////////////////////////////////////////////////////////////////////////////////////////////////
#if 0
void TASK_aosapi_kernel_task_new_priority(void *arg)
{
aos_sem_signal(&sync_sem);
aos_task_exit(0);
}
static void CASE_aosapi_kernel_task_new_priority()
{
int ret = 0;
int success_count = 0;
int i = 0;
#if 1
/* */
ret = aos_sem_new(&sync_sem, 0);
YUNIT_ASSERT_MSG(ret==0, "ret=%d", ret);
ret = aos_task_new_ext("TASK_aosapi_kernel_task_new_priority",
TASK_aosapi_kernel_task_new_priority, NULL,
TEST_TASK_STACK_SIZE, RHINO_CONFIG_PRI_MAX);
YUNIT_ASSERT_MSG(ret==RHINO_BEYOND_MAX_PRI, "ret=%d", ret);
if(ret == RHINO_BEYOND_MAX_PRI) {
aos_sem_signal(&sync_sem);
}
ret = aos_sem_wait(&sync_sem, RHINO_WAIT_FOREVER);
YUNIT_ASSERT_MSG(ret==0, "ret=%d", ret);
aos_sem_free(&sync_sem);
/* */
ret = aos_sem_new(&sync_sem, 0);
YUNIT_ASSERT_MSG(ret==0, "ret=%d", ret);
ret = aos_task_new_ext("TASK_aosapi_kernel_task_new_priority",
TASK_aosapi_kernel_task_new_priority, NULL,
TEST_TASK_STACK_SIZE, RHINO_CONFIG_USER_PRI_MAX);
YUNIT_ASSERT_MSG(ret==0, "ret=%d", ret);
if(ret != 0) {
aos_sem_signal(&sync_sem);
}
ret = aos_sem_wait(&sync_sem, RHINO_WAIT_FOREVER);
YUNIT_ASSERT_MSG(ret==0, "ret=%d", ret);
aos_sem_free(&sync_sem);
#endif
/* */
#if 1
int pris[] = {11,12,13};
for(i=0; i<sizeof(pris)/sizeof(pris[0]); i++) {
ret = aos_sem_new(&sync_sem, 0);
YUNIT_ASSERT_MSG(ret==0, "ret=%d", ret);
ret = aos_task_new_ext("TASK_aosapi_kernel_task_new_priority",
TASK_aosapi_kernel_task_new_priority, NULL,
TEST_TASK_STACK_SIZE, pris[i]);
YUNIT_ASSERT_MSG(ret==0, "ret=%d", ret);
if(ret != 0) {
aos_sem_signal(&sync_sem);
}
ret = aos_sem_wait(&sync_sem, RHINO_WAIT_FOREVER);
YUNIT_ASSERT_MSG(ret==0, "ret=%d", ret);
aos_sem_free(&sync_sem);
success_count += (ret==0 ? 1 : 0);
printf("\ttask prio=%d\n", pris[i]);
}
YUNIT_ASSERT_MSG(success_count==sizeof(pris)/sizeof(pris[0]), "success_count=%d", success_count);
#endif
}
#endif
/**
* 该示例使用任务管理函数来控制任务的执行状态,具体场景为任务2因等待某个信号量进入阻塞状态,而此时被任务1将其挂起,则任务2仍然是处于阻塞状态,\n\r
* 如果在此过程中等到信号量,则任务2会解除阻塞进入挂起状态;如果未等到信号量,则任务2恢复状态后仍然处于阻塞状态。\n\r
* 示例说明如下:
* 1. 在t0时刻,任务task1、task2分别通过aos_task_new()和aos_task_new_ext()函数调用被创建,之后task1进入就绪状态,而task2处于挂起状态。
* 2. Task1得到运行后,在t1时刻调用aos_task_resume()将task2恢复,task2进入就绪状态,之后task1通过调用aos_msleep()进入休眠状态,task2因为task1休眠而获得CPU执行权,task2运行后因等待信号量进入阻塞状态。
* 3. Task1在t2时刻因延迟到期得到运行,并调用aos_task_suspend()将task2挂起,task2此时的状态为阻塞挂起。之后task1通过调用aos_msleep()进入休眠状态。
* 4. Task2在t3时刻因延迟到期得到运行,并调用aos_task_resume()将task2恢复,此时task2的状态为阻塞状态。之后task1通过调用aos_msleep()进入休眠状态。
* 5. Task1在t4时刻因延迟到期得到运行,并调用aos_sem_signal()释放信号量,这时task2因等到信号量而进入就绪状态。待到task1再次进入休眠转改后task2得到运行,进入运行状态。
*/
/* module name used by log print */
#define MODULE_NAME "aos_task_test"
/* sem handle for synchronize of task1 and task2 */
static aos_sem_t g_testsync_sem;
/* task handle for task1 and task2*/
static aos_task_t task1_handle;
static aos_task_t task2_handle;
static int test_flag_1 = 0;
static int test_flag_2 = 0;
/* task entry for task1*/
void task1_entry()
{
aos_status_t status;
printf("[%s]task1 is running!\n", MODULE_NAME);
printf("[%s]task1 resume task2!\n", MODULE_NAME);
status = aos_task_resume(&task2_handle);
if (0 != status) {
printf("[%s]task1 resume task2 failed(%ld)!\n", MODULE_NAME, status);
return;
}
printf("[%s]task1 start to sleep and release CPU!\n", MODULE_NAME);
aos_msleep(10);
printf("[%s]task1 suspend task2!\n", MODULE_NAME);
if (0 != aos_task_suspend(&task2_handle)) {
printf("[%s]task1 resume task2 failed!\n", MODULE_NAME);
return;
}
printf("[%s]task1 start to sleep and release CPU!\n", MODULE_NAME);
aos_msleep(10);
printf("[%s]task1 resume task2 again!\n", MODULE_NAME);
status = aos_task_resume(&task2_handle);
if (0 != status) {
printf("[%s]task1 resume task2 failed(%ld)!\n", MODULE_NAME, status);
return;
}
printf("[%s]task1 start to sleep and release CPU!\n", MODULE_NAME);
aos_msleep(10);
printf("[%s]task1 signal a semphone!\n", MODULE_NAME);
aos_sem_signal(&g_testsync_sem);
printf("[%s]task1 start to sleep and release CPU!\n", MODULE_NAME);
test_flag_1 = 1;
aos_msleep(10);
aos_task_exit(0);
}
/* task entry for task2*/
void task2_entry()
{
printf("[%s]task2 is running!\n", MODULE_NAME);
if (0 != aos_sem_wait(&g_testsync_sem, AOS_WAIT_FOREVER)) {
printf("[%s]task2 wait semphone failed!\n", MODULE_NAME);
return;
}
test_flag_2 = 1;
printf("[%s]task2 get semphone and is running!\n", MODULE_NAME);
aos_task_exit(0);
}
/* task example init function*/
static int aos_task_test(void)
{
aos_status_t status;
test_flag_1 = 0;
test_flag_2 = 0;
status = aos_sem_new(&g_testsync_sem, 0);
if (status != 0) {
printf("[%s]sem new failed, err=%ld\n", MODULE_NAME, status);
return -1;
}
status = aos_task_create(&task2_handle, "task2", task2_entry, NULL, NULL, 4096, 50, AOS_TASK_NONE);
if (status != 0) {
aos_sem_free(&g_testsync_sem);
printf("[%s]create %s error\n", MODULE_NAME, "task2");
return -1;
}
status = aos_task_create(&task1_handle, "task1", task1_entry, NULL, NULL, 4096, 50, AOS_TASK_AUTORUN);
if (status != 0) {
aos_sem_free(&g_testsync_sem);
printf("[%s]create %s error\n", MODULE_NAME, "task1");
return -1;
}
aos_msleep(500);
if ((test_flag_1 == 1) && (test_flag_2 == 1)) {
return 0;
}
return -1;
}
void kernel_test_task(void)
{
YUNIT_ASSERT(aos_task_test() == 0);
}
void aosapi_kernel_task_test_entry(yunit_test_suite_t *suite)
{
yunit_add_test_case(suite, "kernel.task.new", kernel_test_task);
yunit_add_test_case(suite, "kernel.task.param",
CASE_aosapi_kernel_task_new_param);
yunit_add_test_case(suite, "kernel.task.stack",
CASE_aosapi_kernel_task_new_stack);
yunit_add_test_case(suite, "kernel.task.batchcreate",
CASE_aosapi_kernel_task_new_batch);
yunit_add_test_case(suite, "kernel.task.ext",
CASE_aosapi_kernel_task_new_ext);
// yunit_add_test_case(suite, "kernel.task.priority",
//CASE_aosapi_kernel_task_new_priority);
yunit_add_test_case(suite, "kernel.task.getname",
CASE_aosapi_kernel_task_getname);
}
/*
* Copyright (C) 2015-2023 Alibaba Group Holding Limited
*/
#include <stdio.h>
#include <stdlib.h>
#include <aos/kernel.h>
#include "yunit/yunit.h"
#include <errno.h>
static aos_timer_t g_timer;
static aos_sem_t sync_sem;
static int timer_trigger_count = 0;
static void TIMER_aosapi_kernel_timer_param() {}
static void CASE_aosapi_kernel_timer_param()
{
int ret;
#if 0
ret = aos_timer_new(NULL, TIMER_aosapi_kernel_timer_param, NULL, 1000, 0);
YUNIT_ASSERT(ret==RHINO_NULL_PTR);
#endif
ret = aos_timer_create(&g_timer, NULL, NULL, 1000, 0);
YUNIT_ASSERT(ret != 0);
#if 0
ret = aos_timer_create(&g_timer, TIMER_aosapi_kernel_timer_param, NULL, 0, 0);
YUNIT_ASSERT(ret != 0);
#endif
#if 0
ret = aos_timer_start(NULL);
YUNIT_ASSERT(ret == RHINO_NULL_PTR);
#endif
#if 0
ret = aos_timer_stop(NULL);
YUNIT_ASSERT(ret == RHINO_NULL_PTR);
#endif
#if 0
aos_timer_free(NULL);
#endif
#if 0
ret = aos_timer_change(NULL, 0);
YUNIT_ASSERT(ret == RHINO_NULL_PTR);
#endif
aos_timer_free(&g_timer);
}
///////////////////////////////////////////////////////////////////////////////////////////////
static void TIMER_aosapi_kernel_timer_norepeat(void *timer, void *arg)
{
timer_trigger_count++;
aos_timer_stop(&g_timer);
aos_timer_free(&g_timer);
}
static void CASE_aosapi_kernel_timer_norepeat()
{
int ret;
ret = aos_sem_new(&sync_sem, 0);
YUNIT_ASSERT(ret == 0);
timer_trigger_count = 0;
ret =aos_timer_create(&g_timer, TIMER_aosapi_kernel_timer_norepeat, NULL, 100, 0);
YUNIT_ASSERT(ret == 0);
ret = aos_timer_start(&g_timer);
YUNIT_ASSERT(ret == 0);
aos_msleep(1000);
YUNIT_ASSERT(timer_trigger_count == 1);
}
///////////////////////////////////////////////////////////////////////////////////////////////
static void TIMER_aosapi_kernel_timer_repeat(void *timer, void *arg)
{
timer_trigger_count++;
if (timer_trigger_count == 10) {
aos_timer_stop(&g_timer);
aos_timer_free(&g_timer);
}
}
static void CASE_aosapi_kernel_timer_repeat()
{
int ret;
ret = aos_sem_new(&sync_sem, 0);
YUNIT_ASSERT(ret == 0);
timer_trigger_count = 0;
ret =aos_timer_create(&g_timer, TIMER_aosapi_kernel_timer_repeat, NULL, 100, (AOS_TIMER_REPEAT | AOS_TIMER_AUTORUN));
YUNIT_ASSERT(ret == 0);
ret= aos_timer_start(&g_timer);
YUNIT_ASSERT(ret == 0);
aos_msleep(1500);
YUNIT_ASSERT(timer_trigger_count == 10);
}
/**
* 该示例使用定时器管理函数来控制定时器的执行,具体场景为创建一个周期性定时器,定时调用回调函数执行,\n\r
* 停止定时器该变定时器的时间参数,则定时器按照修改后的时间间隔定时调用回调函数执行。
* 示例说明如下:
* 1. t0时刻,测试任务调用aos_timer_create()创建一个周期性的定时器,周期间隔为1秒,回调函数为timer1_func。然后测试任务调用aos_sleep()进入休眠状态。
* 2. t1时刻,相对t0过去1秒,定时器到期,回调函数timer1_func被执行。该过程重复10次。
* 3. tn时刻,测试任务休眠到期,调用aos_timer_stop()停止定时器。然后调用aos_timer_change()接口修改周期间隔为2秒。
* 4. tn+1时刻,相对tn过去2秒,定时器到期,回调函数timer1_func被执行。该过程重复5次
*/
/* module name used by log print */
#define MODULE_NAME "aos_timer_test"
/* timer handle */
static aos_timer_t timer1;
/* timer trigger count */
static volatile int timer_count = 0;
/* test flag */
static volatile int test_flag = 0;
/**
* timer callback function.
* The current use case is executed every 1000ms.
*/
static void timer1_func(void *timer, void *arg)
{
/*
* Warning: an interface that causes a block is not allowed to be called within this function.
* Blocking within this function will cause other timers to run incorrectly.
* The printf function may also block on some platforms, so be careful how you call it.
*/
timer_count++;
}
static void aos_timer_example_task(void *data)
{
aos_status_t status;
/**
* Create timer. Timer starts automatically after successful creation.
* some of the parameters are as follows:
* fn: timer1_func (this function is called when the timer expires)
* ms: 1000 (the cycle of the timer)
* option: AOS_TIMER_REPEAT (set to periodic timer), AOS_TIMER_AUTORUN (set to auto start)
*/
status = aos_timer_create(&timer1, timer1_func, NULL, 100, (AOS_TIMER_REPEAT | AOS_TIMER_AUTORUN));
YUNIT_ASSERT(status == 0);
status = aos_timer_start(&timer1);
YUNIT_ASSERT(status == 0);
if (status != 0) {
printf("[%s]create timer error\n", MODULE_NAME);
return;
}
aos_msleep(1080);
/* stop the timer before modifying the timer parameter */
aos_timer_stop(&timer1);
if (timer_count == 10) {
test_flag++;
}
printf("[%s]timer expires %d times\n", MODULE_NAME, timer_count);
aos_timer_free(&timer1);
#if 0
timer_count = 0;
/* the timer cycle is modified to 2000ms */
aos_timer_change(&timer1, 20);
/* start the timer after the timer parameter modification is complete */
aos_timer_start(&timer1);
aos_msleep(100);
if (timer_count == 5) {
test_flag++;
}
printf("[%s]timer expires %d times\n", MODULE_NAME, timer_count);
#endif
}
static int aos_timer_test(void)
{
aos_status_t status;
aos_task_t task_handle;
status = aos_task_create(&task_handle, "task_timer_test", aos_timer_example_task, NULL, NULL, 1024, 50, AOS_TASK_AUTORUN);
if (status != 0) {
printf("[%s]create %s error\n", MODULE_NAME, "task_timer_test");
return -1;
}
aos_msleep(3000);
if (test_flag == 1) {
return 0;
}
return -1;
}
void kernel_test_timer(void)
{
YUNIT_ASSERT(aos_timer_test() == 0);
}
void aosapi_kernel_timer_test_entry(yunit_test_suite_t *suite)
{
yunit_add_test_case(suite, "kernel.timer.new", kernel_test_timer);
yunit_add_test_case(suite, "kernel.timer.param",CASE_aosapi_kernel_timer_param);
yunit_add_test_case(suite, "kernel.timer.norepeat",CASE_aosapi_kernel_timer_norepeat);
yunit_add_test_case(suite, "kernel.timer.repeat",CASE_aosapi_kernel_timer_repeat);
}
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#include "yunit/yunit.h"
#include <stdio.h>
static int init(void)
{
return 0;
}
static int cleanup(void)
{
return 0;
}
static void setup(void) {}
static void teardown(void) {}
extern void aosapi_kernel_sys_test_entry(yunit_test_suite_t *suite);
extern void aosapi_kernel_task_test_entry(yunit_test_suite_t *suite);
extern void aosapi_kernel_mutex_test_entry(yunit_test_suite_t *suite);
extern void aosapi_kernel_timer_test_entry(yunit_test_suite_t *suite);
extern void aosapi_kernel_queue_test_entry(yunit_test_suite_t *suite);
extern void aosapi_kernel_workqueue_test_entry(yunit_test_suite_t *suite);
extern void aosapi_kernel_mm_test_entry(yunit_test_suite_t *suite);
extern void aosapi_kernel_sem_test_entry(yunit_test_suite_t *suite);
void test_api(void)
{
yunit_test_suite_t *suite;
suite = yunit_add_test_suite("aosapi", init, cleanup, setup, teardown);
/* kernel */
aosapi_kernel_sys_test_entry(suite);
aosapi_kernel_mm_test_entry(suite);
aosapi_kernel_task_test_entry(suite);
aosapi_kernel_mutex_test_entry(suite);
aosapi_kernel_sem_test_entry(suite);
aosapi_kernel_timer_test_entry(suite);
aosapi_kernel_queue_test_entry(suite);
/*
aosapi_kernel_workqueue_test_entry(suite);
*/
}
AOS_TESTCASE(test_api);
/*
* warning: testcase collection code is auto generate, please don't change!!!
*/
/*
extern void kernel_test(void);
extern void aos_fs_test(void);
extern void test_epoll_test(void);
extern void test_select_test(void);
extern void test_poll_test(void);
extern void realtime_test(void);
extern void test_posix_test(void);
extern void test_cpp_test(void);
extern void clib_test(void);
extern void stress_test(void);
extern void test_socket(void);
extern void test_kv_test(void);
extern void netmgr_test(void);
extern void test_uagent(void);
*/
extern void test_api(void);
extern void aos_fs_test(void);
extern void aos_kv_test(void);
void add_test(void) {
test_api();
aos_fs_test();
aos_kv_test();
/*
kernel_test();
aos_fs_test();
test_epoll_test();
test_select_test();
test_poll_test();
realtime_test();
test_posix_test();
test_cpp_test();
clib_test();
stress_test();
test_socket();
test_kv_test();
netmgr_test();
test_uagent();
*/
}
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#include <stdio.h>
#include <stdlib.h>
#if defined (__GNUC__)
#include <sys/wait.h>
#endif
#include <aos/kernel.h>
#include "yunit/yunit.h"
#include "yunit/yts.h"
extern void add_test(void);
static int yts_argc;
static char **yts_argv;
int yts_get_args(const char ***argv)
{
*argv = (const char **)yts_argv;
return yts_argc;
}
void yts_run(int argc, char **argv)
{
yts_argc = argc;
yts_argv = argv;
aos_msleep(2 * 1000);
yunit_test_init();
add_test();
int ret = 0;
if (argc > 1) {
int i;
for (i = 1; i < argc; i++) {
yunit_test_suite_t *test_suite = yunit_get_test_suite(argv[i]);
if (test_suite != NULL) {
ret = yunit_run_test_suite(test_suite);
printf("suite %s completed with %d\n", argv[i], ret);
continue;
}
const char *suite_case = argv[i];
char *test = strrchr(suite_case, ':');
if (test != NULL) {
*test++ = '\0';
test_suite = yunit_get_test_suite(suite_case);
yunit_test_case_t *test_case = yunit_get_test_case(test_suite, test);
if (test_case != NULL) {
ret = yunit_run_test_case(test_suite, test_case);
printf("suite %s completed with %d\n", argv[i], ret);
} else {
printf("test suite %s not found\n", argv[i]);
}
}
}
} else {
ret = yunit_test_run();
printf("\nTests completed with return value %d\n", ret);
}
yunit_test_print_result();
yunit_test_deinit();
}
/*
* Copyright (C) 2015-2017 Alibaba Group Holding Limited
*/
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "aos/kernel.h"
#include "ulog/ulog.h"
#include "yunit/yunit.h"
#define TAG "yunit"
typedef struct yunit_test_case_node_s {
struct yunit_test_case_node_s *next;
const char *name;
yunit_test_case_proc test_proc;
} yunit_test_case_node_t;
typedef struct yunit_test_suite_node_s {
struct yunit_test_suite_node_s *next;
const char *name;
yunit_test_suit_init init;
yunit_test_suit_deinit deinit;
yunit_test_case_setup setup;
yunit_test_case_teardown teardown;
yunit_test_case_node_t test_case_list_header;
} yunit_test_suite_node_t;
#define TEST_RESULT_MESSAGE_LENGTH 64
typedef struct yunit_test_case_result_s {
struct yunit_test_case_result_s *next;
const char *file;
size_t line;
char msg[TEST_RESULT_MESSAGE_LENGTH];
} yunit_test_case_result_t;
typedef struct {
yunit_test_suite_node_t test_suite_list_header;
int all_test_cases_count;
int failed_test_cases_count;
int fatal_test_cases_count;
yunit_test_case_result_t failed_test_case_result;
} yunit_test_context_t;
static int yunit_run_test_case_list(
yunit_test_suite_node_t *suite,
yunit_test_case_node_t *test_case_list_header);
yunit_test_context_t g_test_context;
void yunit_test_init(void)
{
memset(&g_test_context, 0, sizeof(yunit_test_context_t));
}
void yunit_test_deinit(void)
{
yunit_test_suite_node_t *test_suite_node = g_test_context.test_suite_list_header.next;
while (test_suite_node != NULL) {
yunit_test_case_node_t *test_case_node = test_suite_node->test_case_list_header.next;
while (test_case_node != NULL) {
yunit_test_case_node_t *test_case_node_next = test_case_node->next;
aos_free(test_case_node);
test_case_node = test_case_node_next;
}
yunit_test_suite_node_t *test_suite_node_next = test_suite_node->next;
aos_free(test_suite_node);
test_suite_node = test_suite_node_next;
}
yunit_test_case_result_t *test_case_result = g_test_context.failed_test_case_result.next;
while (test_case_result != NULL) {
yunit_test_case_result_t *test_case_result_next = test_case_result->next;
aos_free(test_case_result);
test_case_result = test_case_result_next;
}
}
void *yunit_add_test_suite(
const char *name,
yunit_test_suit_init init,
yunit_test_suit_deinit deinit,
yunit_test_case_setup setup,
yunit_test_case_teardown teardown)
{
yunit_test_suite_node_t *node = aos_malloc(sizeof(yunit_test_suite_node_t));
if (node == NULL) {
printf("%s\n", "out of memory");
return NULL;
}
memset(node, 0, sizeof(yunit_test_suite_node_t));
node->next = NULL;
node->name = name;
node->init = init;
node->deinit = deinit;
node->setup = setup;
node->teardown = teardown;
yunit_test_suite_node_t *prev = &g_test_context.test_suite_list_header;
while (prev->next != NULL) {
prev = prev->next;
}
prev->next = node;
return node;
}
int yunit_add_test_case(void *test_suite, const char *name, yunit_test_case_proc proc)
{
yunit_test_suite_node_t *test_suite_node = test_suite;
yunit_test_case_node_t *prev = &test_suite_node->test_case_list_header;
while (prev->next != NULL) {
prev = prev->next;
}
yunit_test_case_node_t *node = aos_malloc(sizeof(yunit_test_case_node_t));
memset(node,0,sizeof(yunit_test_case_node_t));
if (node == NULL) {
printf("%s\n", "out of memory");
return -1;
}
node->name = name;
node->test_proc = proc;
prev->next = node;
return 0;
}
int yunit_add_test_suites(yunit_test_suite_t *test_suit_array)
{
int i = 0;
while (test_suit_array[i].name != NULL) {
yunit_test_suite_t *test_suite = &test_suit_array[i++];
void *test_suite_node = yunit_add_test_suite(
test_suite->name,
test_suite->init, test_suite->deinit,
test_suite->setup, test_suite->teardown);
if (test_suite_node == NULL) {
return -1;
}
int j = 0;
yunit_test_case_t *test_case_array = test_suite->test_case_array;
while (test_case_array[j].name != NULL) {
yunit_test_case_t *test_case = &test_case_array[j++];
int ret = yunit_add_test_case(
test_suite_node,
test_case->name, test_case->test_proc);
if (ret == -1) {
return ret;
}
}
}
return 0;
}
void *yunit_get_test_suite(const char *name)
{
yunit_test_suite_node_t *node = g_test_context.test_suite_list_header.next;
while (node != NULL) {
if (strcmp(node->name, name) == 0) {
return node;
}
node = node->next;
}
return NULL;
}
void *yunit_get_test_case(void *test_suite, const char *name)
{
yunit_test_suite_node_t *test_suite_node = test_suite;
yunit_test_case_node_t *node = test_suite_node->test_case_list_header.next;
while (node != NULL) {
if (strcmp(node->name, name) == 0) {
return node;
}
node = node->next;
}
return NULL;
}
int yunit_test_run(void)
{
int ret = 0;
yunit_test_suite_node_t* test_suite = g_test_context.test_suite_list_header.next;
while (test_suite != NULL) {
ret = yunit_run_test_suite(test_suite);
if (ret != 0) {
return ret;
}
test_suite = test_suite->next;
}
return ret;
}
int yunit_run_test_suite(void *test_suite)
{
int ret = 0;
yunit_test_suite_node_t *node = test_suite;
printf("run test suites %s\n", node->name);
if (node->init != NULL) {
node->init();
}
ret = yunit_run_test_case_list(node, &node->test_case_list_header);
if (node->deinit != NULL) {
node->deinit();
}
if (ret != 0) {
LOGE(TAG, "run test suite %s error: ret = %d", node->name, ret);
return ret;
}
return 0;
}
static int _run_test_case(void *test_suite, void *test_case)
{
yunit_test_suite_node_t *test_suite_node = test_suite;
yunit_test_case_node_t *test_case_node = test_case;
int cnt1 = g_test_context.failed_test_cases_count + g_test_context.fatal_test_cases_count;
int cnt2;
long long now = aos_now_ms();
int delta;
if (test_suite_node->setup != NULL) {
test_suite_node->setup();
}
fprintf(stderr, "run test case %s\n", test_case_node->name);
test_case_node->test_proc();
if (test_suite_node->teardown != NULL) {
test_suite_node->teardown();
}
cnt2 = g_test_context.failed_test_cases_count + g_test_context.fatal_test_cases_count;
delta = aos_now_ms() - now;
fprintf(stderr, "test case %s finished %d failed %d ms\n", test_case_node->name, cnt2-cnt1, delta);
return 0;
}
int yunit_run_test_case(void *test_suite, void *test_case)
{
int ret = 0;
yunit_test_suite_node_t *tnode = test_suite;
yunit_test_case_node_t *tcase = test_case;
printf("run test suites %s\n", tnode->name);
if (tnode->init != NULL) {
tnode->init();
}
ret = _run_test_case(tnode, tcase);
if (tnode->deinit != NULL) {
tnode->deinit();
}
if (ret != 0) {
LOGE(TAG, "run test suite %s error: ret = %d", tnode->name, ret);
return ret;
}
return 0;
}
int yunit_run_test_case_list(yunit_test_suite_node_t *test_suite,
yunit_test_case_node_t *test_case_list_header)
{
int ret = 0;
yunit_test_case_node_t *node = test_case_list_header->next;
while (node != NULL) {
ret = _run_test_case(test_suite, node);
if (ret != 0) {
return ret;
}
node = node->next;
}
return ret;
}
void yunit_add_test_case_result(int type, const char *file, size_t line, const char *fmt, ...)
{
g_test_context.all_test_cases_count++;
if (type == TEST_RESULT_SUCCESS) {
return;
}
if (type == TEST_RESULT_FAILURE) {
g_test_context.failed_test_cases_count++;
} else if (type == TEST_RESULT_FATAL) {
g_test_context.fatal_test_cases_count++;
} else {
}
yunit_test_case_result_t *result = aos_malloc(sizeof(yunit_test_case_result_t));
if (result == NULL) {
printf("%s\n", "out of memory");
return;
}
memset(result, 0, sizeof(yunit_test_case_result_t));
va_list args;
va_start(args, fmt);
vsnprintf(result->msg, TEST_RESULT_MESSAGE_LENGTH, fmt, args);
va_end(args);
result->file = file;
result->line = line;
yunit_test_case_result_t *prev = &g_test_context.failed_test_case_result;
while (prev != NULL && prev->next != NULL) {
prev = prev->next;
}
prev->next = result;
}
void yunit_test_print_result(void)
{
printf("\n--------------------------------\n");
printf("%d test cases, %d failed\n\n",
g_test_context.all_test_cases_count,
g_test_context.failed_test_cases_count + g_test_context.fatal_test_cases_count);
yunit_test_case_result_t *result = g_test_context.failed_test_case_result.next;
while (result != NULL) {
printf("failed at %s(#%d) %s\n", result->file, result->line, result->msg);
result = result->next;
}
printf("\n--------------------------------\n");
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册