Merged
【57cdc9b33e1f526334d496df144e3fdc】feat:优化BIOS备件配置恢复 #262
liucongAdd on Aug 17
【57cdc9b33e1f526334d496df144e3fdc】feat:优化BIOS备件配置恢复 #262
Merged
Merged fromhwliuc/biosmainintoopenUBMC/biosmain
Total: 5 files changed+267-60
| @@ -527,6 +527,30 @@ sequenceDiagram | |||
| 527 | - 摘要计算在文件写入后异步 `skynet.fork` 执行,不阻塞 IPMI 响应;多系统各独立,无消息队列堆积风险。 | 527 | - 摘要计算在文件写入后异步 `skynet.fork` 执行,不阻塞 IPMI 响应;多系统各独立,无消息队列堆积风险。 |
| 528 | 528 | ||
| 529 | ### 2.2.6 可靠性分析 | 529 | ### 2.2.6 可靠性分析 |
| 530 | + | ||
| 531 | +#### SFMEA 分析表 | ||
| 532 | + | ||
| 533 | +| 用例编号 | 关键步骤 | 故障模式 | 故障影响 | 严重程度 | 容错措施 | 可定位性信息 | 故障注入方法 | 是否已落入DT(未落入说明原因) | 备注 | | ||
| 534 | +|---------|---------|---------|---------|-------|---------|------------|------------|----------------------------|------| | ||
| 535 | +| TC-SFMEA-001 | 初始化兜底备份 | ST-002 文件写入失败(备份副本拷贝失败) | 兜底备份缺失,后续备件更换比对无基准,误判为不一致而置位 | 严重 | 备份失败打印 error 日志不阻断初始化;下次上报或重启重试 | ERROR [bios]system %s backup %s fail | 源文件目录置为只读/无写权限后触发 init_backup | 可以落入DT(test_init_backup_missing/error 已覆盖) | | | ||
| 536 | +| TC-SFMEA-002 | 初始化兜底备份 | DT-002 数据掉电丢失(补备过程中断电/异常退出) | 备份文件半写入或未落盘,备份与源不一致,恢复时用损坏备份 | 严重 | backup_file 拷贝完成后再落盘;拷贝过程应用临时文件+重命名原子写 | ERROR cache not flushed / backup incomplete | 补备过程中强制断电 | 需要开发分析:断电时机难以在DT精确注入 | | | ||
| 537 | +| TC-SFMEA-003 | 带内文件写入 | ST-005 磁盘空间不足(/data/opt 空间满) | 源文件写入失败或备份拷贝失败,备份缺失致无法恢复配置 | 严重 | 写入前检查剩余空间;失败打印 error 日志不阻断 IPMI 响应,下次上报重试 | ERROR No space left on device;df -h 检查 | 填充磁盘至满后触发 WriteFileToBmc | 需要开发分析:磁盘空间耗尽环境构造受限 | | | ||
| 538 | +| TC-SFMEA-004 | 带内文件写入 | ST-003 文件内容损坏/格式错误(BIOS 上报半写入/空文件) | 空或损坏的源文件被当作正常配置备份,覆盖有效历史备份,后续比对失效 | 严重 | backup_file 前用 is_file_nonempty 校验源文件非空;备份内容回读校验 | ERROR source file empty / content corrupt | 上报空文件或截断文件 | 可以落入DT(test_backup_file_error 已覆盖) | | | ||
| 539 | +| TC-SFMEA-005 | 备份副本刷新 | DT-001 数据校验不一致(拷贝后未校验,备份与源内容不一致) | 备份内容与源不一致,备件更换比对时误判一致/不一致,恢复出错误配置 | 严重 | 拷贝成功后回读计算哈希与源文件比对(compare_file_with_backup 自校验),不一致则重试 | WARN backup checksum mismatch | 拷贝后篡改备份文件再比对 | 可以落入DT(test_replace_flag_same_noset/diff_set 已覆盖) | | | ||
| 540 | +| TC-SFMEA-006 | 备件更换检测 | IPC-003 D-Bus/MDB 调用失败 / SV-003 依赖服务返回错误(GetComponentComponentObject 失败) | 无法获取 ReplaceFlag,按容错视为未更换,备件更换后漏置位,用户配置丢失 | 严重 | 沿用既有 pcall 容错,失败时记录日志并视为未更换;下次上报重试刷新 | ERROR get_replace_flag failed;告警 ReplaceFlagQueryFailed | mock GetComponentComponentObject 返回异常/超时 | 需要开发分析:依赖组件服务环境与 mock 构造复杂 | | | ||
| 541 | +| TC-SFMEA-007 | 备件更换检测 | HW-006 硬件状态异常(replace_flag 属性读取值不准确/抖动) | replace_flag 误置 true 触发误置位,或漏置导致不恢复 | 严重 | 状态变化前先连续确认;依赖既有组件状态上报机制;误置位可经恢复流程修正 | WARN replace_flag unexpected change | 模拟 replace_flag 多次翻转 | 可以落入DT(test_replace_trigger_set 已覆盖) | | | ||
| 542 | +| TC-SFMEA-008 | 内容比对 | ST-001 文件读取失败(备份文件读取失败) | 备份读取失败视为不一致而误置位,触发不必要恢复;或读源失败无法比对 | 一般 | compare_file_with_backup 内备份不存在/读取失败返回 false 前打印日志,供人工确认 | ERROR read backup file fail / hash nil | 删除或改名备份文件后触发比对 | 可以落入DT(test_replace_flag_diff_set 已覆盖) | | | ||
| 543 | +| TC-SFMEA-009 | 内容比对 | ST-003 文件内容损坏/格式错误(备份文件被破坏/哈希异常) | 备份损坏致比对误判,恢复时导入失败,配置无法恢复 | 严重 | 比对前校验备份文件完整性(存在且非空);损坏时告警并保留损坏备份供人工恢复 | ERROR backup file corrupt / hash mismatch;告警 BackupCorrupted | 篡改备份文件内容 | 可以落入DT(test_import_old_setup_partial_fail 已覆盖) | | | ||
| 544 | +| TC-SFMEA-010 | 恢复标记置位与持久化 | DT-002 数据掉电丢失 / SQL-008 数据库持久化失败(置位后未及时落库) | NeedRecoverSetup 丢失,重启后不恢复配置,用户配置永久丢失 | 致命 | 置位后立即 info_db:save() 持久化;持久化失败重试并告警 | CRIT NeedRecoverSetup persist fail;log:notice 置位事件 | 置位后立即断电;mock save 失败 | 需要开发分析:断电时机难以在DT精确注入 | | | ||
| 545 | +| TC-SFMEA-011 | 配置恢复 ImportOldSetup | SC-002 证书校验失败(安全启动证书导入失败) | secureboot 证书未恢复,恢复流程保留 NeedRecoverSetup 反复重试,其余配置已恢复 | 一般 | 失败项打印 error 日志并保留标记等待重试;恢复流程不部分提交,但证书为追加语义可重入 | ERROR recover secureboot fail / cert import failed | 构造非法证书串导入 | 可以落入DT(test_import_old_setup_secureboot/partial_fail 已覆盖) | | | ||
| 546 | +| TC-SFMEA-012 | 配置恢复 ImportOldSetup | IPC-005 通信对端无响应(PolicyConfig IMU 下发无响应/超时) | ConfigValue 恢复挂起或超时,恢复任务超时异常,配置未恢复 | 严重 | import_json 既有超时机制;恢复任务设置超时并标记 Exception 保留 NeedRecoverSetup 重试 | ERROR IMU no response / policy config send timeout | 断连 IMU 通道后触发恢复 | 需要开发分析:IMU 对端不可达场景依赖跨组件环境 | | | ||
| 547 | +| TC-SFMEA-013 | 配置恢复 ImportOldSetup | TS-001 操作时序错乱(BIOS 状态不允许导入 secureboot) | 安全启动证书导入被拒,恢复部分失败,配置不完整 | 严重 | 恢复前置校验 BIOS_STARTUP_STATE_OFF/POST_STAGE_FINISH,不满足则挂起等待上报完成后再触发 | ERROR BIOS state not allow import;log:notice 记录当前状态 | 在 BIOS POST 中触发恢复 | 可以落入DT(test_import_old_setup_all_ok 预置状态已覆盖) | | | ||
| 548 | +| TC-SFMEA-014 | 配置恢复 ImportOldSetup | ST-003 文件内容损坏/格式错误(备份 JSON 格式错误/结构不符) | 备份解析失败导入失败,配置无法恢复,保留标记反复重试 | 严重 | 导入前 get_file_json 解析校验,格式错误明确报错并保留标记;提供人工介入恢复路径 | ERROR recover currentvalue/ConfigValue fail / parse error | 写入畸形 JSON 备份文件 | 可以落入DT(test_import_old_setup_partial_fail 已覆盖) | | | ||
| 549 | +| TC-SFMEA-015 | 配置恢复 ImportOldSetup | DT-001 数据校验不一致(部分导入成功不回滚,多处数据不一致) | setting.json/new_secureboot.json/ConfigValue.json 部分更新,后续上报比对产生新差异 | 一般 | 设计约定为追加语义不回滚,仅保留标记重试;重试前按备份整体覆盖,最终收敛一致 | WARN partial import, keep NeedRecoverSetup | 置某份备份缺失后触发恢复 | 可以落入DT(test_import_old_setup_partial_fail 已覆盖) | | | ||
| 550 | +| TC-SFMEA-016 | 多系统并发备份/恢复 | CC-001 竞态条件(多 system 并发上报备份/比对/置位,同对象多文件并发写) | 备份与比对交错,置位状态竞态,备份文件错乱 | 一般 | 各 system_id 路径隔离 + 既有 skynet_queue 串行化写文件;set_need_recover_setup 经对象串行执行 | log:notice 记录各 system 置位/备份事件 | 双系统同时上报不同文件 | 可以落入DT(test_multihost_isolation/recover_setup_parallel 已覆盖) | | | ||
| 551 | +| TC-SFMEA-017 | 配置恢复任务执行 | CC-004 异步任务异常 / TS-002 超时未完成(恢复任务异常/挂起,recover_setup_task 未复位) | 任务异常退出后 recover_setup_task 未清,本对象后续恢复被防重入拒绝,无法重试 | 严重 | 任务 finally 复位 recover_setup_task=nil;任务设置超时监控,异常时更新任务为 Exception | ERROR recover setup task abnormal / task stuck | 恢复逻辑中抛异常强制退出任务 | 可以落入DT(test_recover_setup_task_reentry 已覆盖) | | | ||
| 552 | +| TC-SFMEA-018 | 恢复后备份刷新与标记清除 | SQL-002 数据库写入失败(清除标记持久化失败) | NeedRecoverSetup 未清除,每次上报重复触发恢复,或清除成功但备份未刷新致反复比对 | 严重 | set_need_recover_setup(false) 持久化失败时告警并重试;先清标记再刷新备份,顺序保证 | ERROR clear NeedRecoverSetup persist fail | mock info_db save 失败 | 可以落入DT(test_need_recover_persist 已覆盖) | | | ||
| 553 | + | ||
| 530 | | 编号 | 场景 | 问题描述 | 可靠性影响 | 问题级别 | 建议解决方案/需求 | 讨论结果 | 跟踪人 | 备注 | | 554 | | 编号 | 场景 | 问题描述 | 可靠性影响 | 问题级别 | 建议解决方案/需求 | 讨论结果 | 跟踪人 | 备注 | |
| 531 | | --- | --- | --- | --- | --- | --- | --- | --- | --- | | 555 | | --- | --- | --- | --- | --- | --- | --- | --- | --- | |
| 532 | | 1 | 备份时源文件/目录异常 | 备份副本写入失败 | 无法恢复配置 | 中 | 备份失败打印 error 日志,不阻断主流程;下次上报重试 | | liucong | | | 556 | | 1 | 备份时源文件/目录异常 | 备份副本写入失败 | 无法恢复配置 | 中 | 备份失败打印 error 日志,不阻断主流程;下次上报重试 | | liucong | | |
| @@ -39,6 +39,13 @@ local table_cache = require('mc.table_cache') | |||
| 39 | local tbl_cache = table_cache.new() | 39 | local tbl_cache = table_cache.new() |
| 40 | local file_service = require('service.file_service') | 40 | local file_service = require('service.file_service') |
| 41 | 41 | ||
| 42 | +local pwd_backup_map = { | ||
| 43 | + { obj_def.PROPERTY_BIOS_SETUP_PWD_OLD, obj_def.PROPERTY_BIOS_SETUP_PWD_OLD_BACKUP }, | ||
| 44 | + { obj_def.PROPERTY_BIOS_SETUP_PWD_NEW, obj_def.PROPERTY_BIOS_SETUP_PWD_NEW_BACKUP }, | ||
| 45 | + { obj_def.PROPERTY_BIOS_USER_SETUP_PWD_OLD, obj_def.PROPERTY_BIOS_USER_SETUP_PWD_OLD_BACKUP }, | ||
| 46 | + { obj_def.PROPERTY_BIOS_USER_SETUP_PWD_NEW, obj_def.PROPERTY_BIOS_USER_SETUP_PWD_NEW_BACKUP }, | ||
| 47 | +} | ||
| 48 | + | ||
| 42 | local function get_valid_version(version) | 49 | local function get_valid_version(version) |
| 43 | local valid_version = '' | 50 | local valid_version = '' |
| 44 | for name in string.gmatch(version, '[%w.]') do | 51 | for name in string.gmatch(version, '[%w.]') do |
| @@ -122,7 +129,7 @@ function bios_object:get_replace_flag() | |||
| 122 | log:error('[bios] system %s get cpu board replace flag failed', self.system_id) | 129 | log:error('[bios] system %s get cpu board replace flag failed', self.system_id) |
| 123 | return | 130 | return |
| 124 | end | 131 | end |
| 125 | - self.replace_flag = (obj['ReplaceFlag'] == 0) | 132 | + self.replace_flag = (obj['ReplaceFlag'] == 1) |
| 126 | end | 133 | end |
| 127 | 134 | ||
| 128 | function bios_object:async_fetch_info() | 135 | function bios_object:async_fetch_info() |
| @@ -439,6 +446,10 @@ function bios_object:select_info_db() | |||
| 439 | NewSetupPassword = '', | 446 | NewSetupPassword = '', |
| 440 | UserOldSetupPassword = '', | 447 | UserOldSetupPassword = '', |
| 441 | UserNewSetupPassword = '', | 448 | UserNewSetupPassword = '', |
| 449 | + OldSetupPasswordBackup = '', | ||
| 450 | + NewSetupPasswordBackup = '', | ||
| 451 | + UserOldSetupPasswordBackup = '', | ||
| 452 | + UserNewSetupPasswordBackup = '', | ||
| 442 | SystemStartupState = 0, | 453 | SystemStartupState = 0, |
| 443 | ResetBiosToDefaultsPending = false, | 454 | ResetBiosToDefaultsPending = false, |
| 444 | BiosBootStage = 0, | 455 | BiosBootStage = 0, |
| @@ -463,6 +474,10 @@ function bios_object:select_info_db() | |||
| 463 | NewSetupPassword = '', | 474 | NewSetupPassword = '', |
| 464 | UserOldSetupPassword = '', | 475 | UserOldSetupPassword = '', |
| 465 | UserNewSetupPassword = '', | 476 | UserNewSetupPassword = '', |
| 477 | + OldSetupPasswordBackup = '', | ||
| 478 | + NewSetupPasswordBackup = '', | ||
| 479 | + UserOldSetupPasswordBackup = '', | ||
| 480 | + UserNewSetupPasswordBackup = '', | ||
| 466 | SystemStartupState = 0, | 481 | SystemStartupState = 0, |
| 467 | ResetBiosToDefaultsPending = false, | 482 | ResetBiosToDefaultsPending = false, |
| 468 | BiosBootStage = 0, | 483 | BiosBootStage = 0, |
| @@ -1254,18 +1269,17 @@ function bios_object:init_backup() | |||
| 1254 | self:backup_config_file(f.name, f.src) | 1269 | self:backup_config_file(f.name, f.src) |
| 1255 | end | 1270 | end |
| 1256 | end | 1271 | end |
| 1257 | - local pwd_map = { | 1272 | + local need_pwd_recover = false |
| 1258 | - { obj_def.PROPERTY_BIOS_SETUP_PWD_OLD, obj_def.PROPERTY_BIOS_SETUP_PWD_OLD_BACKUP }, | 1273 | + for _, pair in ipairs(pwd_backup_map) do |
| 1259 | - { obj_def.PROPERTY_BIOS_SETUP_PWD_NEW, obj_def.PROPERTY_BIOS_SETUP_PWD_NEW_BACKUP }, | ||
| 1260 | - { obj_def.PROPERTY_BIOS_USER_SETUP_PWD_OLD, obj_def.PROPERTY_BIOS_USER_SETUP_PWD_OLD_BACKUP }, | ||
| 1261 | - { obj_def.PROPERTY_BIOS_USER_SETUP_PWD_NEW, obj_def.PROPERTY_BIOS_USER_SETUP_PWD_NEW_BACKUP }, | ||
| 1262 | - } | ||
| 1263 | - for _, pair in ipairs(pwd_map) do | ||
| 1264 | local src, bak = pair[1], pair[2] | 1274 | local src, bak = pair[1], pair[2] |
| 1265 | - if #self:get_prop(src) > 0 then | 1275 | + local bak_val = self.info_db[bak] |
| 1276 | + if #bak_val == 0 and #self:get_prop(src) > 0 then | ||
| 1266 | self:set_db_prop(bak, self:get_prop(src)) | 1277 | self:set_db_prop(bak, self:get_prop(src)) |
| 1278 | + elseif bak_val ~= self:get_prop(src) then | ||
| 1279 | + need_pwd_recover = true | ||
| 1267 | end | 1280 | end |
| 1268 | end | 1281 | end |
| 1282 | + self:set_need_recover_setup(need_pwd_recover) | ||
| 1269 | end | 1283 | end |
| 1270 | 1284 | ||
| 1271 | -- 备份三份文件中指定的一份(复制为同目录_bak副本) | 1285 | -- 备份三份文件中指定的一份(复制为同目录_bak副本) |
| @@ -1382,7 +1396,20 @@ function bios_object:recover_bios_setup(ctx) | |||
| 1382 | log:error('[bios]system %s recover ConfigValue fail, err is %s', self.system_id, err3) | 1396 | log:error('[bios]system %s recover ConfigValue fail, err is %s', self.system_id, err3) |
| 1383 | end | 1397 | end |
| 1384 | 1398 | ||
| 1385 | - if ok1 and ok2 and ok3 then | 1399 | + local ok4, err4 = pcall(function() |
| 1400 | + for _, pair in ipairs(pwd_backup_map) do | ||
| 1401 | + local src, bak = pair[1], pair[2] | ||
| 1402 | + local bak_val = self.info_db[bak] | ||
| 1403 | + if #bak_val > 0 then | ||
| 1404 | + self:set_prop(src, bak_val) | ||
| 1405 | + end | ||
| 1406 | + end | ||
| 1407 | + end) | ||
| 1408 | + if not ok4 then | ||
| 1409 | + log:error('[bios]system %s recover setup password fail, err is %s', self.system_id, err4) | ||
| 1410 | + end | ||
| 1411 | + | ||
| 1412 | + if ok1 and ok2 and ok3 and ok4 then | ||
| 1386 | log:notice('[bios]system %s ImportOldSetup success, clear NeedRecoverSetup', self.system_id) | 1413 | log:notice('[bios]system %s ImportOldSetup success, clear NeedRecoverSetup', self.system_id) |
| 1387 | self:set_need_recover_setup(false) | 1414 | self:set_need_recover_setup(false) |
| 1388 | else | 1415 | else |
| @@ -348,13 +348,13 @@ function bios_service:get_all_objs() | |||
| 348 | return self.bios_object_collection | 348 | return self.bios_object_collection |
| 349 | end | 349 | end |
| 350 | 350 | ||
| 351 | -function bios_service:recover_bios_setup(ctx, system_id, path) | 351 | +function bios_service:recover_bios_setup(ctx, system_id) |
| 352 | local bios_obj = self:get_obj(system_id) | 352 | local bios_obj = self:get_obj(system_id) |
| 353 | if not bios_obj then | 353 | if not bios_obj then |
| 354 | log:error('[bios]recover_bios_setup: system id(%s) invalid', system_id) | 354 | log:error('[bios]recover_bios_setup: system id(%s) invalid', system_id) |
| 355 | error(base_messages.InternalError()) | 355 | error(base_messages.InternalError()) |
| 356 | end | 356 | end |
| 357 | - return bios_obj:recover_bios_setup(ctx, path) | 357 | + return bios_obj:recover_bios_setup(ctx) |
| 358 | end | 358 | end |
| 359 | 359 | ||
| 360 | function bios_service:notify_dft_mode() | 360 | function bios_service:notify_dft_mode() |
| @@ -60,19 +60,32 @@ local function make_bios_obj() | |||
| 60 | return bios_obj | 60 | return bios_obj |
| 61 | end | 61 | end |
| 62 | 62 | ||
| 63 | +local function make_info_db() | ||
| 64 | + return { | ||
| 65 | + OldSetupPassword = '', | ||
| 66 | + NewSetupPassword = '', | ||
| 67 | + UserOldSetupPassword = '', | ||
| 68 | + UserNewSetupPassword = '', | ||
| 69 | + OldSetupPasswordBackup = '', | ||
| 70 | + NewSetupPasswordBackup = '', | ||
| 71 | + UserOldSetupPasswordBackup = '', | ||
| 72 | + UserNewSetupPasswordBackup = '', | ||
| 73 | + } | ||
| 74 | +end | ||
| 75 | + | ||
| 63 | TestBackupConfig = {} | 76 | TestBackupConfig = {} |
| 64 | 77 | ||
| 65 | function TestBackupConfig:test_get_replace_flag_success() | 78 | function TestBackupConfig:test_get_replace_flag_success() |
| 66 | local bios_obj = make_bios_obj() | 79 | local bios_obj = make_bios_obj() |
| 67 | local get_component_mock = client.GetComponentComponentObject | 80 | local get_component_mock = client.GetComponentComponentObject |
| 68 | client.GetComponentComponentObject = function(_, req) | 81 | client.GetComponentComponentObject = function(_, req) |
| 69 | - return { ReplaceFlag = 0 } | 82 | + return { ReplaceFlag = 1 } |
| 70 | end | 83 | end |
| 71 | bios_obj:get_replace_flag() | 84 | bios_obj:get_replace_flag() |
| 72 | lu.assertIsTrue(bios_obj.replace_flag) | 85 | lu.assertIsTrue(bios_obj.replace_flag) |
| 73 | 86 | ||
| 74 | client.GetComponentComponentObject = function(_, req) | 87 | client.GetComponentComponentObject = function(_, req) |
| 75 | - return { ReplaceFlag = 1 } | 88 | + return { ReplaceFlag = 0 } |
| 76 | end | 89 | end |
| 77 | bios_obj:get_replace_flag() | 90 | bios_obj:get_replace_flag() |
| 78 | lu.assertIsFalse(bios_obj.replace_flag) | 91 | lu.assertIsFalse(bios_obj.replace_flag) |
| @@ -111,7 +124,9 @@ end | |||
| 111 | 124 | ||
| 112 | function TestBackupConfig:test_init_backup_without_bak() | 125 | function TestBackupConfig:test_init_backup_without_bak() |
| 113 | local bios_obj = make_bios_obj() | 126 | local bios_obj = make_bios_obj() |
| 127 | + bios_obj.info_db = make_info_db() | ||
| 114 | local backup_count = 0 | 128 | local backup_count = 0 |
| 129 | + local need_recover = nil | ||
| 115 | bios_obj.backup_config_file = function(_, file_name, src_path) | 130 | bios_obj.backup_config_file = function(_, file_name, src_path) |
| 116 | backup_count = backup_count + 1 | 131 | backup_count = backup_count + 1 |
| 117 | return true | 132 | return true |
| @@ -131,6 +146,9 @@ function TestBackupConfig:test_init_backup_without_bak() | |||
| 131 | bios_obj.set_db_prop = function(_, key, value) | 146 | bios_obj.set_db_prop = function(_, key, value) |
| 132 | db_prop[key] = value | 147 | db_prop[key] = value |
| 133 | end | 148 | end |
| 149 | + bios_obj.set_need_recover_setup = function(_, value) | ||
| 150 | + need_recover = value | ||
| 151 | + end | ||
| 134 | prop_map[obj_def.PROPERTY_BIOS_SETUP_PWD_OLD] = 'old_pwd_enc' | 152 | prop_map[obj_def.PROPERTY_BIOS_SETUP_PWD_OLD] = 'old_pwd_enc' |
| 135 | prop_map[obj_def.PROPERTY_BIOS_USER_SETUP_PWD_NEW] = 'user_new_pwd_enc' | 153 | prop_map[obj_def.PROPERTY_BIOS_USER_SETUP_PWD_NEW] = 'user_new_pwd_enc' |
| 136 | 154 | ||
| @@ -139,12 +157,15 @@ function TestBackupConfig:test_init_backup_without_bak() | |||
| 139 | lu.assertEquals(db_prop[obj_def.PROPERTY_BIOS_SETUP_PWD_OLD_BACKUP], 'old_pwd_enc') | 157 | lu.assertEquals(db_prop[obj_def.PROPERTY_BIOS_SETUP_PWD_OLD_BACKUP], 'old_pwd_enc') |
| 140 | lu.assertEquals(db_prop[obj_def.PROPERTY_BIOS_USER_SETUP_PWD_NEW_BACKUP], 'user_new_pwd_enc') | 158 | lu.assertEquals(db_prop[obj_def.PROPERTY_BIOS_USER_SETUP_PWD_NEW_BACKUP], 'user_new_pwd_enc') |
| 141 | lu.assertIsNil(db_prop[obj_def.PROPERTY_BIOS_SETUP_PWD_NEW_BACKUP]) | 159 | lu.assertIsNil(db_prop[obj_def.PROPERTY_BIOS_SETUP_PWD_NEW_BACKUP]) |
| 160 | + lu.assertIsFalse(need_recover) | ||
| 142 | bs_util.is_file_nonempty = is_nonempty_mock | 161 | bs_util.is_file_nonempty = is_nonempty_mock |
| 143 | end | 162 | end |
| 144 | 163 | ||
| 145 | function TestBackupConfig:test_init_backup_with_existing_bak() | 164 | function TestBackupConfig:test_init_backup_with_existing_bak() |
| 146 | local bios_obj = make_bios_obj() | 165 | local bios_obj = make_bios_obj() |
| 166 | + bios_obj.info_db = make_info_db() | ||
| 147 | local backup_count = 0 | 167 | local backup_count = 0 |
| 168 | + local need_recover = nil | ||
| 148 | bios_obj.backup_config_file = function(_, file_name, src_path) | 169 | bios_obj.backup_config_file = function(_, file_name, src_path) |
| 149 | backup_count = backup_count + 1 | 170 | backup_count = backup_count + 1 |
| 150 | return true | 171 | return true |
| @@ -157,8 +178,64 @@ function TestBackupConfig:test_init_backup_with_existing_bak() | |||
| 157 | return '' | 178 | return '' |
| 158 | end | 179 | end |
| 159 | bios_obj.set_db_prop = function() end | 180 | bios_obj.set_db_prop = function() end |
| 181 | + bios_obj.set_need_recover_setup = function(_, value) | ||
| 182 | + need_recover = value | ||
| 183 | + end | ||
| 160 | bios_obj:init_backup() | 184 | bios_obj:init_backup() |
| 161 | lu.assertEquals(backup_count, 0) | 185 | lu.assertEquals(backup_count, 0) |
| 186 | + lu.assertIsFalse(need_recover) | ||
| 187 | + bs_util.is_file_nonempty = is_nonempty_mock | ||
| 188 | +end | ||
| 189 | + | ||
| 190 | +function TestBackupConfig:test_init_backup_pwd_mismatch_sets_recover() | ||
| 191 | + local bios_obj = make_bios_obj() | ||
| 192 | + local info_db = make_info_db() | ||
| 193 | + info_db[obj_def.PROPERTY_BIOS_SETUP_PWD_OLD_BACKUP] = 'backup_old' | ||
| 194 | + bios_obj.info_db = info_db | ||
| 195 | + local need_recover = nil | ||
| 196 | + bios_obj.backup_config_file = function() end | ||
| 197 | + local is_nonempty_mock = bs_util.is_file_nonempty | ||
| 198 | + bs_util.is_file_nonempty = function(path) | ||
| 199 | + return true | ||
| 200 | + end | ||
| 201 | + bios_obj.get_prop = function(_, key) | ||
| 202 | + if key == obj_def.PROPERTY_BIOS_SETUP_PWD_OLD then | ||
| 203 | + return 'current_old' | ||
| 204 | + end | ||
| 205 | + return '' | ||
| 206 | + end | ||
| 207 | + bios_obj.set_db_prop = function() end | ||
| 208 | + bios_obj.set_need_recover_setup = function(_, value) | ||
| 209 | + need_recover = value | ||
| 210 | + end | ||
| 211 | + bios_obj:init_backup() | ||
| 212 | + lu.assertIsTrue(need_recover) | ||
| 213 | + bs_util.is_file_nonempty = is_nonempty_mock | ||
| 214 | +end | ||
| 215 | + | ||
| 216 | +function TestBackupConfig:test_init_backup_pwd_match_no_recover() | ||
| 217 | + local bios_obj = make_bios_obj() | ||
| 218 | + local info_db = make_info_db() | ||
| 219 | + info_db[obj_def.PROPERTY_BIOS_SETUP_PWD_OLD_BACKUP] = 'same_pwd' | ||
| 220 | + bios_obj.info_db = info_db | ||
| 221 | + local need_recover = nil | ||
| 222 | + bios_obj.backup_config_file = function() end | ||
| 223 | + local is_nonempty_mock = bs_util.is_file_nonempty | ||
| 224 | + bs_util.is_file_nonempty = function(path) | ||
| 225 | + return true | ||
| 226 | + end | ||
| 227 | + bios_obj.get_prop = function(_, key) | ||
| 228 | + if key == obj_def.PROPERTY_BIOS_SETUP_PWD_OLD then | ||
| 229 | + return 'same_pwd' | ||
| 230 | + end | ||
| 231 | + return '' | ||
| 232 | + end | ||
| 233 | + bios_obj.set_db_prop = function() end | ||
| 234 | + bios_obj.set_need_recover_setup = function(_, value) | ||
| 235 | + need_recover = value | ||
| 236 | + end | ||
| 237 | + bios_obj:init_backup() | ||
| 238 | + lu.assertIsFalse(need_recover) | ||
| 162 | bs_util.is_file_nonempty = is_nonempty_mock | 239 | bs_util.is_file_nonempty = is_nonempty_mock |
| 163 | end | 240 | end |
| 164 | 241 | ||
| @@ -274,14 +351,11 @@ local function build_full_backup_json() | |||
| 274 | } | 351 | } |
| 275 | end | 352 | end |
| 276 | 353 | ||
| 277 | -function TestBackupConfig:test_recover_bios_setup_import_success() | 354 | +local function mock_recover_services() |
| 278 | - local bios_obj = make_bios_obj() | ||
| 279 | - bios_obj.obj.ComponentName = 'Bios' | ||
| 280 | local import_calls = {} | 355 | local import_calls = {} |
| 281 | local sb_calls = {} | 356 | local sb_calls = {} |
| 282 | local boot_cert_calls = {} | 357 | local boot_cert_calls = {} |
| 283 | local boot_crl_calls = {} | 358 | local boot_crl_calls = {} |
| 284 | - local need_recover = nil | ||
| 285 | 359 | ||
| 286 | local file_service_new_mock = file_service.new | 360 | local file_service_new_mock = file_service.new |
| 287 | file_service.new = function() | 361 | file_service.new = function() |
| @@ -309,6 +383,26 @@ function TestBackupConfig:test_recover_bios_setup_import_success() | |||
| 309 | end, | 383 | end, |
| 310 | } | 384 | } |
| 311 | end | 385 | end |
| 386 | + | ||
| 387 | + local function restore() | ||
| 388 | + file_service.new = file_service_new_mock | ||
| 389 | + bios_factory.get_service = get_service_mock | ||
| 390 | + end | ||
| 391 | + | ||
| 392 | + return { | ||
| 393 | + import_calls = import_calls, | ||
| 394 | + sb_calls = sb_calls, | ||
| 395 | + boot_cert_calls = boot_cert_calls, | ||
| 396 | + boot_crl_calls = boot_crl_calls, | ||
| 397 | + restore = restore, | ||
| 398 | + } | ||
| 399 | +end | ||
| 400 | + | ||
| 401 | +function TestBackupConfig:test_recover_bios_setup_import_success() | ||
| 402 | + local bios_obj = make_bios_obj() | ||
| 403 | + bios_obj.info_db = make_info_db() | ||
| 404 | + bios_obj.obj.ComponentName = 'Bios' | ||
| 405 | + local mocks = mock_recover_services() | ||
| 312 | local get_file_json_mock = bs_util.get_file_json | 406 | local get_file_json_mock = bs_util.get_file_json |
| 313 | bs_util.get_file_json = function(path) | 407 | bs_util.get_file_json = function(path) |
| 314 | if path and string.find(path, 'currentvalue_bak') then | 408 | if path and string.find(path, 'currentvalue_bak') then |
| @@ -322,70 +416,54 @@ function TestBackupConfig:test_recover_bios_setup_import_success() | |||
| 322 | end | 416 | end |
| 323 | return nil | 417 | return nil |
| 324 | end | 418 | end |
| 419 | + local need_recover = nil | ||
| 325 | bios_obj.set_need_recover_setup = function(_, value) | 420 | bios_obj.set_need_recover_setup = function(_, value) |
| 326 | need_recover = value | 421 | need_recover = value |
| 327 | end | 422 | end |
| 328 | 423 | ||
| 329 | bios_obj:recover_bios_setup({}) | 424 | bios_obj:recover_bios_setup({}) |
| 330 | - lu.assertEquals(#import_calls, 2) | 425 | + lu.assertEquals(#mocks.import_calls, 2) |
| 331 | - lu.assertEquals(import_calls[1], 'WebConfig') | 426 | + lu.assertEquals(mocks.import_calls[1], 'WebConfig') |
| 332 | - lu.assertEquals(import_calls[2], 'PolicyConfig') | 427 | + lu.assertEquals(mocks.import_calls[2], 'PolicyConfig') |
| 333 | - lu.assertEquals(#sb_calls, 2) | 428 | + lu.assertEquals(#mocks.sb_calls, 2) |
| 334 | - lu.assertEquals(sb_calls[1].db_type, prop_def.INTERACT_KEY_SECUREBOOT_DB) | 429 | + lu.assertEquals(mocks.sb_calls[1].db_type, prop_def.INTERACT_KEY_SECUREBOOT_DB) |
| 335 | - lu.assertEquals(sb_calls[1].cert_str, 'CERT_DB_1') | 430 | + lu.assertEquals(mocks.sb_calls[1].cert_str, 'CERT_DB_1') |
| 336 | - lu.assertEquals(sb_calls[2].db_type, prop_def.INTERACT_KEY_SECUREBOOT_DBX) | 431 | + lu.assertEquals(mocks.sb_calls[2].db_type, prop_def.INTERACT_KEY_SECUREBOOT_DBX) |
| 337 | - lu.assertEquals(#boot_cert_calls, 1) | 432 | + lu.assertEquals(#mocks.boot_cert_calls, 1) |
| 338 | - lu.assertEquals(boot_cert_calls[1], 'BOOT_CERT_1') | 433 | + lu.assertEquals(mocks.boot_cert_calls[1], 'BOOT_CERT_1') |
| 339 | - lu.assertEquals(#boot_crl_calls, 1) | 434 | + lu.assertEquals(#mocks.boot_crl_calls, 1) |
| 340 | - lu.assertEquals(boot_crl_calls[1], 'BOOT_CRL_1') | 435 | + lu.assertEquals(mocks.boot_crl_calls[1], 'BOOT_CRL_1') |
| 341 | lu.assertIsFalse(need_recover) | 436 | lu.assertIsFalse(need_recover) |
| 342 | 437 | ||
| 343 | - file_service.new = file_service_new_mock | 438 | + mocks.restore() |
| 344 | - bios_factory.get_service = get_service_mock | ||
| 345 | bs_util.get_file_json = get_file_json_mock | 439 | bs_util.get_file_json = get_file_json_mock |
| 346 | end | 440 | end |
| 347 | 441 | ||
| 348 | function TestBackupConfig:test_recover_bios_setup_no_backup() | 442 | function TestBackupConfig:test_recover_bios_setup_no_backup() |
| 349 | local bios_obj = make_bios_obj() | 443 | local bios_obj = make_bios_obj() |
| 444 | + bios_obj.info_db = make_info_db() | ||
| 350 | bios_obj.obj.ComponentName = 'Bios' | 445 | bios_obj.obj.ComponentName = 'Bios' |
| 351 | - local import_calls = {} | 446 | + local mocks = mock_recover_services() |
| 352 | - local need_recover = nil | ||
| 353 | - | ||
| 354 | - local file_service_new_mock = file_service.new | ||
| 355 | - file_service.new = function() | ||
| 356 | - return { | ||
| 357 | - import_json = function(_, ctx, file_type, content, sys_id) | ||
| 358 | - import_calls[#import_calls + 1] = file_type | ||
| 359 | - end, | ||
| 360 | - } | ||
| 361 | - end | ||
| 362 | - local get_service_mock = bios_factory.get_service | ||
| 363 | - bios_factory.get_service = function(name) | ||
| 364 | - return { | ||
| 365 | - import_secure_boot_certificate = function() end, | ||
| 366 | - import_boot_certificate = function() end, | ||
| 367 | - import_boot_crl = function() end, | ||
| 368 | - } | ||
| 369 | - end | ||
| 370 | local get_file_json_mock = bs_util.get_file_json | 447 | local get_file_json_mock = bs_util.get_file_json |
| 371 | bs_util.get_file_json = function(path) | 448 | bs_util.get_file_json = function(path) |
| 372 | return nil | 449 | return nil |
| 373 | end | 450 | end |
| 451 | + local need_recover = nil | ||
| 374 | bios_obj.set_need_recover_setup = function(_, value) | 452 | bios_obj.set_need_recover_setup = function(_, value) |
| 375 | need_recover = value | 453 | need_recover = value |
| 376 | end | 454 | end |
| 377 | 455 | ||
| 378 | bios_obj:recover_bios_setup({}) | 456 | bios_obj:recover_bios_setup({}) |
| 379 | - lu.assertEquals(#import_calls, 0) | 457 | + lu.assertEquals(#mocks.import_calls, 0) |
| 380 | lu.assertIsFalse(need_recover) | 458 | lu.assertIsFalse(need_recover) |
| 381 | 459 | ||
| 382 | - file_service.new = file_service_new_mock | 460 | + mocks.restore() |
| 383 | - bios_factory.get_service = get_service_mock | ||
| 384 | bs_util.get_file_json = get_file_json_mock | 461 | bs_util.get_file_json = get_file_json_mock |
| 385 | end | 462 | end |
| 386 | 463 | ||
| 387 | function TestBackupConfig:test_recover_bios_setup_partial_fail() | 464 | function TestBackupConfig:test_recover_bios_setup_partial_fail() |
| 388 | local bios_obj = make_bios_obj() | 465 | local bios_obj = make_bios_obj() |
| 466 | + bios_obj.info_db = make_info_db() | ||
| 389 | bios_obj.obj.ComponentName = 'Bios' | 467 | bios_obj.obj.ComponentName = 'Bios' |
| 390 | local need_recover = nil | 468 | local need_recover = nil |
| 391 | 469 | ||
| @@ -423,26 +501,91 @@ function TestBackupConfig:test_recover_bios_setup_partial_fail() | |||
| 423 | bs_util.get_file_json = get_file_json_mock | 501 | bs_util.get_file_json = get_file_json_mock |
| 424 | end | 502 | end |
| 425 | 503 | ||
| 504 | +function TestBackupConfig:test_recover_bios_setup_password_recover_success() | ||
| 505 | + local bios_obj = make_bios_obj() | ||
| 506 | + local info_db = make_info_db() | ||
| 507 | + info_db[obj_def.PROPERTY_BIOS_SETUP_PWD_OLD_BACKUP] = 'old_bak' | ||
| 508 | + info_db[obj_def.PROPERTY_BIOS_SETUP_PWD_NEW_BACKUP] = 'new_bak' | ||
| 509 | + bios_obj.info_db = info_db | ||
| 510 | + bios_obj.obj.ComponentName = 'Bios' | ||
| 511 | + local mocks = mock_recover_services() | ||
| 512 | + local set_prop_calls = {} | ||
| 513 | + bios_obj.set_prop = function(_, key, value) | ||
| 514 | + set_prop_calls[#set_prop_calls + 1] = { key = key, value = value } | ||
| 515 | + return true | ||
| 516 | + end | ||
| 517 | + local get_file_json_mock = bs_util.get_file_json | ||
| 518 | + bs_util.get_file_json = function(path) | ||
| 519 | + return nil | ||
| 520 | + end | ||
| 521 | + local need_recover = nil | ||
| 522 | + bios_obj.set_need_recover_setup = function(_, value) | ||
| 523 | + need_recover = value | ||
| 524 | + end | ||
| 525 | + | ||
| 526 | + bios_obj:recover_bios_setup({}) | ||
| 527 | + lu.assertEquals(#set_prop_calls, 2) | ||
| 528 | + lu.assertEquals(set_prop_calls[1].key, obj_def.PROPERTY_BIOS_SETUP_PWD_OLD) | ||
| 529 | + lu.assertEquals(set_prop_calls[1].value, 'old_bak') | ||
| 530 | + lu.assertEquals(set_prop_calls[2].key, obj_def.PROPERTY_BIOS_SETUP_PWD_NEW) | ||
| 531 | + lu.assertEquals(set_prop_calls[2].value, 'new_bak') | ||
| 532 | + lu.assertIsFalse(need_recover) | ||
| 533 | + | ||
| 534 | + mocks.restore() | ||
| 535 | + bs_util.get_file_json = get_file_json_mock | ||
| 536 | +end | ||
| 537 | + | ||
| 538 | +function TestBackupConfig:test_recover_bios_setup_password_recover_fail() | ||
| 539 | + local bios_obj = make_bios_obj() | ||
| 540 | + local info_db = make_info_db() | ||
| 541 | + info_db[obj_def.PROPERTY_BIOS_SETUP_PWD_OLD_BACKUP] = 'old_bak' | ||
| 542 | + bios_obj.info_db = info_db | ||
| 543 | + bios_obj.obj.ComponentName = 'Bios' | ||
| 544 | + local mocks = mock_recover_services() | ||
| 545 | + bios_obj.set_prop = function() | ||
| 546 | + error('set_prop fail') | ||
| 547 | + end | ||
| 548 | + local get_file_json_mock = bs_util.get_file_json | ||
| 549 | + bs_util.get_file_json = function(path) | ||
| 550 | + return nil | ||
| 551 | + end | ||
| 552 | + local need_recover = nil | ||
| 553 | + bios_obj.set_need_recover_setup = function(_, value) | ||
| 554 | + need_recover = value | ||
| 555 | + end | ||
| 556 | + | ||
| 557 | + local ok, err = pcall(bios_obj.recover_bios_setup, bios_obj, {}) | ||
| 558 | + lu.assertFalse(ok) | ||
| 559 | + lu.assertStrContains(err, 'Type=Bios') | ||
| 560 | + lu.assertIsNil(need_recover) | ||
| 561 | + | ||
| 562 | + mocks.restore() | ||
| 563 | + bs_util.get_file_json = get_file_json_mock | ||
| 564 | +end | ||
| 565 | + | ||
| 426 | function TestBackupConfig:test_bios_service_recover_bios_setup() | 566 | function TestBackupConfig:test_bios_service_recover_bios_setup() |
| 427 | local bios_obj = make_bios_obj() | 567 | local bios_obj = make_bios_obj() |
| 428 | local recover_called = false | 568 | local recover_called = false |
| 429 | - bios_obj.recover_bios_setup = function(_, ctx, path) | 569 | + local recover_ctx = nil |
| 570 | + bios_obj.recover_bios_setup = function(_, ctx) | ||
| 430 | recover_called = true | 571 | recover_called = true |
| 572 | + recover_ctx = ctx | ||
| 431 | return true | 573 | return true |
| 432 | end | 574 | end |
| 433 | local get_obj_mock = bios_service.get_obj | 575 | local get_obj_mock = bios_service.get_obj |
| 434 | bios_service.get_obj = function(_, sys_id) | 576 | bios_service.get_obj = function(_, sys_id) |
| 435 | return bios_obj | 577 | return bios_obj |
| 436 | end | 578 | end |
| 437 | - local ret = bios_service:recover_bios_setup({}, 1, '/test/path') | 579 | + local ret = bios_service:recover_bios_setup({}, 1) |
| 438 | lu.assertIsTrue(ret) | 580 | lu.assertIsTrue(ret) |
| 439 | lu.assertIsTrue(recover_called) | 581 | lu.assertIsTrue(recover_called) |
| 582 | + lu.assertNotNil(recover_ctx) | ||
| 440 | 583 | ||
| 441 | bios_service.get_obj = function() | 584 | bios_service.get_obj = function() |
| 442 | return nil | 585 | return nil |
| 443 | end | 586 | end |
| 444 | local ok = pcall(function() | 587 | local ok = pcall(function() |
| 445 | - return bios_service:recover_bios_setup({}, 2, '/test/path') | 588 | + return bios_service:recover_bios_setup({}, 2) |
| 446 | end) | 589 | end) |
| 447 | lu.assertIsFalse(ok) | 590 | lu.assertIsFalse(ok) |
| 448 | bios_service.get_obj = get_obj_mock | 591 | bios_service.get_obj = get_obj_mock |
| @@ -544,6 +687,7 @@ end | |||
| 544 | 687 | ||
| 545 | function TestBackupConfig:test_recover_bios_setup_secureboot_fail() | 688 | function TestBackupConfig:test_recover_bios_setup_secureboot_fail() |
| 546 | local bios_obj = make_bios_obj() | 689 | local bios_obj = make_bios_obj() |
| 690 | + bios_obj.info_db = make_info_db() | ||
| 547 | bios_obj.obj.ComponentName = 'Bios' | 691 | bios_obj.obj.ComponentName = 'Bios' |
| 548 | 692 | ||
| 549 | local file_service_new_mock = file_service.new | 693 | local file_service_new_mock = file_service.new |
| @@ -11,6 +11,7 @@ local bios_service = require('service.bios_service') | |||
| 11 | local lu = require('luaunit') | 11 | local lu = require('luaunit') |
| 12 | local open_db = require('bios.db') | 12 | local open_db = require('bios.db') |
| 13 | local vos = require('utils.vos') | 13 | local vos = require('utils.vos') |
| 14 | +local file_sec = require('utils.file') | ||
| 14 | 15 | ||
| 15 | local test_common = require('test_common.utils') | 16 | local test_common = require('test_common.utils') |
| 16 | local bus = test_common.dbus_launch('../.dbus', nil, true) | 17 | local bus = test_common.dbus_launch('../.dbus', nil, true) |
| @@ -29,19 +30,29 @@ end | |||
| 29 | 30 | ||
| 30 | function TestWriteToBmc:test_write_firmware_data_to_bmc() | 31 | function TestWriteToBmc:test_write_firmware_data_to_bmc() |
| 31 | local bios_ser = bios_service.new(bus, construct_db()) | 32 | local bios_ser = bios_service.new(bus, construct_db()) |
| 32 | - bios_ser.get_data_opt = function() end | ||
| 33 | bios_ser.dft_mode = true | 33 | bios_ser.dft_mode = true |
| 34 | bios_ser.upg_fw_file = false | 34 | bios_ser.upg_fw_file = false |
| 35 | + local offset = 0 | ||
| 35 | bios_ser.get_data_opt = function() | 36 | bios_ser.get_data_opt = function() |
| 36 | local obj = {} | 37 | local obj = {} |
| 37 | obj.get_offset = function() | 38 | obj.get_offset = function() |
| 38 | - return 0 | 39 | + return offset |
| 39 | end | 40 | end |
| 41 | + obj.set_offset = function() end | ||
| 40 | return obj | 42 | return obj |
| 41 | end | 43 | end |
| 44 | + local open_s_mock = file_sec.open_s | ||
| 45 | + file_sec.open_s = function(path, mode) | ||
| 46 | + return { | ||
| 47 | + write = function() | ||
| 48 | + return true | ||
| 49 | + end, | ||
| 50 | + close = function() end, | ||
| 51 | + } | ||
| 52 | + end | ||
| 42 | 53 | ||
| 43 | local ok = pcall(function() | 54 | local ok = pcall(function() |
| 44 | - bios_ser:write_firmware_data_to_bmc({}, {}, 1) | 55 | + bios_ser:write_firmware_data_to_bmc({}, { FileData = 'data' }, 1) |
| 45 | end) | 56 | end) |
| 46 | lu.assertEquals(ok, true) | 57 | lu.assertEquals(ok, true) |
| 47 | 58 | ||
| @@ -58,10 +69,11 @@ function TestWriteToBmc:test_write_firmware_data_to_bmc() | |||
| 58 | }, | 69 | }, |
| 59 | } | 70 | } |
| 60 | ok = pcall(function() | 71 | ok = pcall(function() |
| 61 | - bios_ser:write_firmware_data_to_bmc({}, {}, {}, ctx) | 72 | + bios_ser:write_firmware_data_to_bmc({}, { FileData = 'data' }, 1, ctx) |
| 62 | end) | 73 | end) |
| 63 | lu.assertEquals(ok, true) | 74 | lu.assertEquals(ok, true) |
| 64 | vos.get_file_accessible = get_file_accessible | 75 | vos.get_file_accessible = get_file_accessible |
| 76 | + file_sec.open_s = open_s_mock | ||
| 65 | end | 77 | end |
| 66 | 78 | ||
| 67 | function TestWriteToBmc:test_write_prepare_firmware_data_to_bmc() | 79 | function TestWriteToBmc:test_write_prepare_firmware_data_to_bmc() |