mirror of
https://github.com/thead-yocto-mirror/prd-utils
synced 2026-06-21 08:52:31 +02:00
Linux_SDK_V1.1.2
This commit is contained in:
9
.gitignore
vendored
Normal file
9
.gitignore
vendored
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
!.gitignore
|
||||||
|
*.o
|
||||||
|
out_*
|
||||||
|
buildout
|
||||||
|
build
|
||||||
|
output
|
||||||
|
install.sh
|
||||||
|
make.sh
|
||||||
|
|
||||||
34
CMakeLists.txt
Normal file
34
CMakeLists.txt
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2023 Alibaba Group Holding Limited
|
||||||
|
#
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.5.1)
|
||||||
|
project(prd_utils C)
|
||||||
|
set(CMAKE_C_STANDARD 99)
|
||||||
|
|
||||||
|
# Add fpic
|
||||||
|
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||||
|
|
||||||
|
# Board Selection
|
||||||
|
if (${BOARD_NAME} MATCHES "light*")
|
||||||
|
set(BOARD_NAME "light")
|
||||||
|
include(cmake/board_light.cmake)
|
||||||
|
else ()
|
||||||
|
message(FATAL_ERROR, "No BOARD_NAME")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0 -Wall -g")
|
||||||
|
set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--no-undefined")
|
||||||
|
|
||||||
|
include(cmake/show_cmake_param.cmake)
|
||||||
|
|
||||||
|
|
||||||
|
# Add include dirs for all sub modules
|
||||||
|
include_directories(${PROJECT_BINARY_DIR})
|
||||||
|
include_directories(${PROJECT_SOURCE_DIR}/include)
|
||||||
|
|
||||||
|
add_subdirectory(platform/${BOARD_NAME})
|
||||||
|
add_subdirectory(utils)
|
||||||
|
add_subdirectory(test)
|
||||||
|
|
||||||
|
install(FILES ${INSTALL_HEAD_FILES} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||||
36
README.en.md
36
README.en.md
@@ -1,36 +0,0 @@
|
|||||||
# prd-utils
|
|
||||||
|
|
||||||
#### Description
|
|
||||||
product produce utilities
|
|
||||||
|
|
||||||
#### Software Architecture
|
|
||||||
Software architecture description
|
|
||||||
|
|
||||||
#### Installation
|
|
||||||
|
|
||||||
1. xxxx
|
|
||||||
2. xxxx
|
|
||||||
3. xxxx
|
|
||||||
|
|
||||||
#### Instructions
|
|
||||||
|
|
||||||
1. xxxx
|
|
||||||
2. xxxx
|
|
||||||
3. xxxx
|
|
||||||
|
|
||||||
#### Contribution
|
|
||||||
|
|
||||||
1. Fork the repository
|
|
||||||
2. Create Feat_xxx branch
|
|
||||||
3. Commit your code
|
|
||||||
4. Create Pull Request
|
|
||||||
|
|
||||||
|
|
||||||
#### Gitee Feature
|
|
||||||
|
|
||||||
1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md
|
|
||||||
2. Gitee blog [blog.gitee.com](https://blog.gitee.com)
|
|
||||||
3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore)
|
|
||||||
4. The most valuable open source project [GVP](https://gitee.com/gvp)
|
|
||||||
5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help)
|
|
||||||
6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
|
|
||||||
51
README.md
51
README.md
@@ -1,37 +1,20 @@
|
|||||||
# prd-utils
|
# Comments
|
||||||
|
This is utilities for product produce process, including:
|
||||||
|
- utils for set/get/clean Key-Value
|
||||||
|
|
||||||
#### 介绍
|
# How to get the code
|
||||||
product produce utilities
|
- git clone git@gitlab.alibaba-inc.com:thead-linux/prd_utils.git
|
||||||
|
|
||||||
#### 软件架构
|
# How to build
|
||||||
软件架构说明
|
1. export PATH=riscv-toolchain-2.2.8/bin:$PATH
|
||||||
|
2. mkdir build
|
||||||
|
3. cd buildout
|
||||||
|
4. cmake ../ -DBOARD_NAME="light" -DCMAKE_INSTALL_BINDIR=bin -DCMAKE_INSTALL_LIBDIR=lib -DCMAKE_INSTALL_INCLUDEDIR=include -DCMAKE_C_COMPILER=gcc
|
||||||
|
5. make
|
||||||
|
|
||||||
|
# Description of each directories
|
||||||
#### 安装教程
|
- cmake/: The cmake files for build.
|
||||||
|
- include/: The header files.
|
||||||
1. xxxx
|
- platform/: Different platform implementation code directories.
|
||||||
2. xxxx
|
- test/: The test cases.
|
||||||
3. xxxx
|
- utils/: The utils using in console.
|
||||||
|
|
||||||
#### 使用说明
|
|
||||||
|
|
||||||
1. xxxx
|
|
||||||
2. xxxx
|
|
||||||
3. xxxx
|
|
||||||
|
|
||||||
#### 参与贡献
|
|
||||||
|
|
||||||
1. Fork 本仓库
|
|
||||||
2. 新建 Feat_xxx 分支
|
|
||||||
3. 提交代码
|
|
||||||
4. 新建 Pull Request
|
|
||||||
|
|
||||||
|
|
||||||
#### 特技
|
|
||||||
|
|
||||||
1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md
|
|
||||||
2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com)
|
|
||||||
3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目
|
|
||||||
4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目
|
|
||||||
5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help)
|
|
||||||
6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
|
|
||||||
|
|||||||
6
cmake/board_light.cmake
Normal file
6
cmake/board_light.cmake
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2023 Alibaba Group Holding Limited
|
||||||
|
#
|
||||||
|
|
||||||
|
SET(CMAKE_C_COMPILER riscv64-linux-gcc)
|
||||||
|
SET(CMAKE_CXX_COMPILER riscv64-linux-c++)
|
||||||
11
cmake/custom_macros.cmake
Normal file
11
cmake/custom_macros.cmake
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2023 Alibaba Group Holding Limited
|
||||||
|
#
|
||||||
|
|
||||||
|
macro(BuildNormalProgram sourceName)
|
||||||
|
set(TargetName ${sourceName})
|
||||||
|
set(target_src ${sourceName}.c)
|
||||||
|
add_executable(${TargetName} ${target_src})
|
||||||
|
target_link_libraries(${TargetName} ${linkLibs})
|
||||||
|
endmacro(BuildNormalProgram)
|
||||||
|
|
||||||
19
cmake/show_cmake_param.cmake
Normal file
19
cmake/show_cmake_param.cmake
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2023 Alibaba Group Holding Limited
|
||||||
|
#
|
||||||
|
|
||||||
|
message("")
|
||||||
|
message("=== Show cmake system paramerters ===")
|
||||||
|
message(STATUS "PROJECT_NAME = ${PROJECT_NAME}")
|
||||||
|
message(STATUS "PROJECT_SOURCE_DIR = ${PROJECT_SOURCE_DIR}")
|
||||||
|
message(STATUS "PROJECT_BINARY_DIR = ${PROJECT_BINARY_DIR}")
|
||||||
|
message(STATUS "CMAKE_SOURCE_DIR = ${CMAKE_SOURCE_DIR}")
|
||||||
|
message(STATUS "CMAKE_SYSTEM_PROCESSOR = ${CMAKE_SYSTEM_PROCESSOR}")
|
||||||
|
message(STATUS "CMAKE_SYSTEM = ${CMAKE_SYSTEM}")
|
||||||
|
message(STATUS "CMAKE_C_COMPILER = ${CMAKE_C_COMPILER}")
|
||||||
|
message(STATUS "CMAKE_C_FLAGS = ${CMAKE_C_FLAGS}")
|
||||||
|
message(STATUS "CMAKE_SHARED_LINKER_FLAGS = ${CMAKE_SHARED_LINKER_FLAGS}")
|
||||||
|
message(STATUS "BOARD_NAME = ${BOARD_NAME}")
|
||||||
|
|
||||||
|
message(STATUS "CMAKE_INSTALL_LIBDIR = ${CMAKE_INSTALL_LIBDIR}")
|
||||||
|
message("")
|
||||||
41
include/prd_utils_internal.h
Normal file
41
include/prd_utils_internal.h
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Alibaba Group Holding Limited
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PRD_UTILS_INTERNAL_H
|
||||||
|
#define PRD_UTILS_INTERNAL_H
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#define MKTAG_NEGA(e) (-(e))
|
||||||
|
|
||||||
|
#define LOG_COLOR_RED_YELLO_BACK "\033[1;31;43m"
|
||||||
|
#define LOG_COLOR_RED "\033[2;31;49m"
|
||||||
|
#define LOG_COLOR_YELLOW "\033[2;33;49m"
|
||||||
|
#define LOG_COLOR_GREEN "\033[2;32;49m"
|
||||||
|
#define LOG_COLOR_BLUE "\033[2;34;49m"
|
||||||
|
#define LOG_COLOR_GRAY "\033[1;30m"
|
||||||
|
#define LOG_COLOR_WHITE "\033[1;47;49m"
|
||||||
|
#define LOG_COLOR_RESET "\033[0m"
|
||||||
|
|
||||||
|
|
||||||
|
#define PRD_UTILS_LOG(fmt, args...) \
|
||||||
|
do {printf("[%s():%d] ",__FUNCTION__, __LINE__); printf(fmt,##args);} while(0)
|
||||||
|
|
||||||
|
#define PRD_UTILS_ASSERT(expr) \
|
||||||
|
do { \
|
||||||
|
if (!(expr)) { \
|
||||||
|
printf(LOG_COLOR_RED \
|
||||||
|
"\nASSERT failed at:\n"\
|
||||||
|
" >File name: %s\n" \
|
||||||
|
" >Function : %s\n" \
|
||||||
|
" >Line No. : %d\n" \
|
||||||
|
" >Condition: %s\n" \
|
||||||
|
LOG_COLOR_RESET, \
|
||||||
|
__FILE__,__FUNCTION__, __LINE__, #expr);\
|
||||||
|
exit(-1); \
|
||||||
|
} \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* PRD_UTILS_INTERNAL_H */
|
||||||
30
include/prd_utils_kv.h
Normal file
30
include/prd_utils_kv.h
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Alibaba Group Holding Limited
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PRD_UTILS_KV_H
|
||||||
|
#define PRD_UTILS_KV_H
|
||||||
|
|
||||||
|
#define PRD_UTILS_KEY_MAX_LENGTH 64
|
||||||
|
#define PRD_UTILS_VAL_MAX_LENGTH 256
|
||||||
|
#define PRD_UTILS_KV_MAX_COUNT 128
|
||||||
|
|
||||||
|
#define PRD_UTILS_KEY_NAME_ETH_ADDR "ethaddr"
|
||||||
|
#define PRD_UTILS_KEY_NAME_SN "sn"
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
PRD_UTILS_RESULT_OK = 0,
|
||||||
|
PRD_UTILS_RESULT_KV_INPUT_INVALID = -1,
|
||||||
|
PRD_UTILS_RESULT_KV_IO_FAILED = -2,
|
||||||
|
PRD_UTILS_RESULT_KV_NOT_EXIST = -3,
|
||||||
|
} prd_utils_result_e;
|
||||||
|
|
||||||
|
// Notice:
|
||||||
|
// 1. input key CAN'T including space or other non-printable charater
|
||||||
|
// 2. input value CAN'T including any non-printable charater
|
||||||
|
|
||||||
|
int prd_utils_get_kv(char *key, char **value);
|
||||||
|
int prd_utils_set_kv(char *key, char *value);
|
||||||
|
int prd_utils_clean_kv(char *key);
|
||||||
|
|
||||||
|
#endif /* PRD_UTILS_KV_H */
|
||||||
20
platform/light/CMakeLists.txt
Normal file
20
platform/light/CMakeLists.txt
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2023 Alibaba Group Holding Limited
|
||||||
|
#
|
||||||
|
|
||||||
|
# include
|
||||||
|
INCLUDE_DIRECTORIES(./)
|
||||||
|
|
||||||
|
SET(LIBSOURCE
|
||||||
|
prd_utils_kv_light.c
|
||||||
|
uboot_env_params.c
|
||||||
|
)
|
||||||
|
|
||||||
|
ADD_LIBRARY(prd_utils SHARED ${LIBSOURCE})
|
||||||
|
|
||||||
|
INSTALL(DIRECTORY ./include/. DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||||
|
INSTALL(TARGETS prd_utils
|
||||||
|
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||||
|
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
|
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||||
|
|
||||||
53
platform/light/prd_utils_kv_light.c
Normal file
53
platform/light/prd_utils_kv_light.c
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Alibaba Group Holding Limited
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <prd_utils_kv.h>
|
||||||
|
#include <prd_utils_internal.h>
|
||||||
|
|
||||||
|
#include "uboot_env_params.h"
|
||||||
|
|
||||||
|
#define CHECK_KEY_VALID(key) \
|
||||||
|
do { \
|
||||||
|
if (key == NULL || strlen(key) >= PRD_UTILS_KEY_MAX_LENGTH) \
|
||||||
|
{ \
|
||||||
|
PRD_UTILS_LOG("key is NULL or key len > %d\n", PRD_UTILS_KEY_MAX_LENGTH); \
|
||||||
|
return PRD_UTILS_RESULT_KV_INPUT_INVALID; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define CHECK_VAL_VALID(val) \
|
||||||
|
do { \
|
||||||
|
if (val == NULL || strlen(val) >= PRD_UTILS_VAL_MAX_LENGTH) \
|
||||||
|
{ \
|
||||||
|
PRD_UTILS_LOG("val is NULL or val len > %d\n", PRD_UTILS_VAL_MAX_LENGTH); \
|
||||||
|
return PRD_UTILS_RESULT_KV_INPUT_INVALID; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
|
int prd_utils_get_kv(char *key, char **value)
|
||||||
|
{
|
||||||
|
CHECK_KEY_VALID(key);
|
||||||
|
|
||||||
|
return light_uboot_get_env(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
int prd_utils_set_kv(char *key, char *value)
|
||||||
|
{
|
||||||
|
CHECK_KEY_VALID(key);
|
||||||
|
CHECK_VAL_VALID(value);
|
||||||
|
|
||||||
|
return light_uboot_set_env(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
int prd_utils_clean_kv(char *key)
|
||||||
|
{
|
||||||
|
CHECK_KEY_VALID(key);
|
||||||
|
|
||||||
|
return light_uboot_clean_env(key);
|
||||||
|
}
|
||||||
|
|
||||||
93
platform/light/uboot_env_params.c
Normal file
93
platform/light/uboot_env_params.c
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Alibaba Group Holding Limited
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <prd_utils_kv.h>
|
||||||
|
#include <prd_utils_internal.h>
|
||||||
|
|
||||||
|
#include "uboot_env_params.h"
|
||||||
|
static char g_result[PRD_UTILS_VAL_MAX_LENGTH] = "";
|
||||||
|
|
||||||
|
static int execmd_fetch_result_string(const char *cmd, char *result)
|
||||||
|
{
|
||||||
|
char buffer[PRD_UTILS_VAL_MAX_LENGTH];
|
||||||
|
|
||||||
|
FILE *pipe = popen(cmd, "r");
|
||||||
|
if (pipe == NULL)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(!feof(pipe))
|
||||||
|
{
|
||||||
|
if(fgets(buffer, PRD_UTILS_VAL_MAX_LENGTH, pipe))
|
||||||
|
{
|
||||||
|
strcat(result, buffer);
|
||||||
|
if(strlen(result) >= PRD_UTILS_VAL_MAX_LENGTH)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pclose(pipe);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int light_uboot_get_env(const char *key, char **value)
|
||||||
|
{
|
||||||
|
char cmd[128 + PRD_UTILS_KEY_MAX_LENGTH] ="";
|
||||||
|
memset(g_result, 0, sizeof(g_result));
|
||||||
|
|
||||||
|
snprintf(cmd, sizeof(cmd),
|
||||||
|
"fw_printenv | grep '%s=' | awk -F '=' '{print $2}' | tr -d '\n' '\r'", key);
|
||||||
|
|
||||||
|
if (execmd_fetch_result_string(cmd, g_result) == 0)
|
||||||
|
{
|
||||||
|
*value = g_result;
|
||||||
|
if (strlen(*value) == 0)
|
||||||
|
{
|
||||||
|
//PRD_UTILS_LOG("light_uboot_get_env() failed, return enmpty value\n");
|
||||||
|
return PRD_UTILS_RESULT_KV_NOT_EXIST;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PRD_UTILS_RESULT_OK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*value = NULL;
|
||||||
|
//PRD_UTILS_LOG("light_uboot_get_env() failed\n");
|
||||||
|
return PRD_UTILS_RESULT_KV_IO_FAILED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int light_uboot_set_env(const char *key, char *value)
|
||||||
|
{
|
||||||
|
char cmd[128 + PRD_UTILS_KEY_MAX_LENGTH + PRD_UTILS_VAL_MAX_LENGTH] ="";
|
||||||
|
snprintf(cmd, sizeof(cmd), "fw_setenv %s '%s'", key, value);
|
||||||
|
|
||||||
|
if (system(cmd) != 0)
|
||||||
|
{
|
||||||
|
PRD_UTILS_LOG("execute cmd='%s' failed\n", cmd);
|
||||||
|
return PRD_UTILS_RESULT_KV_IO_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PRD_UTILS_RESULT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int light_uboot_clean_env(const char *key)
|
||||||
|
{
|
||||||
|
char cmd[128 + PRD_UTILS_KEY_MAX_LENGTH] = "";
|
||||||
|
snprintf(cmd, sizeof(cmd), "fw_setenv %s", key);
|
||||||
|
|
||||||
|
if (system(cmd) != 0)
|
||||||
|
{
|
||||||
|
PRD_UTILS_LOG("execute cmd='%s' failed\n", cmd);
|
||||||
|
return PRD_UTILS_RESULT_KV_IO_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PRD_UTILS_RESULT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
12
platform/light/uboot_env_params.h
Normal file
12
platform/light/uboot_env_params.h
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Alibaba Group Holding Limited
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef UBOOT_ENV_PARAMS_H
|
||||||
|
#define UBOOT_ENV_PARAMS_H
|
||||||
|
|
||||||
|
int light_uboot_get_env(const char *key, char **value);
|
||||||
|
int light_uboot_set_env(const char *key, char *value);
|
||||||
|
int light_uboot_clean_env(const char *key);
|
||||||
|
|
||||||
|
#endif /* UBOOT_ENV_PARAMS_H */
|
||||||
12
test/CMakeLists.txt
Normal file
12
test/CMakeLists.txt
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2023 Alibaba Group Holding Limited
|
||||||
|
#
|
||||||
|
|
||||||
|
include(${PROJECT_SOURCE_DIR}/cmake/custom_macros.cmake)
|
||||||
|
|
||||||
|
# Config all parameters for test cases below
|
||||||
|
set(linkLibs prd_utils)
|
||||||
|
|
||||||
|
# test factory param
|
||||||
|
BuildNormalProgram(test_prd_utils_kv)
|
||||||
|
|
||||||
254
test/test_prd_utils_kv.c
Normal file
254
test/test_prd_utils_kv.c
Normal file
@@ -0,0 +1,254 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Alibaba Group Holding Limited
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
#include <prd_utils_kv.h>
|
||||||
|
#include <prd_utils_internal.h>
|
||||||
|
|
||||||
|
#define KV_OP_MAX_DURATION 100 // unit: ms
|
||||||
|
|
||||||
|
static char test_key[] = "test_key";
|
||||||
|
static char test_val[] = "test value with spaces";
|
||||||
|
|
||||||
|
static char max_length_key[PRD_UTILS_KEY_MAX_LENGTH] =
|
||||||
|
"12345678901234567890123456789012345678901234567890" \
|
||||||
|
"1234567890123";
|
||||||
|
|
||||||
|
static char max_length_val[PRD_UTILS_VAL_MAX_LENGTH] =
|
||||||
|
"12345678901234567890123456789012345678901234567890" \
|
||||||
|
"12345678901234567890123456789012345678901234567890" \
|
||||||
|
"12345678901234567890123456789012345678901234567890" \
|
||||||
|
"12345678901234567890123456789012345678901234567890" \
|
||||||
|
"12345678901234567890123456789012345678901234567890" \
|
||||||
|
"12345";
|
||||||
|
|
||||||
|
typedef struct test_performance_records
|
||||||
|
{
|
||||||
|
// unit: us
|
||||||
|
int normal_set;
|
||||||
|
int normal_get;
|
||||||
|
int normal_clean;
|
||||||
|
int max_len_set;
|
||||||
|
int max_len_get;
|
||||||
|
int max_len_clean;
|
||||||
|
|
||||||
|
// tmp values
|
||||||
|
struct timeval tpstart;
|
||||||
|
struct timeval tpend;
|
||||||
|
} test_performance_records_t;
|
||||||
|
|
||||||
|
static test_performance_records_t perf_records;
|
||||||
|
|
||||||
|
#define GET_TIME_BEGIN() do { gettimeofday(&perf_records.tpstart, NULL); } while(0)
|
||||||
|
#define GET_TIME_RECORD(target) do { gettimeofday(&perf_records.tpend, NULL); \
|
||||||
|
target = 1000000 * (perf_records.tpend.tv_sec - perf_records.tpstart.tv_sec) \
|
||||||
|
+ perf_records.tpend.tv_usec - perf_records.tpstart.tv_usec; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
static int test_prd_utils_set_kv()
|
||||||
|
{
|
||||||
|
printf("Test: prd_utils_set_kv() start\n");
|
||||||
|
|
||||||
|
GET_TIME_BEGIN();
|
||||||
|
PRD_UTILS_ASSERT(prd_utils_set_kv(test_key, test_val) == PRD_UTILS_RESULT_OK);
|
||||||
|
GET_TIME_RECORD(perf_records.normal_set);
|
||||||
|
|
||||||
|
printf("Test: prd_utils_set_kv() pass\n\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int test_prd_utils_get_kv()
|
||||||
|
{
|
||||||
|
char *get_val;
|
||||||
|
printf("Test: prd_utils_get_kv() start\n");
|
||||||
|
|
||||||
|
GET_TIME_BEGIN();
|
||||||
|
PRD_UTILS_ASSERT(prd_utils_get_kv(test_key, &get_val) == PRD_UTILS_RESULT_OK);
|
||||||
|
GET_TIME_RECORD(perf_records.normal_get);
|
||||||
|
|
||||||
|
PRD_UTILS_ASSERT(strncmp(test_val, get_val, PRD_UTILS_VAL_MAX_LENGTH) == 0);
|
||||||
|
|
||||||
|
printf("Test: prd_utils_get_kv() pass\n\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int test_prd_utils_clean_kv()
|
||||||
|
{
|
||||||
|
char *get_val;
|
||||||
|
printf("Test: prd_utils_clean_kv() start\n");
|
||||||
|
|
||||||
|
GET_TIME_BEGIN();
|
||||||
|
PRD_UTILS_ASSERT(prd_utils_clean_kv(test_key) == PRD_UTILS_RESULT_OK);
|
||||||
|
GET_TIME_RECORD(perf_records.normal_clean);
|
||||||
|
|
||||||
|
PRD_UTILS_ASSERT(prd_utils_get_kv(test_key, &get_val) == PRD_UTILS_RESULT_KV_NOT_EXIST);
|
||||||
|
|
||||||
|
printf("Test: prd_utils_clean_kv() pass\n\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int test_prd_utils_max_kv_value_length()
|
||||||
|
{
|
||||||
|
char *get_val;
|
||||||
|
printf("Test: max value length(%u) start\n", PRD_UTILS_VAL_MAX_LENGTH);
|
||||||
|
|
||||||
|
PRD_UTILS_ASSERT(strlen(max_length_val) == PRD_UTILS_VAL_MAX_LENGTH - 1);
|
||||||
|
|
||||||
|
PRD_UTILS_ASSERT(prd_utils_set_kv(test_key, max_length_val) == PRD_UTILS_RESULT_OK);
|
||||||
|
PRD_UTILS_ASSERT(prd_utils_get_kv(test_key, &get_val) == PRD_UTILS_RESULT_OK);
|
||||||
|
PRD_UTILS_ASSERT(strncmp(max_length_val, get_val, PRD_UTILS_VAL_MAX_LENGTH) == 0);
|
||||||
|
|
||||||
|
PRD_UTILS_ASSERT(prd_utils_clean_kv(test_key) == PRD_UTILS_RESULT_OK);
|
||||||
|
PRD_UTILS_ASSERT(prd_utils_get_kv(test_key, &get_val) == PRD_UTILS_RESULT_KV_NOT_EXIST);
|
||||||
|
|
||||||
|
printf("Test: max value length(%u) pass\n\n", PRD_UTILS_VAL_MAX_LENGTH);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int test_prd_utils_max_kv_key_length()
|
||||||
|
{
|
||||||
|
char *get_val;
|
||||||
|
printf("Test: max key length(%u) start\n", PRD_UTILS_KEY_MAX_LENGTH);
|
||||||
|
|
||||||
|
PRD_UTILS_ASSERT(strlen(max_length_key) == PRD_UTILS_KEY_MAX_LENGTH - 1);
|
||||||
|
|
||||||
|
PRD_UTILS_ASSERT(prd_utils_set_kv(max_length_key, test_val) == PRD_UTILS_RESULT_OK);
|
||||||
|
PRD_UTILS_ASSERT(prd_utils_get_kv(max_length_key, &get_val) == PRD_UTILS_RESULT_OK);
|
||||||
|
PRD_UTILS_ASSERT(strncmp(test_val, get_val, PRD_UTILS_VAL_MAX_LENGTH) == 0);
|
||||||
|
|
||||||
|
PRD_UTILS_ASSERT(prd_utils_clean_kv(max_length_key) == PRD_UTILS_RESULT_OK);
|
||||||
|
PRD_UTILS_ASSERT(prd_utils_get_kv(max_length_key, &get_val) == PRD_UTILS_RESULT_KV_NOT_EXIST);
|
||||||
|
|
||||||
|
printf("Test: max key length(%u) pass\n\n", PRD_UTILS_KEY_MAX_LENGTH);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int test_prd_utils_max_kv_capacity()
|
||||||
|
{
|
||||||
|
char *get_val;
|
||||||
|
char test_key[PRD_UTILS_KEY_MAX_LENGTH];
|
||||||
|
char test_val[PRD_UTILS_VAL_MAX_LENGTH];
|
||||||
|
|
||||||
|
printf("Test: max kv capacity(key_len=%u, val_len=%u, count=%u) start\n",
|
||||||
|
PRD_UTILS_KEY_MAX_LENGTH, PRD_UTILS_VAL_MAX_LENGTH, PRD_UTILS_KV_MAX_COUNT);
|
||||||
|
|
||||||
|
const int test_loop_count = PRD_UTILS_KV_MAX_COUNT;
|
||||||
|
// set KVs
|
||||||
|
printf(" step1. testing set max kv(loop=%d):\n ", test_loop_count);
|
||||||
|
for (int i = 0; i < test_loop_count; i++)
|
||||||
|
{
|
||||||
|
//snprintf(test_key, PRD_UTILS_KEY_MAX_LENGTH, test_key_long_fmt, i);
|
||||||
|
snprintf(test_key, PRD_UTILS_KEY_MAX_LENGTH,
|
||||||
|
"12345678901234567890123456789012345678901234567890123456789_%03d", i);
|
||||||
|
|
||||||
|
PRD_UTILS_ASSERT(strlen(test_key) == PRD_UTILS_KEY_MAX_LENGTH - 1);
|
||||||
|
|
||||||
|
snprintf(test_val, PRD_UTILS_VAL_MAX_LENGTH,
|
||||||
|
"12345678901234567890123456789012345678901234567890" \
|
||||||
|
"12345678901234567890123456789012345678901234567890" \
|
||||||
|
"12345678901234567890123456789012345678901234567890" \
|
||||||
|
"12345678901234567890123456789012345678901234567890" \
|
||||||
|
"12345678901234567890123456789012345678901234567890" \
|
||||||
|
"1_%03d", i);
|
||||||
|
PRD_UTILS_ASSERT(strlen(test_val) == PRD_UTILS_VAL_MAX_LENGTH - 1);
|
||||||
|
|
||||||
|
if (i == 0) GET_TIME_BEGIN();
|
||||||
|
PRD_UTILS_ASSERT(prd_utils_set_kv(test_key, test_val) == PRD_UTILS_RESULT_OK);
|
||||||
|
if (i == 0) GET_TIME_RECORD(perf_records.max_len_set);
|
||||||
|
|
||||||
|
printf("."); fflush(stdout); if (i % 64 == 63) printf("\n ");
|
||||||
|
}
|
||||||
|
|
||||||
|
// get KVs and verify, clean
|
||||||
|
printf("step2. testing get max kv(loop=%d):\n ", test_loop_count);
|
||||||
|
for (int i = 0; i < test_loop_count; i++)
|
||||||
|
{
|
||||||
|
snprintf(test_key, PRD_UTILS_KEY_MAX_LENGTH,
|
||||||
|
"12345678901234567890123456789012345678901234567890123456789_%03d", i);
|
||||||
|
|
||||||
|
snprintf(test_val, PRD_UTILS_VAL_MAX_LENGTH,
|
||||||
|
"12345678901234567890123456789012345678901234567890" \
|
||||||
|
"12345678901234567890123456789012345678901234567890" \
|
||||||
|
"12345678901234567890123456789012345678901234567890" \
|
||||||
|
"12345678901234567890123456789012345678901234567890" \
|
||||||
|
"12345678901234567890123456789012345678901234567890" \
|
||||||
|
"1_%03d", i);
|
||||||
|
|
||||||
|
if (i == 0) GET_TIME_BEGIN();
|
||||||
|
PRD_UTILS_ASSERT(prd_utils_get_kv(test_key, &get_val) == PRD_UTILS_RESULT_OK);
|
||||||
|
if (i == 0) GET_TIME_RECORD(perf_records.max_len_get);
|
||||||
|
|
||||||
|
PRD_UTILS_ASSERT(strncmp(test_val, get_val, PRD_UTILS_VAL_MAX_LENGTH) == 0);
|
||||||
|
printf("."); fflush(stdout); if (i % 64 == 63) printf("\n ");
|
||||||
|
}
|
||||||
|
|
||||||
|
// clean KVs
|
||||||
|
printf("step3. testing clean max kv(loop=%d):\n ", test_loop_count);
|
||||||
|
for (int i = 0; i < test_loop_count; i++)
|
||||||
|
{
|
||||||
|
snprintf(test_key, PRD_UTILS_KEY_MAX_LENGTH,
|
||||||
|
"12345678901234567890123456789012345678901234567890123456789_%03d", i);
|
||||||
|
|
||||||
|
if (i == 0) GET_TIME_BEGIN();
|
||||||
|
PRD_UTILS_ASSERT(prd_utils_clean_kv(test_key) == PRD_UTILS_RESULT_OK);
|
||||||
|
if (i == 0) GET_TIME_RECORD(perf_records.max_len_clean);
|
||||||
|
|
||||||
|
PRD_UTILS_ASSERT(prd_utils_get_kv(test_key, &get_val) == PRD_UTILS_RESULT_KV_NOT_EXIST);
|
||||||
|
printf("."); fflush(stdout); if (i % 64 == 63) printf("\n ");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Test: max kv capacity(key_len=%u, val_len=%u, count=%u) pass\n\n",
|
||||||
|
PRD_UTILS_KEY_MAX_LENGTH, PRD_UTILS_VAL_MAX_LENGTH, PRD_UTILS_KV_MAX_COUNT);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
// test normal usage
|
||||||
|
PRD_UTILS_ASSERT(test_prd_utils_set_kv() == 0);
|
||||||
|
PRD_UTILS_ASSERT(test_prd_utils_get_kv() == 0);
|
||||||
|
PRD_UTILS_ASSERT(test_prd_utils_clean_kv() == 0);
|
||||||
|
|
||||||
|
// test max length
|
||||||
|
PRD_UTILS_ASSERT(test_prd_utils_max_kv_value_length() == 0);
|
||||||
|
PRD_UTILS_ASSERT(test_prd_utils_max_kv_key_length() == 0);
|
||||||
|
|
||||||
|
// test max capacity
|
||||||
|
PRD_UTILS_ASSERT(test_prd_utils_max_kv_capacity() == 0);
|
||||||
|
|
||||||
|
// print performance
|
||||||
|
printf("==== prd_utils performance test results ====================\n");
|
||||||
|
printf(" normal set_kv(key_len=%zu, val_len=%zu) cost %.3f ms\n",
|
||||||
|
strlen(test_key), strlen(test_val), (1.0 * perf_records.normal_set) / 1000);
|
||||||
|
printf(" normal get_kv(key_len=%zu, val_len=%zu) cost %.3f ms\n",
|
||||||
|
strlen(test_key), strlen(test_val), (1.0 * perf_records.normal_get) / 1000);
|
||||||
|
printf(" normal clean_kv(key_len=%zu, val_len=%zu) cost %.3f ms\n",
|
||||||
|
strlen(test_key), strlen(test_val), (1.0 * perf_records.normal_clean) / 1000);
|
||||||
|
|
||||||
|
printf(" max_len set_kv(key_len=%u, val_len=%u) cost %.3f ms\n",
|
||||||
|
PRD_UTILS_KEY_MAX_LENGTH, PRD_UTILS_VAL_MAX_LENGTH, (1.0 * perf_records.max_len_set) / 1000);
|
||||||
|
printf(" max_len get_kv(key_len=%u, val_len=%u) cost %.3f ms\n",
|
||||||
|
PRD_UTILS_KEY_MAX_LENGTH, PRD_UTILS_VAL_MAX_LENGTH, (1.0 * perf_records.max_len_get) / 1000);
|
||||||
|
printf(" max_len clean_kv(key_len=%u, val_len=%u) cost %.3f ms\n",
|
||||||
|
PRD_UTILS_KEY_MAX_LENGTH, PRD_UTILS_VAL_MAX_LENGTH, (1.0 * perf_records.max_len_clean) / 1000);
|
||||||
|
printf("============================================================\n");
|
||||||
|
|
||||||
|
PRD_UTILS_ASSERT(perf_records.normal_set/1000 < KV_OP_MAX_DURATION &&
|
||||||
|
perf_records.normal_get/1000 < KV_OP_MAX_DURATION &&
|
||||||
|
perf_records.normal_clean/1000 < KV_OP_MAX_DURATION &&
|
||||||
|
perf_records.max_len_set/1000 < KV_OP_MAX_DURATION &&
|
||||||
|
perf_records.max_len_get/1000 < KV_OP_MAX_DURATION &&
|
||||||
|
perf_records.max_len_clean/1000 < KV_OP_MAX_DURATION);
|
||||||
|
|
||||||
|
printf(LOG_COLOR_GREEN "All KV tests PASSED\n" LOG_COLOR_RESET);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
12
utils/CMakeLists.txt
Normal file
12
utils/CMakeLists.txt
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2023 Alibaba Group Holding Limited
|
||||||
|
#
|
||||||
|
|
||||||
|
include(${PROJECT_SOURCE_DIR}/cmake/custom_macros.cmake)
|
||||||
|
|
||||||
|
# Config all parameters for test cases below
|
||||||
|
set(linkLibs prd_utils)
|
||||||
|
|
||||||
|
# test factory param
|
||||||
|
BuildNormalProgram(prd_utils_kv)
|
||||||
|
|
||||||
128
utils/prd_utils_kv.c
Normal file
128
utils/prd_utils_kv.c
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Alibaba Group Holding Limited
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
|
||||||
|
#include <prd_utils_kv.h>
|
||||||
|
|
||||||
|
#define PROGRAM_NAME "prd_utils_kv"
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int op_code; /* 0: set, 1:get; 2: clean */
|
||||||
|
char key[PRD_UTILS_KEY_MAX_LENGTH];
|
||||||
|
char val[PRD_UTILS_VAL_MAX_LENGTH];
|
||||||
|
} cmd_params_s;
|
||||||
|
|
||||||
|
static const char *shortopts = "hs:g:c:";
|
||||||
|
static const struct option long_options[] =
|
||||||
|
{
|
||||||
|
{"help", no_argument, 0, 'h'},
|
||||||
|
{"SetParam", required_argument, 0, 's'},
|
||||||
|
{"GetParam", required_argument, 0, 'g'},
|
||||||
|
{"CleanParam", required_argument, 0, 'c'},
|
||||||
|
{0, 0, 0, 0 } // Act as end of option
|
||||||
|
};
|
||||||
|
|
||||||
|
static void usage(char *program_name)
|
||||||
|
{
|
||||||
|
printf("Usage: %s [OPTION]\n", program_name);
|
||||||
|
printf(" -h, --help display this help and exit\n");
|
||||||
|
printf(" -s, --SetParam set param, for example: %s -s sn=123456abcde\n", program_name);
|
||||||
|
printf(" -g, --GetParam get param, for example: %s -g sn\n", program_name);
|
||||||
|
printf(" -c, --CleanParam clean param, for example: %s -c sn\n", program_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int parse_params(int argc, char *argv[], cmd_params_s *params)
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
int option_index = 0;
|
||||||
|
int option_count = 0;
|
||||||
|
|
||||||
|
char *program_name = PROGRAM_NAME;
|
||||||
|
|
||||||
|
char *equal_sign;
|
||||||
|
int pos;
|
||||||
|
|
||||||
|
while ((c = getopt_long(argc, argv, shortopts, long_options, &option_index)) != -1)
|
||||||
|
{
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
case 'h':
|
||||||
|
usage(program_name);
|
||||||
|
exit(0);
|
||||||
|
case 's':
|
||||||
|
params->op_code = 0;
|
||||||
|
equal_sign = strchr(optarg, '=');
|
||||||
|
if (equal_sign == NULL)
|
||||||
|
{
|
||||||
|
printf("command is invalid, please flow:\n");
|
||||||
|
usage(program_name);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
pos = equal_sign - optarg;
|
||||||
|
strncpy(params->key, optarg, pos);
|
||||||
|
strncpy(params->val, optarg + pos + 1, strlen(optarg) - pos);
|
||||||
|
option_count++;
|
||||||
|
break;
|
||||||
|
case 'g':
|
||||||
|
params->op_code = 1;
|
||||||
|
sscanf(optarg, "%s", params->key);
|
||||||
|
option_count++;
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
params->op_code = 2;
|
||||||
|
sscanf(optarg, "%s", params->key);
|
||||||
|
option_count++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("Not supported opt:'%c'\n", c);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return option_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
char *val;
|
||||||
|
|
||||||
|
cmd_params_s cmd_params;
|
||||||
|
memset(&cmd_params, 0, sizeof(cmd_params));
|
||||||
|
int option_count = parse_params(argc, argv, &cmd_params);
|
||||||
|
if (option_count == 0)
|
||||||
|
{
|
||||||
|
usage(PROGRAM_NAME);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (cmd_params.op_code)
|
||||||
|
{
|
||||||
|
case 0: // set
|
||||||
|
ret = prd_utils_set_kv(cmd_params.key, cmd_params.val);
|
||||||
|
printf("set '%s'='%s' %s\n", cmd_params.key, cmd_params.val, (ret == 0) ? "OK" : "failed");
|
||||||
|
break;
|
||||||
|
case 1: // get
|
||||||
|
ret = prd_utils_get_kv(cmd_params.key, &val);
|
||||||
|
if (ret != 0)
|
||||||
|
{
|
||||||
|
printf("get sys param '%s' failed\n", cmd_params.key);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
printf("Got sys param '%s'='%s'\n", cmd_params.key, val);
|
||||||
|
break;
|
||||||
|
case 2: // clean;
|
||||||
|
ret = prd_utils_clean_kv(cmd_params.key);
|
||||||
|
printf("clean sys param '%s' %s\n", cmd_params.key, (ret == 0) ? "OK" : "failed");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user