ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

CANN Runtime ErrMsg 真实上报 UT 验证框架搭建指南:让 ErrorManager 打印格式化错误码

CANN Runtime ErrMsg 真实上报 UT 验证框架搭建指南:让 ErrorManager 打印格式化错误码 CANN Runtime ErrMsg 真实上报 UT 验证框架搭建指南让 ErrorManager 打印格式化错误码【免费下载链接】runtime本项目提供CANN运行时组件和维测功能组件。项目地址: https://gitcode.com/cann/runtime导读在 CANN Runtime 的单元测试UT环境中ErrorManager::ATCReportErrMessage默认被 stub 替换导致 ErrMsg 上报整改的 PR 无法在测试中验证格式化输出效果。本文基于tests/ut/runtime/runtime现有 UT 工程给出了一套完整的真实 ErrorManager UT 验证框架搭建方法通过取消CFG_DEV_PLATFORM_PC宏定义让错误上报宏如COND_RETURN_AND_MSG_OUTER调用真实实现并配合条件编译解决 stub 与真实类同名冲突。读完本文你将能够独立搭建验证目标、编写覆盖 EE1013 / EE1003 / EE1004 / EE1017 / EE1018 / EE1006 / EE9999 等常见错误码的测试用例并输出与生产环境一致的格式化 ErrMsg。背景为什么 UT 里看不到真实的 ErrMsgRuntime 的错误上报整改引入了统一的 ErrMsg 机制错误码如 EE1013通过 error_code.json 中的模板ErrMessage、Arglist、Possible Cause、Solution进行格式化最终由ErrorManager单例统一输出。这一链路的核心实现位于 error_manager.cc 与 error_manager.h。然而在默认的 UT 编译环境下存在三个障碍宏定义导致上报被跳过UT 默认定义CFG_DEV_PLATFORM_PC错误上报宏如COND_RETURN_AND_MSG_OUTER在展开后直接走跳过分支错误信息根本不会进入ErrorManager。stub 替换真实实现UT 工程默认链接 error_manager_stub.ccATCReportErrMessage是空实现无法输出格式化内容。同名类冲突stub 中同样声明了一个ErrorManager类若直接引入真实实现会出现redefinition of class ErrorManager编译错误。因此要验证ErrMsg 上报整改效果必须绕过这三个障碍让测试目标链接真实ErrorManager并真正打印格式化后的错误信息。核心原理本方案的核心链路可以概括为三步取消宏定义通过target_compile_options(... -UCFG_DEV_PLATFORM_PC)取消CFG_DEV_PLATFORM_PC使 error_message_manage.hpp 中的上报宏如COND_RETURN_AND_MSG_OUTER、NULL_PTR_RETURN_MSG_OUTER、RT_LOG_INNER_MSG走真实上报路径调用ErrorManager。链接真实实现在 CMake 目标中直接加入 error_manager.cc同时排除error_manager_stub.cc。条件编译解决冲突用#if defined(CFG_DEV_PLATFORM_PC)包裹 stub 头文件中的ErrorManager类当宏被取消后 stub 类不参与编译真实类生效两套同名类互不干扰。Step 1修改 CMakeLists.txt 追加测试目标在 tests/ut/runtime/runtime/CMakeLists.txt 末尾追加独立测试目标runtime_utest_errmsg_real完整配置见 appendix_a_cmake.txt。核心要点如下add_executable(runtime_utest_errmsg_real ${runtime_raw_device_adpt_common_list} # ... driver 与 v100 stub 源文件此处省略详见附录 A... # 真实 ErrorManager 实现关键替代 stub ${TOP_DIR}/src/dfx/error_manager/error_manager.cc # 只保留必要的 stub排除 error_manager_stub.cc stub/hal_stub.cc stub/atrace_stub.cc stub/awatch_dog_stub.cc stub/log_stub.cc stub/prof_stub.cc stub/platform_stub.cc # 测试文件 test/main.cc test/rt_errmsg_real_test.cc ) # 关键取消 CFG_DEV_PLATFORM_PC 定义让 ErrMsg 宏调用真实 ErrorManager target_compile_options(runtime_utest_errmsg_real PRIVATE -UCFG_DEV_PLATFORM_PC )关键配置项说明配置项说明${TOP_DIR}/src/dfx/error_manager/error_manager.cc真实 ErrorManager 实现替代 stubstub/hal_stub.cc必须保留提供 hal 函数 stub不包含stub/error_manager_stub.cc排除 stub使用真实实现-UCFG_DEV_PLATFORM_PC取消定义让宏调用真实 ErrorManageradd_dependencies(runtime_ut_all runtime_utest_errmsg_real)将新目标挂入 UT 依赖链同时需要将 error_manager.h 所在的src/dfx/error_manager、include/dfx等目录加入target_include_directories并链接runtimeut_src_static_lib、mockcpp、pthread、dl。该目标还定义了TEMP_PERFORMANCE、TEMP_PERFORMANCE_NOT_OUTPUT编译宏与既有 UT 目标保持一致。Step 2用条件编译改造 stub 头文件修改 tests/ut/runtime/runtime/stub/rt_utest_stub.h将文件末尾的 stubErrorManager类用条件编译包裹完整对比见 appendix_b_stub.txt// stub ErrorManager only when CFG_DEV_PLATFORM_PC is defined // otherwise, use real ErrorManager from error_manager.h #if defined(CFG_DEV_PLATFORM_PC) class ErrorManager { public: static ErrorManager GetInstance(); void SetStage(const std::string firstStage, const std::string secondStage); void ATCReportErrMessage(std::string error_code, const std::vectorstd::string key {}, const std::vectorstd::string value {}); int Init(); int ReportInterErrMessage(std::string error_code, const std::string error_msg); std::string GetErrorMessage(); const std::string GetLogHeader(); }; #endif原理说明当-UCFG_DEV_PLATFORM_PC取消定义后stubErrorManager类因#if条件不满足而不被编译此时由base.hpp引入的真实error_manager.h中的ErrorManager类生效从而避免两个同名类冲突。此修改仅影响runtime_utest_errmsg_real目标其他 UT 目标因仍定义CFG_DEV_PLATFORM_PC而继续使用 stub互不影响。Step 3创建测试文件并编写用例创建 tests/ut/runtime/runtime/test/rt_errmsg_real_test.cc完整模板见 appendix_c_test.txt。测试夹具Fixture负责初始化和清理#include gtest/gtest.h #include string #include vector #include iostream #include error_manager.h #include base.hpp #include error_message_manage.hpp #include errcode_manage.hpp #include error_codes/rt_error_codes.h using namespace cce::runtime; class ErrMsgRealTest : public ::testing::Test { protected: void SetUp() override { std::string json_base_path /mnt/workspace/gitCode/cann-fork/runtime/src/dfx/; int32_t ret ErrorManager::GetInstance().Init(json_base_path); std::cout [SetUp] ErrorManager Init ret ret std::endl; uint64_t work_stream_id 0; ErrorManager::GetInstance().ClearErrorMsgContainer(work_stream_id); } void TearDown() override { uint64_t work_stream_id 0; ErrorManager::GetInstance().ClearErrorMsgContainer(work_stream_id); } std::string GetAndPrintErrMsg() { std::string err_msg ErrorManager::GetInstance().GetErrorMessage(); std::cout \n ErrMsg Output \n err_msg \n\n std::endl; return err_msg; } };注意ErrorManager::Init(path)的入参指向src/dfx/目录内部按error_manager/error_code.json相对路径解析实际使用时请替换为你的工作目录。从 error_manager.cc 的实现看Init通过ParseJsonFile解析模板文件并懒初始化到error_map_只有初始化成功返回 0后ATCReportErrMessage才能按模板格式化。Lambda 包装宏调用的关键技巧COND_RETURN_AND_MSG_OUTER宏内部带有return RTERRCODE语句定义见 error_message_manage.hpp而 gtest 的TEST_F是 void 函数直接调用会编译失败。解决方案是用 lambda 包装让宏内的return在 lambda 内生效auto test_func []() - rtError_t { COND_RETURN_AND_MSG_OUTER(true, RT_ERROR_MEMORY_ALLOCATION, ErrorCode::EE1013, buf_size); return RT_ERROR_NONE; // 条件不满足时返回 }; rtError_t ret test_func(); // 调用 lambda而RT_LOG_INNER_MSG宏没有return可以直接调用。常见错误码测试用例对照表Skill 中给出了错误码、源文件位置与宏名称的对照测试用例即围绕这些真实上报点展开错误码源文件位置宏名称场景EE1013uma_arg_loader.cc:62COND_RETURN_AND_MSG_OUTER内存分配失败EE1003kernel_utils.cc:198-200COND_RETURN_AND_MSG_OUTER参数值无效EE1004para_convertor.cc:136NULL_PTR_RETURN_MSG_OUTER指针参数为空EE1017para_convertor.cc:35-37COND_RETURN_AND_MSG_OUTER参数不匹配EE1018model.cc:874-876COND_RETURN_AND_MSG_OUTERAPI 调用顺序错误EE1006kernel_utils.cc:229-230COND_RETURN_AND_MSG_OUTER功能不支持EE9999capture_model.cc:719RT_LOG_INNER_MSG内部错误每个用例的模式一致先打印测试说明再用 lambda 触发上报宏最后通过EXPECT_TRUE(err_msg.find(...))断言格式化结果中的关键片段。例如 EE1013 用例断言Failed to allocate、buf_size、host memory、Runtime、EE1013均出现在输出中。这些断言词与 error_code.json 中 EE1013 的模板一一对应——Failed to allocate %s bytes of host memory via %s to Runtime.、Possible Cause与Solution字段也都会被如实拼装进最终输出。如需新增其他错误码测试直接复制 appendix_c_test.txt 末尾的通用模板替换EEXXXX、RT_ERROR_XXX、参数与断言文本即可。Step 4准备 error_code.json真实ErrorManager初始化时需要读取错误码模板文件mkdir -p src/conf/error_manager cp src/dfx/error_manager/error_code.json src/conf/error_manager/该 JSON 文件按errClass如RTS Errors、errTitle、ErrCode、ErrMessage、Arglist、suggestion组织是格式化输出的词典。以 EE1013 为例见 error_code.json{ errClass: RTS Errors, errTitle: Resource_Error_Insufficient_Host_Memory, ErrCode: EE1013, ErrMessage: Failed to allocate %s bytes of host memory via %s to Runtime., Arglist: buf_size, alloc_interface, suggestion: { Possible Cause: Allocation failed due to insufficient host memory., Solution: Ensure that there is sufficient memory available. You can stop unnecessary processes to free up memory. } }上报宏传入的实参按Arglist顺序填入%s占位符最终拼装出完整错误信息。若路径不正确Init会返回 -1测试输出的 ErrMsg 为空。Step 5编译与运行编译# 方式 1使用 build_ut.sh推荐注意不加 -u 参数避免运行所有 UT bash tests/build_ut.sh --target runtime_utest_errmsg_real # 方式 2使用 make最快 cd build make -j8 runtime_utest_errmsg_real cd ..运行# 运行所有 ErrMsg 测试 ./build/tests/ut/runtime/runtime/runtime_utest_errmsg_real --gtest_filterErrMsgRealTest* # 运行单个错误码测试 ./build/tests/ut/runtime/runtime/runtime_utest_errmsg_real --gtest_filterErrMsgRealTest.EE1013* ./build/tests/ut/runtime/runtime/runtime_utest_errmsg_real --gtest_filterErrMsgRealTest.EE1003* ./build/tests/ut/runtime/runtime/runtime_utest_errmsg_real --gtest_filterErrMsgRealTest.EE1004* ./build/tests/ut/runtime/runtime/runtime_utest_errmsg_real --gtest_filterErrMsgRealTest.EE1017* ./build/tests/ut/runtime/runtime/runtime_utest_errmsg_real --gtest_filterErrMsgRealTest.EE1018* ./build/tests/ut/runtime/runtime/runtime_utest_errmsg_real --gtest_filterErrMsgRealTest.EE1006* ./build/tests/ut/runtime/runtime/runtime_utest_errmsg_real --gtest_filterErrMsgRealTest.EE9999* # 一键编译 运行 cd build make -j8 runtime_utest_errmsg_real cd .. \ ./build/tests/ut/runtime/runtime/runtime_utest_errmsg_real --gtest_filterErrMsgRealTest*完整命令与常见问题汇总见 appendix_d_commands.txt。输出验证两种 ErrMsg 形态测试运行后会输出两种 ErrMsg日志输出console 直接打印来自PrintErrMsgToLogErrorManager 输出 ErrMsg Output 区块来自ErrorManager::GetErrorMessage()示例输出EE1013[PID: 12345] 2025-04-28-15:38:53.922.974 Resource_Error_Insufficient_Host_Memory(EE1013): Failed to allocate 1024 bytes host memory for Runtime. Possible Cause: Allocation failed due to insufficient host memory. Solution: Stop unnecessary processes and ensure that the required memory is available.观察要点错误标题Resource_Error_Insufficient_Host_Memory来自 JSON 的errTitle正文由ErrMessage模板填充参数生成Possible Cause与Solution来自suggestion字段。这与生产环境中用户看到的错误信息完全一致从而验证 ErrMsg 上报整改的真实效果。从 error_manager.h 的注释可知GetErrorMessage()调用成功后还会清理已有错误信息因此每个用例独立调用、独立断言互不污染。常见问题排查问题 1编译报错 redefinition of class ErrorManager原因未修改stub/rt_utest_stub.hstub ErrorManager 与真实 ErrorManager 冲突。解决按 appendix_b_stub.txt 修改 stub 头文件添加条件编译。问题 2ErrMsg 输出为空原因未取消CFG_DEV_PLATFORM_PC定义宏调用被跳过。解决确保 tests/ut/runtime/runtime/CMakeLists.txt 中有target_compile_options(... -UCFG_DEV_PLATFORM_PC)。问题 3ErrorManager Init 返回 -1原因error_code.json路径不正确。解决检查路径是否为src/conf/error_manager/error_code.json相对于工作目录或确认SetUp中Init(path)的path指向包含error_manager/error_code.json的目录。注意事项此测试目标仅用于本地验证不提交到仓库修改前记录 worktree 中已有改动不覆盖用户已修改的 CMake、stub 或测试文件验证结束后只清理本次创建的临时内容未经用户授权不使用可能丢失已有改动的恢复命令如需新增错误码测试参考 appendix_c_test.txt 中已有测试用例格式并确保error_code.json中已存在对应错误码模板由于真实ErrorManager采用按work_stream_id分桶存储错误信息见 error_manager.h测试中固定使用work_stream_id 0并在SetUp/TearDown中清理保证用例间隔离。扩展阅读错误上报宏的完整定义与分类 error_message_manage.hppErrorManager 单例的公开接口Init/ATCReportErrMessage/GetErrorMessage等 error_manager.h全部错误码模板含RTS Errors分类下 EE10xx 系列 error_code.json错误码参考文档 docs/zh/error_code_ref/RTS-Errors【免费下载链接】runtime本项目提供CANN运行时组件和维测功能组件。项目地址: https://gitcode.com/cann/runtime创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表