-- Copyright (c) 2025 Huawei Technologies Co., Ltd.
-- openUBMC is licensed under Mulan PSL v2.
-- You can use this software according to the terms and conditions of the Mulan PSL v2.
-- You may obtain a copy of Mulan PSL v2 at: http://license.coscl.org.cn/MulanPSL2
-- THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
-- EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
-- MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
-- See the Mulan PSL v2 for more details.

local class = require 'mc.class'
local lu = require 'luaunit'
local block_info = require 'domain.system_info.block_info'
local character_info = require 'domain.system_info.character_info'
local open_db = require 'bios.db'
local ipmi = require 'ipmi'
local cc = ipmi.types.Cc
local boot_service = require 'service.boot_service'
local system_info_object = require 'pojo.system_info_object'
local s_pack = string.pack

TestSystemInfo = {}

local function construct_db()
    local ok, datas = pcall(require, 'bios.datas')
    if not ok then
        -- 如果没有datas配置，证明当前组件不需要datas，仅打开数据库
        datas = nil
    end
    local db = open_db(':memory:', datas)
    return db
end

local function construct_ctx()
    local ctx = {}
    ctx.ChanType = 1
    ctx.get_initiator = function()
        return {}
    end

    return ctx
end

function TestSystemInfo:test_decode_encode()
    character_info.new({})
    local block_instance = block_info.new()
    local data = block_instance:decode_db_info('/1/2/3/4/5/6')
    lu.assertEquals(data[0], 1)
    lu.assertEquals(data[1], 2)
    lu.assertEquals(data[2], 3)
    lu.assertEquals(data[3], 4)
    lu.assertEquals(data[4], 5)
    lu.assertEquals(data[5], 6)

    local res = block_instance:encode_db_info(data)
    lu.assertEquals(res, '/1/2/3/4/5/6')
end

-- 验证一块block不满足16字节
function TestSystemInfo:test_one_block()
    local block_instance = block_info.new({
        db = {
            FirmwareVersion = '/6/0/3/4/5/6',
            save = function ()
                return true
            end
        },
        prop = 'FirmwareVersion',
        system_id = 1,
        volidate = false
    })
    local data = block_instance.data
    lu.assertEquals(data[0], 6)
    lu.assertEquals(data[1], 0)
    lu.assertEquals(data[2], 3)
    lu.assertEquals(data[3], 4)
    lu.assertEquals(data[4], 5)
    lu.assertEquals(data[5], 6)

    lu.assertEquals(block_instance.length, 6)
    lu.assertEquals(block_instance.last_seg_length, 6)
    lu.assertEquals(block_instance.seg_num, 1)
    lu.assertEquals(block_instance.current_seg_num, 0)
end

-- 验证一块block满足16字节
function TestSystemInfo:test_full_one_block()
    local block_instance = block_info.new({
        db = {
            FirmwareVersion = '/16/0/3/4/5/6',
            save = function ()
                return true
            end
        },
        prop = 'FirmwareVersion',
        system_id = 1,
        volidate = false
    })
    local data = block_instance.data
    lu.assertEquals(data[0], 16)
    lu.assertEquals(data[1], 0)
    lu.assertEquals(data[2], 3)
    lu.assertEquals(data[3], 4)
    lu.assertEquals(data[4], 5)
    lu.assertEquals(data[5], 6)

    lu.assertEquals(block_instance.length, 16)
    lu.assertEquals(block_instance.last_seg_length, 16)
    lu.assertEquals(block_instance.seg_num, 1)
    lu.assertEquals(block_instance.current_seg_num, 0)
end

-- 验证两块block不满足16字节
function TestSystemInfo:test_two_block()
    local block_instance = block_info.new({
        db = {
            FirmwareVersion = '/31/1/3/4/5/6',
            save = function ()
                return true
            end
        },
        prop = 'FirmwareVersion',
        system_id = 1,
        volidate = false
    })
    local data = block_instance.data
    lu.assertEquals(data[0], 31)
    lu.assertEquals(data[1], 1)
    lu.assertEquals(data[2], 3)
    lu.assertEquals(data[3], 4)
    lu.assertEquals(data[4], 5)
    lu.assertEquals(data[5], 6)

    lu.assertEquals(block_instance.length, 31)
    lu.assertEquals(block_instance.last_seg_length, 15)
    lu.assertEquals(block_instance.seg_num, 2)
    lu.assertEquals(block_instance.current_seg_num, 1)
end

-- 验证两块block满足16字节
function TestSystemInfo:test_full_two_block()
    local block_instance = block_info.new({
        db = {
            FirmwareVersion = '/32/0/3/4/5/6',
            save = function ()
                return true
            end
        },
        prop = 'FirmwareVersion',
        system_id = 1,
        volidate = false
    })
    local data = block_instance.data
    lu.assertEquals(data[0], 32)
    lu.assertEquals(data[1], 0)
    lu.assertEquals(data[2], 3)
    lu.assertEquals(data[3], 4)
    lu.assertEquals(data[4], 5)
    lu.assertEquals(data[5], 6)

    lu.assertEquals(block_instance.length, 32)
    lu.assertEquals(block_instance.last_seg_length, 16)
    lu.assertEquals(block_instance.seg_num, 2)
    lu.assertEquals(block_instance.current_seg_num, 0)
end

function TestSystemInfo:test_save()
    local block_instance = block_info.new({
        db = {
            FirmwareVersion = '/31/1/3/4/5/6',
            save = function()
            end
        },
        prop = 'FirmwareVersion',
        system_id = 1,
        volidate = false
    })
    local res = block_instance:save()
    lu.assertEquals(res, true)
end

function TestSystemInfo:test_clear()
    local block_instance = block_info.new({
        db = {
            FirmwareVersion = '/31/1/3/4/5/6',
            save = function()
            end
        },
        prop = 'FirmwareVersion',
        system_id = 1,
        volidate = false
    })
    local data = block_instance.data
    lu.assertEquals(data[0], 31)
    lu.assertEquals(data[1], 1)
    lu.assertEquals(data[2], 3)
    lu.assertEquals(data[3], 4)
    lu.assertEquals(data[4], 5)
    lu.assertEquals(data[5], 6)
    lu.assertEquals(block_instance.length, 31)
    lu.assertEquals(block_instance.last_seg_length, 15)
    lu.assertEquals(block_instance.seg_num, 2)
    lu.assertEquals(block_instance.current_seg_num, 1)

    block_instance:clear()
    lu.assertEquals(block_instance.data, {})
    lu.assertEquals(block_instance.length, 0)
    lu.assertEquals(block_instance.last_seg_length, 0)
    lu.assertEquals(block_instance.seg_num, 0)
    lu.assertEquals(block_instance.current_seg_num, 0)
end

function TestSystemInfo:test_reallocate()
    local block_instance = block_info.new({
        db = {
            FirmwareVersion = '/31/1/3/4/5/6',
            save = function ()
                return true
            end
        },
        prop = 'FirmwareVersion',
        system_id = 1,
    })

    block_instance:reallocate()
    lu.assertEquals(block_instance.data[0], 0)
    lu.assertEquals(block_instance.length, 0)
    lu.assertEquals(block_instance.last_seg_length, 0)
    lu.assertEquals(block_instance.seg_num, 0)
    lu.assertEquals(block_instance.current_seg_num, 0)

    block_instance:reallocate(16)
    lu.assertEquals(block_instance.data[0], 16)
    lu.assertEquals(block_instance.length, 16)
    lu.assertEquals(block_instance.last_seg_length, 16)
    lu.assertEquals(block_instance.seg_num, 1)
    lu.assertEquals(block_instance.current_seg_num, 0)

    block_instance:reallocate(15)
    lu.assertEquals(block_instance.data[0], 15)
    lu.assertEquals(block_instance.length, 15)
    lu.assertEquals(block_instance.last_seg_length, 15)
    lu.assertEquals(block_instance.seg_num, 1)
    lu.assertEquals(block_instance.current_seg_num, 0)

    block_instance:reallocate(30)
    lu.assertEquals(block_instance.data[0], 30)
    lu.assertEquals(block_instance.length, 30)
    lu.assertEquals(block_instance.last_seg_length, 14)
    lu.assertEquals(block_instance.seg_num, 2)
    lu.assertEquals(block_instance.current_seg_num, 0)

    block_instance:reallocate(32)
    lu.assertEquals(block_instance.data[0], 32)
    lu.assertEquals(block_instance.length, 32)
    lu.assertEquals(block_instance.last_seg_length, 16)
    lu.assertEquals(block_instance.seg_num, 2)
    lu.assertEquals(block_instance.current_seg_num, 0)
end

-- 检验第一帧
function TestSystemInfo:test_validate_first_block()
    local block_instance = block_info.new({
        db = {
            FirmwareVersion = '/36/1/3/4/5/6',
            save = function ()
                return true
            end
        },
        prop = 'FirmwareVersion',
        system_id = 1,
    })
    -- 非法用例：未传参数
    local res = block_instance:validate_first_block()
    lu.assertEquals(res, cc.InvalidFieldRequest)

    -- 非法用例：总长度小于3
    res = block_instance:validate_first_block(0, 0)
    lu.assertEquals(res, cc.InvalidFieldRequest)

    -- 非法用例：只有一帧，数据长度13，实际传12
    res = block_instance:validate_first_block(13, 12)
    lu.assertEquals(res, cc.ReqDataLenInvalid)

    -- 合法用例：只有一帧，数据长度13，实际传13
    res = block_instance:validate_first_block(13, 13)
    lu.assertEquals(res, cc.Success)

    -- 合法用例：只有一帧，数据长度13，实际传大于13
    res = block_instance:validate_first_block(13, 16)
    lu.assertEquals(res, cc.Success)

    -- 非法用例：有多帧，数据长度20，实际传小于16
    res = block_instance:validate_first_block(20, 12)
    lu.assertEquals(res, cc.ReqDataLenInvalid)

    -- 合法用例：有多帧，数据长度20，实际传16
    res = block_instance:validate_first_block(20, 16)
    lu.assertEquals(res, cc.Success)

    -- 合法用例：有多帧，数据长度20，实际传大于16
    res = block_instance:validate_first_block(20, 20)
    lu.assertEquals(res, cc.Success)
end

-- 检验非第一帧
function TestSystemInfo:test_validate()
    local block_instance = block_info.new({
        db = {
            FirmwareVersion = '/36/1/3/4/5/6',
            save = function ()
                return true
            end
        },
        prop = 'FirmwareVersion',
        system_id = 1,
    })
    -- 非法用例：未传参数
    local res = block_instance:validate()
    lu.assertEquals(res, cc.InvalidFieldRequest)

    -- 非法用例：当前帧0，设置帧1
    block_instance.current_seg_num = 0
    res = block_instance:validate(1, 0)
    lu.assertEquals(res, cc.InvalidFieldRequest)

    -- 非法用例：非最后一帧，长度小于16
    block_instance.current_seg_num = 1
    res = block_instance:validate(1, 5)
    lu.assertEquals(res, cc.ReqDataLenInvalid)

    -- 合法用例：非最后一帧，长度等于16
    block_instance.current_seg_num = 1
    res = block_instance:validate(1, 16)
    lu.assertEquals(res, cc.Success)

    -- 非法用例：最后一帧，长度预期4，实际小于4
    block_instance.current_seg_num = 2
    res = block_instance:validate(2, 3)
    lu.assertEquals(res, cc.ReqDataLenInvalid)

    -- 合法用例：最后一帧，长度预期4，实际等于4
    block_instance.current_seg_num = 2
    res = block_instance:validate(2, 4)
    lu.assertEquals(res, cc.Success)

    -- 合法用例：最后一帧，长度预期4，实际大于4
    block_instance.current_seg_num = 2
    res = block_instance:validate(2, 5)
    lu.assertEquals(res, cc.Success)
end

-- 验证非最后一帧填充数据
function TestSystemInfo:test_fill_data()
    local block_instance = block_info.new({
        db = {
            FirmwareVersion = '/31/0/3/4/5/6',
            save = function ()
                return true
            end
        },
        prop = 'FirmwareVersion',
        system_id = 1,
    })

    -- 填充16字节
    block_instance.last_seg = false
    block_instance:fill_data(0, '\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x06')
    lu.assertEquals(block_instance.data[0], 31)
    -- 当前帧变为1
    lu.assertEquals(block_instance.data[1], 1)
    lu.assertEquals(block_instance.data[2], 1)
    lu.assertEquals(block_instance.data[16], 15)
    lu.assertEquals(block_instance.data[17], 6)
end

-- 验证最后一帧填充数据
function TestSystemInfo:test_fill_last_seg_data()
    local block_instance = block_info.new({
        db = {
            FirmwareVersion = '/6/0/3/4/5/6',
            save = function ()
                return true
            end
        },
        prop = 'FirmwareVersion',
        system_id = 1,
    })

    -- 填充16字节
    block_instance.last_seg = true
    block_instance:fill_data(0, '\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x06')
    lu.assertEquals(block_instance.data[0], 6)
    lu.assertEquals(block_instance.data[1], 0)
    lu.assertEquals(block_instance.data[2], 1)
    lu.assertEquals(block_instance.data[7], 6)
    lu.assertEquals(block_instance.data[8], 0)
end

-- 数据只有一帧，验证第一帧填充数据
function TestSystemInfo:test_set_firtst_block_info()
    local block_instance = block_info.new({
        db = {
            FirmwareVersion = '/6/0/3/4/5/6',
            save = function ()
                return true
            end
        },
        prop = 'FirmwareVersion',
        system_id = 1,
    })

    -- 长度小于4
    local res = block_instance:set_info('\x00\x02\x05', construct_ctx())
    lu.assertEquals(res, cc.ReqDataLenInvalid)

    -- 设置长度5，实际长度2
    res = block_instance:set_info('\x00\x02\x05\x01\x02', construct_ctx())
    lu.assertEquals(res, cc.ReqDataLenInvalid)

    -- 设置长度5，实际长度5
    res = block_instance:set_info('\x00\x02\x05\x01\x02\x01\x02\x01', construct_ctx())
    lu.assertEquals(res, cc.Success)

    -- 设置长度5，实际长度6
    res = block_instance:set_info('\x00\x02\x05\x01\x02\x03\x04\x05\x06', construct_ctx())
    lu.assertEquals(res, cc.Success)
    lu.assertEquals(block_instance.data[0], 7)
    lu.assertEquals(block_instance.data[1], 0)
    lu.assertEquals(block_instance.data[2], 2)
    lu.assertEquals(block_instance.data[6], 3)
    lu.assertEquals(block_instance.data[8], 5)
    lu.assertEquals(block_instance.data[9], 0)
end

-- 数据有两帧，验证第一\二帧填充数据
function TestSystemInfo:test_set_first_info_multi2_frame()
    local block_instance = block_info.new({
        db = {
            FirmwareVersion = '/6/0/3/4/5/6',
            save = function ()
                return true
            end
        },
        prop = 'FirmwareVersion',
        system_id = 1,
    })

    -- 先设置第一帧：长度为20，第一帧不满16字节
    local res = block_instance:set_info('\x00\x02\x14\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d',
        construct_ctx())
    lu.assertEquals(res, cc.ReqDataLenInvalid)

    -- 先设置第一帧：长度为20，第一帧16字节
    res = block_instance:set_info('\x00\x02\x14\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e',
        construct_ctx())
    lu.assertEquals(res, cc.Success)

    -- 先设置第一帧：长度为20，第一帧大于16字节
    res = block_instance:set_info('\x00\x02\x14\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f',
        construct_ctx())
    lu.assertEquals(res, cc.Success)
    lu.assertEquals(block_instance.length, 22)
    lu.assertEquals(block_instance.last_seg_length, 6)
    lu.assertEquals(block_instance.seg_num, 2)
    lu.assertEquals(block_instance.current_seg_num, 1)
    lu.assertEquals(block_instance.data[0], 22)
    lu.assertEquals(block_instance.data[1], 1)
    lu.assertEquals(block_instance.data[3], 20)
    lu.assertEquals(block_instance.data[17], 14)

    -- 再设置第二帧：数据长度小于6
    res = block_instance:set_info('\x01\x01\x02\x03\x04\x05', construct_ctx())
    lu.assertEquals(res, cc.ReqDataLenInvalid)

    -- 再设置第二帧：数据长度等于6
    res = block_instance:set_info('\x01\x01\x02\x03\x04\x05\x06', construct_ctx())
    lu.assertEquals(res, cc.Success)

    -- 再设置第二帧：数据长度大于6
    res = block_instance:set_info('\x01\x01\x02\x03\x04\x05\x06', construct_ctx())
    lu.assertEquals(res, cc.Success)
    lu.assertEquals(block_instance.data[0], 22)
    lu.assertEquals(block_instance.data[1], 1)
    lu.assertEquals(block_instance.data[3], 20)
    lu.assertEquals(block_instance.data[17], 14)
    lu.assertEquals(block_instance.data[18], 1)
    lu.assertEquals(block_instance.data[23], 6)
    lu.assertEquals(block_instance.data[24], 0)
end

-- 数据有三帧，验证第一\二\三帧填充数据
function TestSystemInfo:test_set_first_info_multi3_frame()
    local block_instance = block_info.new({
        db = {
            FirmwareVersion = '/6/0/3/4/5/6',
            save = function ()
                return true
            end
        },
        prop = 'FirmwareVersion',
        system_id = 1,
    })
    -- 先设置第一帧：长度为31，第一帧16字节
    local res = block_instance:set_info('\x00\x02\x1f\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e',
        construct_ctx())
    lu.assertEquals(res, cc.Success)

    -- 再设置第二帧：长度为31，第二帧小于16字节
    res = block_instance:set_info('\x01\x02\x1f\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d',
        construct_ctx())
    lu.assertEquals(res, cc.ReqDataLenInvalid)

    -- 再设置第二帧：长度为31，第二帧16字节
    res = block_instance:set_info('\x01\x02\x1f\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e',
        construct_ctx())
    lu.assertEquals(res, cc.Success)

    -- 再设置第三帧：数据长度1
    res = block_instance:set_info('\x02\x01', construct_ctx())
    lu.assertEquals(res, cc.Success)

    -- 再设置第三帧：数据长度1
    res = block_instance:set_info('\x02\xff\x06', construct_ctx())
    lu.assertEquals(res, cc.Success)
    lu.assertEquals(block_instance.data[0], 33)
    lu.assertEquals(block_instance.data[1], 2)
    lu.assertEquals(block_instance.data[3], 31)
    lu.assertEquals(block_instance.data[33], 14)
    lu.assertEquals(block_instance.data[34], 0xff)
    lu.assertEquals(block_instance.data[35], 0)
end

function TestSystemInfo:test_get_info()
    local block_instance = block_info.new({
        db = {
            FirmwareVersion = '/31/0/3/4/5/6',
            save = function ()
                return true
            end
        },
        prop = 'FirmwareVersion',
        system_id = 1,
    })
    local res, data

    res = block_instance:get_info(3)
    lu.assertEquals(res, cc.SensorInvalid)

    res, _, data = block_instance:get_info(1)
    lu.assertEquals(res, cc.Success)
    lu.assertEquals(data, '\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')

    -- 先设置第一帧：长度为31，第一帧16字节
    res = block_instance:set_info('\x00\x02\x1f\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e',
        construct_ctx())
    lu.assertEquals(res, cc.Success)
    res, _, data = block_instance:get_info(0)
    lu.assertEquals(res, cc.Success)
    lu.assertEquals(data, '\x00\x02\x1f\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e')

    -- 再设置第二帧：长度为31，第二帧16字节
    res = block_instance:set_info('\x01\x02\x1f\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0f',
        construct_ctx())
    lu.assertEquals(res, cc.Success)
    res, _, data = block_instance:get_info(1)
    lu.assertEquals(res, cc.Success)
    lu.assertEquals(data, '\x01\x02\x1f\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0f')

    -- 再设置第三帧：数据长度1
    res = block_instance:set_info('\x02\x06\xff', construct_ctx())
    lu.assertEquals(res, cc.Success)
    res, _, data = block_instance:get_info(2)
    lu.assertEquals(res, cc.Success)
    lu.assertEquals(data, '\02\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
end

function TestSystemInfo:test_chara_get_info()
    local character_instance = character_info.new({
        db = {
            BMCUrl = '',
            save = function ()
                return true
            end
        },
        prop = 'BMCUrl',
        system_id = 1,
    })
    local res, data

    res = character_instance:get_info()
    lu.assertEquals(res, cc.SensorInvalid)

    res = character_instance:set_info('\x00\x02\x1f\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e',
        construct_ctx())
    lu.assertEquals(res, cc.Success)

    res, _, data = character_instance:get_info()
    lu.assertEquals(res, cc.Success)
    lu.assertEquals(data, '\x00\x02\x1f\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e')
end

function TestSystemInfo:test_service_set_get_info()
    local boot_ser = boot_service.new(construct_db())
    local req = {
        GetOption = 0,
        SetSelector = 0,
        BlockSelector = 0
    }
    local res = boot_ser:get_system_info_parameters(req, {}, 1)
    lu.assertEquals(res, cc.DataNotAvailable)

    req = {}
    res = boot_ser:get_system_info_parameters(req, nil, 1)
    lu.assertEquals(res, cc.ReqDataLenInvalid)

    res = boot_ser:set_system_info_parameters(req, {}, 1)
    lu.assertEquals(res, cc.ReqDataLenInvalid)

    req = {
        Info = '\x00\x00\x04\x41\x42\x43\x44'
    }
    res = boot_ser:set_system_info_parameters(req, {}, 1)
    lu.assertEquals(res, cc.DataNotAvailable)

    res = boot_ser:clear_system_info()
    lu.assertEquals(res, nil)

    res = boot_ser:validate_system_info_selector(4)
    lu.assertEquals(res, true)
    res = boot_ser:validate_system_info_selector(9)
    lu.assertEquals(res, false)
end

function TestSystemInfo:test_obj_set_get_info()
    local get_boot_info_tbl = system_info_object.get_boot_info_tbl
    system_info_object.get_boot_info_tbl = function (db, system_id)
        local db_obj = {
            SystemId = system_id,
            SystemFirmwareVersion = '',
            SystemName = '',
            PrimaryOperatingSystemName = '',
            OperatingSystemName = '',
            PresentOSVersionNumber = '',
            BMCUrl = '',
            BaseOsUrlForManageability = '',
            save = function ()
                return true
            end
        }
        return db_obj
    end
    local system_info_obj = system_info_object.new({}, 1)

    local res, _, data = system_info_obj:get_info(0, 0)
    lu.assertEquals(res, cc.Success)
    lu.assertEquals(data, s_pack('I1', 0))

    res = system_info_obj:get_info(1, 0)
    lu.assertEquals(res, cc.SensorInvalid)

    local info = ''
    res = system_info_obj:set_info(1, info, construct_ctx())
    lu.assertEquals(res, cc.ReqDataLenInvalid)

    info = '\x00\x00\x04\x41\x42\x43\x44'

    res = system_info_obj:set_info(1, info, construct_ctx())
    lu.assertEquals(res, cc.Success)

    res, _, data = system_info_obj:get_info(1, 0)
    lu.assertEquals(res, cc.Success)
    lu.assertEquals(data, '\x00\x00\x04\x41\x42\x43\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')

    res = system_info_obj:set_info(0, '\x01', construct_ctx())
    lu.assertEquals(res, cc.Success)

    res = system_info_obj:set_info(0, '\x30\x31', construct_ctx())
    lu.assertEquals(res, cc.ReqDataLenInvalid)

    res = system_info_obj:set_info(0, '\x33', construct_ctx())
    lu.assertEquals(res, cc.InvalidFieldRequest)

    res = system_info_obj:set_info(0, '\x01', construct_ctx())
    lu.assertEquals(res, 0x81)

    local ok = pcall(function (...)
        system_info_obj:clear_system_info()
    end)
    lu.assertEquals(ok, true)

    system_info_object.get_boot_info_tbl = get_boot_info_tbl
end