95432b86创建于 2025年12月22日历史提交
/*
 * Copyright (c)2025 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 <gtest/gtest.h>

#include <thread>
#include <chrono>
#include <cstring>

#include "heartbeat.h"

using namespace Hdc;
using namespace std::chrono;

class HdcHeartbeatTest : public ::testing::Test {
protected:
    HdcHeartbeat heartbeat;
    
    void SetUp() override {
        heartbeat = HdcHeartbeat();
    }
};

HWTEST_F(HdcHeartbeatTest, HdcHeartbeatTest1, ConstructorInitializesCorrectly) {
    EXPECT_EQ(heartbeat.GetHeartbeatCount(), 0);
    EXPECT_FALSE(heartbeat.GetSupportHeartbeat());
}

HWTEST_F(HdcHeartbeatTest, HdcHeartbeatTest2, AddHeartbeatCountIncrementsCount) {
    heartbeat.AddHeartbeatCount();
    EXPECT_EQ(heartbeat.GetHeartbeatCount(), 1);
    
    heartbeat.AddHeartbeatCount();
    heartbeat.AddHeartbeatCount();
    EXPECT_EQ(heartbeat.GetHeartbeatCount(), 3);
}

HWTEST_F(HdcHeartbeatTest, HdcHeartbeatTest3, SetAndGetSupportHeartbeat) {
    heartbeat.SetSupportHeartbeat(true);
    EXPECT_TRUE(heartbeat.GetSupportHeartbeat());
    
    heartbeat.SetSupportHeartbeat(false);
    EXPECT_FALSE(heartbeat.GetSupportHeartbeat());
    
    heartbeat.SetSupportHeartbeat(true);
    EXPECT_TRUE(heartbeat.GetSupportHeartbeat());
}

HWTEST_F(HdcHeartbeatTest, HdcHeartbeatTest4, HandleMessageCountReturnsBoolean) {
    bool result = heartbeat.HandleMessageCount();
    EXPECT_TRUE(result || !result);
    
    for (int i = 0; i < 20; ++i) {
        result = heartbeat.HandleMessageCount();
    }
}

HWTEST_F(HdcHeartbeatTest, HdcHeartbeatTest5, ToStringReturnsNonEmptyString) {
    std::string str = heartbeat.ToString();
    EXPECT_FALSE(str.empty());
    EXPECT_NE(str.find("HdcHeartbeat"), std::string::npos);
    
    heartbeat.AddHeartbeatCount();
    heartbeat.SetSupportHeartbeat(true);
    
    std::string str2 = heartbeat.ToString();
    EXPECT_FALSE(str2.empty());
    EXPECT_NE(str, str2);
    EXPECT_NE(str2.find("heartbeatCount=1"), std::string::npos);
    EXPECT_NE(str2.find("supportHeartbeat=true"), std::string::npos);
}

HWTEST_F(HdcHeartbeatTest, HdcHeartbeatTest6, HandleRecvHeartbeatMsgWithNullPayload) {
    std::string result = heartbeat.HandleRecvHeartbeatMsg(nullptr, 0);
    EXPECT_FALSE(result.empty());
    EXPECT_NE(result.find("ERROR"), std::string::npos);
    
    result = heartbeat.HandleRecvHeartbeatMsg(nullptr, 10);
    EXPECT_FALSE(result.empty());
    EXPECT_NE(result.find("ERROR"), std::string::npos);
    
    result = heartbeat.HandleRecvHeartbeatMsg(nullptr, -1);
    EXPECT_FALSE(result.empty());
    EXPECT_NE(result.find("ERROR"), std::string::npos);
}

HWTEST_F(HdcHeartbeatTest, HdcHeartbeatTest7, HandleRecvHeartbeatMsgWithValidPayload) {
    uint8_t payload[] = {'H', 'e', 'l', 'l', 'o'};
    
    std::string result = heartbeat.HandleRecvHeartbeatMsg(payload, sizeof(payload));
    EXPECT_FALSE(result.empty());
    EXPECT_NE(result.find("HEARTBEAT_RESPONSE"), std::string::npos);
    EXPECT_NE(result.find("NACK"), std::string::npos);
    
    heartbeat.SetSupportHeartbeat(true);
    result = heartbeat.HandleRecvHeartbeatMsg(payload, sizeof(payload));
    EXPECT_FALSE(result.empty());
    EXPECT_NE(result.find("HEARTBEAT_RESPONSE"), std::string::npos);
    EXPECT_NE(result.find("ACK"), std::string::npos);
}

HWTEST_F(HdcHeartbeatTest, HdcHeartbeatTest8, HandleRecvHeartbeatMsgWithLargePayload) {
    const int largeSize = 10000;
    uint8_t* largePayload = new uint8_t[largeSize];
    memset(largePayload, 'A', largeSize);
    
    heartbeat.SetSupportHeartbeat(true);
    std::string result = heartbeat.HandleRecvHeartbeatMsg(largePayload, largeSize);
    EXPECT_FALSE(result.empty());
    EXPECT_NE(result.find("HEARTBEAT_RESPONSE"), std::string::npos);
    EXPECT_NE(result.find("ACK"), std::string::npos);
    EXPECT_NE(result.find("..."), std::string::npos);
    
    delete[] largePayload;
}

HWTEST_F(HdcHeartbeatTest, HdcHeartbeatTest9, ThreadSafetyForAddHeartbeatCount) {
    const int numThreads = 10;
    const int incrementsPerThread = 1000;
    
    std::vector<std::thread> threads;
    
    for (int i = 0; i < numThreads; ++i) {
        threads.emplace_back([&]() {
            for (int j = 0; j < incrementsPerThread; ++j) {
                heartbeat.AddHeartbeatCount();
            }
        });
    }
    
    for (auto& thread : threads) {
        thread.join();
    }
    
    EXPECT_EQ(heartbeat.GetHeartbeatCount(), numThreads * incrementsPerThread);
}

HWTEST_F(HdcHeartbeatTest, HdcHeartbeatTest10, ThreadSafetyForSetSupportHeartbeat) {
    std::atomic<bool> testPassed{true};
    
    std::thread t1([&]() {
        for (int i = 0; i < 1000; ++i) {
            heartbeat.SetSupportHeartbeat(true);
            std::this_thread::sleep_for(std::chrono::microseconds(10));
        }
    });
    
    std::thread t2([&]() {
        for (int i = 0; i < 1000; ++i) {
            heartbeat.SetSupportHeartbeat(false);
            std::this_thread::sleep_for(std::chrono::microseconds(10));
        }
    });
    
    t1.join();
    t2.join();
    
    bool finalState = heartbeat.GetSupportHeartbeat();
    EXPECT_TRUE(finalState || !finalState);
}

HWTEST_F(HdcHeartbeatTest, HdcHeartbeatTest11, MultipleHandleMessageCountCalls) {
    for (int i = 0; i < 100; ++i) {
        bool result = heartbeat.HandleMessageCount();
        EXPECT_TRUE(result || !result);
    }
}

HWTEST_F(HdcHeartbeatTest, HdcHeartbeatTest12, ConsecutiveToStringCalls) {
    std::string str1 = heartbeat.ToString();
    std::string str2 = heartbeat.ToString();
    
    EXPECT_EQ(str1.substr(0, str1.find("lastTimeElapsed")), 
              str2.substr(0, str2.find("lastTimeElapsed")));
    
    heartbeat.AddHeartbeatCount();
    
    std::string str3 = heartbeat.ToString();
    std::string str4 = heartbeat.ToString();
    
    EXPECT_EQ(str3.substr(0, str3.find("lastTimeElapsed")), 
              str4.substr(0, str4.find("lastTimeElapsed")));
    EXPECT_NE(str1, str3);
}

HWTEST_F(HdcHeartbeatTest, HdcHeartbeatTest13, MixedOperations) {
    heartbeat.SetSupportHeartbeat(true);
    EXPECT_TRUE(heartbeat.GetSupportHeartbeat());
    
    heartbeat.AddHeartbeatCount();
    EXPECT_EQ(heartbeat.GetHeartbeatCount(), 1);
    
    bool handleResult = heartbeat.HandleMessageCount();
    EXPECT_TRUE(handleResult || !handleResult);
    
    std::string str = heartbeat.ToString();
    EXPECT_FALSE(str.empty());
    EXPECT_NE(str.find("heartbeatCount=1"), std::string::npos);
    
    uint8_t payload[] = {'T', 'e', 's', 't'};
    std::string result = heartbeat.HandleRecvHeartbeatMsg(payload, sizeof(payload));
    EXPECT_FALSE(result.empty());
    EXPECT_NE(result.find("ACK"), std::string::npos);
    EXPECT_EQ(heartbeat.GetHeartbeatCount(), 2);
}

HWTEST_F(HdcHeartbeatTest, HdcHeartbeatTest14, ResetBehavior) {
    heartbeat.SetSupportHeartbeat(true);
    heartbeat.AddHeartbeatCount();
    heartbeat.AddHeartbeatCount();
    
    EXPECT_TRUE(heartbeat.GetSupportHeartbeat());
    EXPECT_EQ(heartbeat.GetHeartbeatCount(), 2);
    
    HdcHeartbeat newHeartbeat;
    EXPECT_EQ(newHeartbeat.GetHeartbeatCount(), 0);
    EXPECT_FALSE(newHeartbeat.GetSupportHeartbeat());
}

HWTEST_F(HdcHeartbeatTest, HdcHeartbeatTest15, HandleRecvHeartbeatMsgWithSpecialCharacters) {
    uint8_t payload1[] = {0x00, 0xFF, 0x80, 0x7F};
    heartbeat.SetSupportHeartbeat(true);
    std::string result1 = heartbeat.HandleRecvHeartbeatMsg(payload1, sizeof(payload1));
    EXPECT_FALSE(result1.empty());
    EXPECT_NE(result1.find("ACK_DATA:00FF807F"), std::string::npos);
    
    uint8_t payload2[] = {'\n', '\t', '\r', '\0', 'E', 'N', 'D'};
    std::string result2 = heartbeat.HandleRecvHeartbeatMsg(payload2, sizeof(payload2));
    EXPECT_FALSE(result2.empty());
    EXPECT_NE(result2.find("ACK_DATA:0A090D00"), std::string::npos);
}

HWTEST_F(HdcHeartbeatTest, HdcHeartbeatTest16, HandleMessageCountWithHeartbeatSupport) {
    heartbeat.SetSupportHeartbeat(true);
    
    for (int i = 0; i < 5; ++i) {
        heartbeat.AddHeartbeatCount();
    }
    
    bool result = heartbeat.HandleMessageCount();
    
    std::this_thread::sleep_for(std::chrono::seconds(1));
    result = heartbeat.HandleMessageCount();
    
    EXPECT_EQ(heartbeat.GetHeartbeatCount(), 0);
}

HWTEST_F(HdcHeartbeatTest, HdcHeartbeatTest17, PerformanceTestMultipleAdds) {
    const int iterations = 1000000;
    
    auto start = steady_clock::now();
    
    for (int i = 0; i < iterations; ++i) {
        heartbeat.AddHeartbeatCount();
    }
    
    auto end = steady_clock::now();
    auto duration = duration_cast<milliseconds>(end - start);
    
    EXPECT_EQ(heartbeat.GetHeartbeatCount(), iterations);
    
    std::cout << "Performance: " << iterations << " AddHeartbeatCount calls took " 
              << duration.count() << " ms" << std::endl;
}

HWTEST_F(HdcHeartbeatTest, HdcHeartbeatTest18, HandleRecvHeartbeatMsgIncrementsCountWhenSupported) {
    heartbeat.SetSupportHeartbeat(false);
    uint8_t payload[] = {'X'};
    
    std::string result1 = heartbeat.HandleRecvHeartbeatMsg(payload, 1);
    EXPECT_EQ(heartbeat.GetHeartbeatCount(), 0);
    
    heartbeat.SetSupportHeartbeat(true);
    std::string result2 = heartbeat.HandleRecvHeartbeatMsg(payload, 1);
    EXPECT_EQ(heartbeat.GetHeartbeatCount(), 1);
    
    std::string result3 = heartbeat.HandleRecvHeartbeatMsg(payload, 1);
    EXPECT_EQ(heartbeat.GetHeartbeatCount(), 2);
}

HWTEST_F(HdcHeartbeatTest, HdcHeartbeatTest19, ToStringContainsAllFields) {
    heartbeat.SetSupportHeartbeat(true);
    heartbeat.AddHeartbeatCount();
    heartbeat.AddHeartbeatCount();
    
    for (int i = 0; i < 15; ++i) {
        heartbeat.HandleMessageCount();
    }
    
    std::string str = heartbeat.ToString();
    
    EXPECT_NE(str.find("heartbeatCount=2"), std::string::npos);
    EXPECT_NE(str.find("messageCount="), std::string::npos);
    EXPECT_NE(str.find("supportHeartbeat=true"), std::string::npos);
    EXPECT_NE(str.find("lastTimeElapsed="), std::string::npos);
    EXPECT_NE(str.find("ms"), std::string::npos);
}

HWTEST_F(HdcHeartbeatTest, HdcHeartbeatTest20, EmptyPayloadHandling) {
    uint8_t emptyPayload[] = {};
    
    heartbeat.SetSupportHeartbeat(true);
    std::string result = heartbeat.HandleRecvHeartbeatMsg(emptyPayload, 0);
    
    EXPECT_NE(result.find("ERROR"), std::string::npos);
    
    result = heartbeat.HandleRecvHeartbeatMsg(nullptr, 0);
    EXPECT_NE(result.find("ERROR"), std::string::npos);
}