本文主要记录了将mbedtls移植到YoC的过程,为测试人员对其他开源组件测试集做移植提供参考。 通常来说,知名开源组件测试集覆盖测试点广,质量较高,具有移植价值,但它们大多基于x86平台,并且包含较为复杂的测试框架,移植起来还是有一点难度的。
下面就以mbedtls为例,介绍一下其移植过程。
mbedtls测试集执行流程
参考github上mbedtls的readme.md及tests/Makefile, 可以知道,mbedtls测试集当中每个模块生成单独的可执行文件,以aes.ecb为例,涉及到的输入文件如下:
Main code file : suites/main_test.function
Platform code file : suites/host_test.function
Helper file : suites/helpers.function
Test suite file : suites/test_suite_aes.function
Test suite data : suites/test_suite_aes.ecb.data
Script file : scripts/generate_test_code.py
涉及到的输出文件如下:
Test suite file : test_suite_aes.ecb.c
Test suite data : test_suite_aes.ecb.datax
generate_test_code.py以.function文件为模板,参考.data文件生成test_suite_aes.ecb.c和test_suite_aes.ecb.datax。 以test_suite_aes.ecb.c为例,参考test_suite_aes.ecb.datax前两行:
AES-128-CBC Encrypt NIST KAT #1
2:hex:"fffffffffffff8000000000000000000":hex:"00000000000000000000000000000000":hex:"00000000000000000000000000000000":hex:"8b527a6aebdaec9eaef8eda2cb7783e5":int:0
第一行为case描述,第二行首先被parse_arguments分隔存入params数组,params第一个元素为2,参考test_funcs,对应要执行的function为test_aes_encrypt_cbc_wrapper,查看convert_params函数可以知道最终执行的函数调用为
unsigned char *p0 = {0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
size_t p1 = 16;
unsigned char *p2 ={0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
size_t p3 = 16;
unsigned char *p4 ={0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
size_t p5 = 16;
unsigned char *p6={0x8b,0x52,0x7a,0x6a,0xeb,0xda,0xec,0x9e,0xae,0xf8,0xed,0xa2,0xcb,0x77,0x83,0xe5};
size_t p7 = 16;
int p8 = 0
test_aes_encrypt_cbc ({p0,p1}, {p2,p3},{p4,p5},{p6,p7}, p8)
test_aes_encrypt_cbc里面使用TEST_ASSERT来判断case是否pass。
移植设计
首先,我们需要将datax文件放到YoC当中,目前YoC支持spiffs和lfs文件系统,这里我们以lfs为例,介绍一下如何将datax文件放入YoC。 参考
solutions_cb5654/smart_speaker_demo/app/src/audio/lfsdisk/README.md
可以将支持的模块的datax文件都放入一个文件夹,然后制作好镜像。
在要编译的package.yaml里面指定的config.yaml里面添加lfs分区,设定好大小,要和制作的lfs镜像文件的大小保持一致。 在要编译的package.yaml里面Makefile里面指定好编好的lfs镜像目录,将其copy到$(MK_GENERATED_IMGS_PATH)/data/lfs当中。
其次,mbedtls测试集使用了fgets来读取文件内容,YoC不支持FILE *指针,我们使用aos_read自己实现了fgets,代码如下:
static char my_fgets(int fd, char s, int n)
{
int c;
char *cs;
cs = s;
while(--n > 0 && (c = aos_read(fd, s, 1)) > 0)
{
if((*cs++ = *s++) == '\n')
{
break;
}
}
*cs = '0';
return (c == 0 && cs == s) ? NULL : s ;
}
fopen, fclose可以直接用aos_open, aos_close替换,feof逻辑使用do while循环替换。
问题及调试
YoC里面case是编译成一个solution,然后利用console组件aos_cli_register_command将需要执行的suite注册为串口命令,通过串口命令来执行对应的case。前面提到每个模块都会被编成单独的可执行文件,所以有各自的main函数,移植需要将各模块的main修改,这里采用的方式是修改main为$main_name,然后在scripts/generate_test_code.py里面add_input_info函数增加
snippets['main_name'] = c_file.strip("./")[:-2].replace(".","_")
另外,由于要读取的文件存入了lfs分区,需要修改suites/host_test.function里面的execute_tests将default_filename从"DATA_FILE"改为"/lfs/DATA_FILE"。
此外,由于用到了vfs相关api,需要在suites/helpers.function里面增加#include ,但这样会导致编译失败,由于我们不需要在x86平台生成可执行文件,可以修改tests/Makefile,注释掉$(CC) $(LOCAL_CFLAGS) $(CFLAGS) $< $(MBEDTLS_TEST_OBJS) $(LOCAL_LDFLAGS) $(LDFLAGS) -o $@。
编译过程还会缺乏文件,相关的都一并引入,如图
需要在package.yaml当中的source_file里面添加
app/src/mbedtls_test/*.c
app/src/mbedtls_test/src/*.c
最后编译还是会报重复定义,在重复的函数名前添加static限定即可解决。
参考文件patch: https://gist.github.com/lzq420241/63ad7d7465c8452ba0c480d168c99748