ce14869d创建于 2025年5月6日历史提交
/*

 * Copyright (c) 2021 Huawei Device Co., Ltd.

 * Licensed under the Apache License, Version 2.0 (the "License");

 * you may not use this file except in compliance with the License.

 * You may obtain a copy of the License at

 *

 *     http://www.apache.org/licenses/LICENSE-2.0

 *

 * Unless required by applicable law or agreed to in writing, software

 * distributed under the License is distributed on an "AS IS" BASIS,

 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

 * See the License for the specific language governing permissions and

 * limitations under the License.

 */



#include "tlv_ut.h"

#include <gmock/gmock.h>

#include <gtest/gtest.h>



using namespace testing::ext;

using namespace testing;



namespace Hdc {

#define MAX_BUFFER_SIZE (1 * 1024 * 1024 * 1024)

class HdcTLVTest : public testing::Test {

public:

    static void SetUpTestCase(void);

    static void TearDownTestCase(void);

    void SetUp();

    void TearDown();

private:

    uint8_t *BuildTlv(const std::vector<uint32_t> tags,

            const std::vector<uint32_t> sizes, uint8_t val, uint32_t &tlvsize) const;

            

    uint32_t TlvSize(uint32_t len) { return len + TLV_HEAD_SIZE; }

};



void HdcTLVTest::SetUpTestCase()

{

}



void HdcTLVTest::TearDownTestCase() {}



void HdcTLVTest::SetUp() {}



void HdcTLVTest::TearDown() {}



uint8_t *HdcTLVTest::BuildTlv(const std::vector<uint32_t> tags,

    const std::vector<uint32_t> sizes,

    uint8_t val,

    uint32_t &tlvsize) const

{

    if (tags.size() != sizes.size() || tags.empty()) {

        WRITE_LOG(LOG_WARN, "not valid size: %u, %u", tags.size(), sizes.size());

        return nullptr;

    }

    tlvsize = 0;

    for (auto size : sizes) {

        tlvsize += TLV_HEAD_SIZE;

        tlvsize += size;

    }



    if (tlvsize == 0 || tlvsize > MAX_BUFFER_SIZE) {

        WRITE_LOG(LOG_WARN, "invalid size 0");

        return nullptr;

    }

    uint8_t *tlv = new (std::nothrow) uint8_t[tlvsize];

    if (tlv == nullptr) {

        WRITE_LOG(LOG_WARN, "not enough memory %u", tlvsize);

        tlvsize = 0;

        return nullptr;

    }

    uint32_t pos = 0;

    int i = 0;

    for (; pos < tlvsize && i < tags.size(); i++) {

        *(uint32_t *)(tlv + pos) = tags[i];

        *(uint32_t *)(tlv + pos + sizeof(tags[i])) = sizes[i];



        pos += TLV_HEAD_SIZE;

        if (memset_s(tlv + pos, tlvsize - pos, val, sizes[i]) != 0) {

            tlvsize = 0;

            delete[] tlv;

            return nullptr;

        }

        pos += sizes[i];

    }



    return tlv;

}



HWTEST_F(HdcTLVTest, TlvBuf_Constructor_001, TestSize.Level0)

{

    TlvBuf tb;

    ASSERT_EQ(tb.GetBufSize(), 0);

}



HWTEST_F(HdcTLVTest, TlvBuf_Constructor_002, TestSize.Level0)

{

    std::set<uint32_t> validtags = { 1, 2, 3 };

    TlvBuf tb(validtags);

    ASSERT_EQ(tb.GetBufSize(), 0);

}



HWTEST_F(HdcTLVTest, TlvBuf_Constructor_003, TestSize.Level0)

{

    std::vector<uint32_t> tags = { 1 };

    std::vector<uint32_t> sizes = { 1 };

    uint32_t tlvsize = 0;

    uint8_t *tlv = this->BuildTlv(tags, sizes, 0xAB, tlvsize);

    ASSERT_NE(tlv, nullptr);



    TlvBuf tb(tlv, tlvsize);

    ASSERT_EQ(tb.GetBufSize(), tlvsize);



    delete[] tlv;

}



HWTEST_F(HdcTLVTest, TlvBuf_Constructor_004, TestSize.Level0)

{

    std::set<uint32_t> validtags = { 1, 2, 3 };



    std::vector<uint32_t> tags = { 1 };

    std::vector<uint32_t> sizes = { 1 };

    uint32_t tlvsize = 0;

    uint8_t *tlv = this->BuildTlv(tags, sizes, 0xAB, tlvsize);

    ASSERT_NE(tlv, nullptr);



    TlvBuf tb(tlv, tlvsize, validtags);

    ASSERT_EQ(tb.GetBufSize(), tlvsize);



    delete[] tlv;

}



HWTEST_F(HdcTLVTest, TlvBuf_Constructor_005, TestSize.Level0)

{

    std::set<uint32_t> validtags = { 1, 2, 3 };



    std::vector<uint32_t> tags = { 1 };

    std::vector<uint32_t> sizes = { TLV_VALUE_MAX_LEN + 1 };

    uint32_t tlvsize = 0;

    uint8_t *tlv = this->BuildTlv(tags, sizes, 0xAB, tlvsize);

    ASSERT_NE(tlv, nullptr);



    TlvBuf tb(tlv, tlvsize, validtags);

    ASSERT_EQ(tb.GetBufSize(), 0);



    delete[] tlv;

}



HWTEST_F(HdcTLVTest, TlvBuf_Clear_001, TestSize.Level0)

{

    std::vector<uint32_t> tags = { 1 };

    std::vector<uint32_t> sizes = { 1 };

    uint32_t tlvsize = 0;

    uint8_t *tlv = this->BuildTlv(tags, sizes, 0xAB, tlvsize);

    ASSERT_NE(tlv, nullptr);



    TlvBuf tb(tlv, tlvsize);

    ASSERT_EQ(tb.GetBufSize(), tlvsize);

    tb.Clear();

    ASSERT_EQ(tb.GetBufSize(), 0);



    delete[] tlv;

}



HWTEST_F(HdcTLVTest, TlvBuf_Append_001, TestSize.Level0)

{

    uint8_t val[10] = { 0xAC };

    TlvBuf tb;

    ASSERT_EQ(tb.GetBufSize(), 0);



    ASSERT_EQ(tb.Append(1, sizeof(val), val), true);

    ASSERT_EQ(tb.GetBufSize(), TlvSize(sizeof(val)));



    // duplicate, append failed, nothing changed

    ASSERT_EQ(tb.Append(1, sizeof(val), val), false);

    ASSERT_EQ(tb.GetBufSize(), TlvSize(sizeof(val)));



    ASSERT_EQ(tb.Append(2, sizeof(val), val), true);

    ASSERT_EQ(tb.GetBufSize(), TlvSize(sizeof(val)) * 2);

}



HWTEST_F(HdcTLVTest, TlvBuf_Append_002, TestSize.Level0)

{

    uint32_t tag = 1;

    string val = "hello world!";

    TlvBuf tb;

    ASSERT_EQ(tb.GetBufSize(), 0);



    ASSERT_EQ(tb.Append(tag, val), true);

    ASSERT_EQ(tb.GetBufSize(), TlvSize(val.size()));

}



HWTEST_F(HdcTLVTest, TlvBuf_Append_003, TestSize.Level0)

{

    TlvBuf tb;



    ASSERT_EQ(tb.Append(1, 0, nullptr), false);

    ASSERT_EQ(tb.GetBufSize(), 0);



    ASSERT_EQ(tb.Append(1, TLV_VALUE_MAX_LEN + 1, nullptr), false);

    ASSERT_EQ(tb.GetBufSize(), 0);



    ASSERT_EQ(tb.Append(1, TLV_VALUE_MAX_LEN, nullptr), false);

    ASSERT_EQ(tb.GetBufSize(), 0);

}



HWTEST_F(HdcTLVTest, TlvBuf_CopyToBuf_001, TestSize.Level0)

{

    uint32_t tag = 1;

    const uint32_t len = 10;

    uint8_t val[len] = { 0xAC };

    TlvBuf tb;

    ASSERT_EQ(tb.GetBufSize(), 0);



    ASSERT_EQ(tb.Append(tag, len, val), true);

    uint32_t size = tb.GetBufSize();

    ASSERT_EQ(size, TlvSize(len));



    uint8_t *buf = new (std::nothrow) uint8_t[size];

    ASSERT_EQ(tb.CopyToBuf(buf, size - 1), false);

    ASSERT_EQ(tb.CopyToBuf(nullptr, size), false);



    ASSERT_EQ(tb.CopyToBuf(buf, size), true);

    ASSERT_EQ(*(uint32_t *)buf, tag);

    ASSERT_EQ(*(uint32_t *)(buf + sizeof(tag)), len);

    ASSERT_EQ(memcmp(buf + TLV_HEAD_SIZE, val, len), 0);

}



HWTEST_F(HdcTLVTest, TlvBuf_FindTlv_001, TestSize.Level0)

{

    uint32_t tag = 1;

    const uint32_t len = 10;

    uint8_t val[len] = { 0xAC };

    TlvBuf tb;

    ASSERT_EQ(tb.GetBufSize(), 0);



    ASSERT_EQ(tb.Append(tag, len, val), true);

    ASSERT_EQ(tb.GetBufSize(), TlvSize(len));



    uint32_t ftag = 2;

    uint32_t flen = 1;

    uint8_t *fval = nullptr;

    ASSERT_EQ(tb.FindTlv(ftag, flen, fval), false);

    ASSERT_EQ(fval, nullptr);

    ftag = 1;

    ASSERT_EQ(tb.FindTlv(ftag, flen, fval), true);

    ASSERT_EQ(flen, len);

    ASSERT_EQ(memcmp(fval, val, len), 0);



    delete[] fval;

}



HWTEST_F(HdcTLVTest, TlvBuf_FindTlv_002, TestSize.Level0)

{

    uint32_t tag = 1;

    string val = "hello world!";

    TlvBuf tb;

    ASSERT_EQ(tb.GetBufSize(), 0);



    ASSERT_EQ(tb.Append(tag, val), true);

    ASSERT_EQ(tb.GetBufSize(), TlvSize(val.size()));



    string fval;

    ASSERT_EQ(tb.FindTlv(tag, fval), true);

    ASSERT_EQ(val, fval);

}



HWTEST_F(HdcTLVTest, TlvBuf_ContainInvalidTag_001, TestSize.Level0)

{

    std::set<uint32_t> validtags = { 1, 2, 3 };

    std::vector<uint32_t> tags = { 1, 2, 3 };

    std::vector<uint32_t> sizes = { 4, 4, 4 };

    uint32_t tlvsize = 0;

    uint8_t *tlv = this->BuildTlv(tags, sizes, 0xAB, tlvsize);

    ASSERT_NE(tlv, nullptr);

    TlvBuf tb(tlv, tlvsize, validtags);

    ASSERT_EQ(tb.GetBufSize(), tlvsize);



    ASSERT_EQ(tb.ContainInvalidTag(), false);



    uint32_t tag = 5;

    const uint32_t len = 10;

    uint8_t val[len] = { 0xAC };

    ASSERT_EQ(tb.Append(tag, len, val), true);

    ASSERT_EQ(tb.ContainInvalidTag(), true);



    delete[] tlv;

}



HWTEST_F(HdcTLVTest, TlvBuf_ContainInvalidTag_002, TestSize.Level0)

{

    std::set<uint32_t> validtags = { 1, 2 };

    std::vector<uint32_t> tags = { 1, 2, 3 };

    std::vector<uint32_t> sizes = { 4, 4, 4 };

    uint32_t tlvsize = 0;

    uint8_t *tlv = this->BuildTlv(tags, sizes, 0xAB, tlvsize);

    ASSERT_NE(tlv, nullptr);

    TlvBuf tb(tlv, tlvsize, validtags);

    ASSERT_EQ(tb.GetBufSize(), tlvsize);



    ASSERT_EQ(tb.ContainInvalidTag(), true);



    delete[] tlv;

}



HWTEST_F(HdcTLVTest, TlvBuf_Display_001, TestSize.Level0)

{

    std::vector<uint32_t> tags = { 1 };

    std::vector<uint32_t> sizes = { 1 };

    uint32_t tlvsize = 0;

    uint8_t *tlv = this->BuildTlv(tags, sizes, 0xAB, tlvsize);

    ASSERT_NE(tlv, nullptr);



    TlvBuf tb(tlv, tlvsize);

    ASSERT_EQ(tb.GetBufSize(), tlvsize);

    tb.Display();



    delete[] tlv;

}



} // namespace Hdc