1 #include "version_handler.hpp" 2 #include "version_mock.hpp" 3 4 #include <memory> 5 #include <string> 6 #include <string_view> 7 #include <vector> 8 9 #include <gtest/gtest.h> 10 11 using ::testing::_; 12 using ::testing::DoAll; 13 using ::testing::ElementsAreArray; 14 using ::testing::Ge; 15 using ::testing::IsEmpty; 16 using ::testing::Return; 17 18 namespace ipmi_flash 19 { 20 21 class VersionReadBlobTest : public ::testing::Test 22 { 23 protected: 24 void SetUp() override 25 { 26 h = std::make_unique<VersionBlobHandler>( 27 createMockVersionConfigs(blobNames, &im, &tm)); 28 } 29 std::unique_ptr<blobs::GenericBlobInterface> h; 30 std::vector<std::string> blobNames{"blob0", "blob1", "blob2", "blob3"}; 31 std::unordered_map<std::string, TriggerMock*> tm; 32 std::unordered_map<std::string, ImageHandlerMock*> im; 33 const std::uint16_t defaultSessionNumber{200}; 34 std::vector<uint8_t> vector1{0xDE, 0xAD, 0xBE, 0xEF, 35 0xBA, 0xDF, 0xEE, 0x0D}; 36 std::vector<uint8_t> vector2{0xCE, 0xAD, 0xDE, 0xFF}; 37 }; 38 39 TEST_F(VersionReadBlobTest, VerifyValidRead) 40 { 41 testing::InSequence seq; 42 EXPECT_CALL(*tm.at("blob0"), trigger()) 43 .WillOnce(DoAll([&]() { tm.at("blob0")->cb(*tm.at("blob0")); }, 44 Return(true))); 45 EXPECT_CALL(*tm.at("blob0"), status()) 46 .WillOnce(Return(ActionStatus::success)); 47 EXPECT_CALL(*im.at("blob0"), open(_, std::ios::in)).WillOnce(Return(true)); 48 EXPECT_CALL(*im.at("blob0"), read(0, Ge(vector1.size()))) 49 .WillOnce(Return(vector1)); 50 EXPECT_CALL(*im.at("blob0"), close()).Times(1); 51 EXPECT_TRUE(h->open(defaultSessionNumber, blobs::read, "blob0")); 52 53 std::basic_string_view<uint8_t> vectorS(vector1.data(), vector1.size()); 54 EXPECT_THAT(h->read(defaultSessionNumber, 0, 7), 55 ElementsAreArray(vectorS.substr(0, 7))); 56 EXPECT_THAT(h->read(defaultSessionNumber, 2, 10), 57 ElementsAreArray(vectorS.substr(2, 6))); 58 EXPECT_THAT(h->read(defaultSessionNumber, 10, 0), IsEmpty()); 59 } 60 61 TEST_F(VersionReadBlobTest, VerifyMultipleSession) 62 { 63 testing::InSequence seq; 64 EXPECT_CALL(*tm.at("blob0"), trigger()).WillOnce(Return(true)); 65 EXPECT_TRUE(h->open(0, blobs::read, "blob0")); 66 EXPECT_TRUE(h->open(1, blobs::read, "blob0")); 67 68 EXPECT_CALL(*tm.at("blob0"), status()) 69 .WillOnce(Return(ActionStatus::success)); 70 EXPECT_CALL(*im.at("blob0"), open(_, std::ios::in)).WillOnce(Return(true)); 71 EXPECT_CALL(*im.at("blob0"), read(0, Ge(vector1.size()))) 72 .WillOnce(Return(vector1)); 73 EXPECT_CALL(*im.at("blob0"), close()).Times(1); 74 tm.at("blob0")->cb(*tm.at("blob0")); 75 76 EXPECT_CALL(*tm.at("blob0"), trigger()).WillOnce(Return(true)); 77 EXPECT_TRUE(h->open(2, blobs::read, "blob0")); 78 79 EXPECT_CALL(*tm.at("blob0"), status()) 80 .WillOnce(Return(ActionStatus::success)); 81 EXPECT_CALL(*im.at("blob0"), open(_, std::ios::in)).WillOnce(Return(true)); 82 EXPECT_CALL(*im.at("blob0"), read(0, Ge(vector2.size()))) 83 .WillOnce(Return(vector2)); 84 EXPECT_CALL(*im.at("blob0"), close()).Times(1); 85 tm.at("blob0")->cb(*tm.at("blob0")); 86 87 EXPECT_THAT(h->read(0, 0, 10), ElementsAreArray(vector1)); 88 EXPECT_THAT(h->read(1, 0, 10), ElementsAreArray(vector1)); 89 EXPECT_THAT(h->read(2, 0, 10), ElementsAreArray(vector2)); 90 } 91 92 TEST_F(VersionReadBlobTest, VerifyReadEarlyFails) 93 { 94 EXPECT_CALL(*tm.at("blob0"), trigger()).WillOnce(Return(true)); 95 96 EXPECT_TRUE(h->open(defaultSessionNumber, blobs::read, "blob0")); 97 EXPECT_THAT(h->read(defaultSessionNumber, 0, 10), IsEmpty()); 98 } 99 100 TEST_F(VersionReadBlobTest, VerifyTriggerFailureReadFails) 101 { 102 EXPECT_CALL(*tm.at("blob0"), trigger()) 103 .WillOnce(DoAll([&]() { tm.at("blob0")->cb(*tm.at("blob0")); }, 104 Return(true))); 105 EXPECT_CALL(*tm.at("blob0"), status()) 106 .WillOnce(Return(ActionStatus::failed)); 107 EXPECT_TRUE(h->open(defaultSessionNumber, blobs::read, "blob0")); 108 EXPECT_THAT(h->read(defaultSessionNumber, 0, 10), IsEmpty()); 109 } 110 111 TEST_F(VersionReadBlobTest, VerifyReadFailsOnFileOpenFailure) 112 { 113 EXPECT_CALL(*tm.at("blob0"), trigger()) 114 .WillOnce(DoAll([&]() { tm.at("blob0")->cb(*tm.at("blob0")); }, 115 Return(true))); 116 EXPECT_CALL(*tm.at("blob0"), status()) 117 .WillOnce(Return(ActionStatus::success)); 118 EXPECT_CALL(*im.at("blob0"), open(_, std::ios::in)).WillOnce(Return(false)); 119 120 EXPECT_TRUE(h->open(defaultSessionNumber, blobs::read, "blob0")); 121 EXPECT_THAT(h->read(defaultSessionNumber, 0, 10), IsEmpty()); 122 } 123 124 TEST_F(VersionReadBlobTest, VerifyReadFailsOnFileReadFailure) 125 { 126 EXPECT_CALL(*tm.at("blob0"), trigger()) 127 .WillOnce(DoAll([&]() { tm.at("blob0")->cb(*tm.at("blob0")); }, 128 Return(true))); 129 EXPECT_CALL(*tm.at("blob0"), status()) 130 .WillOnce(Return(ActionStatus::success)); 131 EXPECT_CALL(*im.at("blob0"), open(_, std::ios::in)).WillOnce(Return(true)); 132 EXPECT_CALL(*im.at("blob0"), read(_, _)).WillOnce(Return(std::nullopt)); 133 EXPECT_CALL(*im.at("blob0"), close()).Times(1); 134 135 EXPECT_TRUE(h->open(defaultSessionNumber, blobs::read, "blob0")); 136 EXPECT_THAT(h->read(defaultSessionNumber, 0, 10), IsEmpty()); 137 } 138 139 } // namespace ipmi_flash 140