| #include "cper_encoder.hpp" |
| |
| #include <chrono> |
| |
| #include "gtest/gtest.h" |
| #include <gmock/gmock.h> |
| |
| namespace uefi::cper |
| { |
| class CperEncoderTest : public testing::Test |
| { |
| public: |
| void SetUp() override |
| {} |
| |
| void expectEqTimestamp( |
| const uint64_t cperTimestamp, |
| const std::chrono::time_point<std::chrono::system_clock> ref, |
| const bool isPrecise = true) |
| { |
| Timestamp structTimestamp; |
| memcpy(&structTimestamp, &cperTimestamp, sizeof(structTimestamp)); |
| |
| time_t tt = std::chrono::system_clock::to_time_t(ref); |
| tm utcTime = *gmtime(&tt); |
| |
| EXPECT_EQ(structTimestamp.seconds, utcTime.tm_sec); |
| EXPECT_EQ(structTimestamp.minutes, utcTime.tm_min); |
| EXPECT_EQ(structTimestamp.hours, utcTime.tm_hour); |
| EXPECT_EQ(structTimestamp.isPrecise, (isPrecise & 0x1)); |
| EXPECT_EQ(structTimestamp.day, utcTime.tm_mday); |
| EXPECT_EQ(structTimestamp.month, utcTime.tm_mon); |
| EXPECT_EQ(structTimestamp.year, (utcTime.tm_year + 1900) % 100); |
| EXPECT_EQ(structTimestamp.century, (utcTime.tm_year + 1900) / 100); |
| } |
| }; |
| |
| TEST_F(CperEncoderTest, SeqMemcopy) |
| { |
| std::string section1 = "Hello"; |
| std::string section2 = " "; |
| std::string section3 = "World"; |
| |
| std::string dest(section1.size() + section2.size() + section3.size(), 0); |
| |
| SeqMemcopy<char> seqMemcpy(dest); |
| |
| EXPECT_NO_THROW(seqMemcpy.copy(section1.data(), section1.size())); |
| EXPECT_NO_THROW(seqMemcpy.copy(section2.data(), section2.size())); |
| EXPECT_NO_THROW(seqMemcpy.copy(section3.data(), section3.size())); |
| |
| EXPECT_EQ(dest, section1 + section2 + section3); |
| |
| std::string section4 = "This is an attempted buffer overflow!"; |
| |
| EXPECT_THROW(seqMemcpy.copy(section4.data(), section4.size()), |
| std::out_of_range); |
| } |
| |
| TEST_F(CperEncoderTest, CreateCperTimestamp) |
| { |
| const auto now = std::chrono::system_clock::now(); |
| |
| const uint64_t preciseTimestamp = createCperTimestamp(now); |
| expectEqTimestamp(preciseTimestamp, now); |
| |
| const uint64_t impreciseTimestamp = createCperTimestamp(now, false); |
| expectEqTimestamp(impreciseTimestamp, now, false); |
| } |
| |
| TEST_F(CperEncoderTest, SmokeTest) |
| { |
| RecordHeader recordHeader; |
| |
| const std::array<uint8_t, 4> kExpectedSignature = {'C', 'P', 'E', 'R'}; |
| const std::array<uint8_t, 12> kExpectedReserved = {0}; |
| |
| EXPECT_EQ(recordHeader.signature, kExpectedSignature); |
| EXPECT_EQ(recordHeader.revision, 0x0000); |
| EXPECT_EQ(recordHeader.signatureEnd, 0xffffffff); |
| EXPECT_EQ(recordHeader.reserved, kExpectedReserved); |
| |
| // Check for proper packing by putting a needle in the haystack. |
| recordHeader.flags = 0xBEEF; |
| const size_t flagsOffset = 104; |
| |
| std::array<uint8_t, sizeof(recordHeader)> headerBin; |
| memcpy(&headerBin, &recordHeader, sizeof(headerBin)); |
| |
| uint32_t flagsValue; |
| memcpy(&flagsValue, &headerBin[flagsOffset], sizeof(flagsValue)); |
| EXPECT_EQ(recordHeader.flags, flagsValue); |
| } |
| } // namespace uefi::cper |