1 #include "flags.hpp" 2 #include "image_mock.hpp" 3 #include "triggerable_mock.hpp" 4 #include "util.hpp" 5 #include "version_handler.hpp" 6 7 #include <array> 8 #include <string> 9 #include <vector> 10 11 #include <gtest/gtest.h> 12 using ::testing::_; 13 using ::testing::IsEmpty; 14 using ::testing::Return; 15 namespace ipmi_flash 16 { 17 18 class VersionReadBlobTest : public ::testing::Test 19 { 20 protected: 21 void SetUp() override 22 { 23 VersionInfoMap vim; 24 for (const auto& blobName : blobNames) 25 { 26 auto t = CreateTriggerMock(); 27 auto i = CreateImageMock(); 28 tm[blobName] = reinterpret_cast<TriggerMock*>(t.get()); 29 im[blobName] = reinterpret_cast<ImageHandlerMock*>(i.get()); 30 vim.try_emplace( 31 blobName, 32 VersionInfoPack( 33 blobName, std::make_unique<VersionActionPack>(std::move(t)), 34 std::move(i))); 35 } 36 h = VersionBlobHandler::create(std::move(vim)); 37 ASSERT_NE(h, nullptr); 38 for (const auto& [key, val] : tm) 39 { 40 ON_CALL(*val, trigger()).WillByDefault(Return(true)); 41 } 42 } 43 std::unique_ptr<blobs::GenericBlobInterface> h; 44 std::vector<std::string> blobNames{"blob0", "blob1", "blob2", "blob3"}; 45 std::unordered_map<std::string, TriggerMock*> tm; 46 std::unordered_map<std::string, ImageHandlerMock*> im; 47 const std::uint16_t defaultSessionNumber{200}; 48 std::vector<uint8_t> vector1{0xDE, 0xAD, 0xBE, 0xEF, 49 0xBA, 0xDF, 0xEE, 0x0D}; 50 }; 51 52 TEST_F(VersionReadBlobTest, VerifyValidRead) 53 { 54 EXPECT_CALL(*tm.at("blob0"), status()) 55 .Times(2) 56 .WillRepeatedly(Return(ActionStatus::success)); 57 EXPECT_TRUE(h->open(defaultSessionNumber, blobs::read, "blob0")); 58 /* file path gets bound to file_handler on creation so path parameter 59 * doesn't actually matter 60 */ 61 EXPECT_CALL(*im.at("blob0"), open(_, std::ios::in)) 62 .Times(2) 63 .WillRepeatedly(Return(true)); 64 EXPECT_CALL(*im.at("blob0"), read(0, 10)).WillOnce(Return(vector1)); 65 EXPECT_CALL(*im.at("blob0"), read(2, 10)).WillOnce(Return(vector1)); 66 EXPECT_CALL(*im.at("blob0"), close()).Times(2); 67 68 EXPECT_EQ(h->read(defaultSessionNumber, 0, 10), vector1); 69 EXPECT_EQ(h->read(defaultSessionNumber, 2, 10), vector1); 70 } 71 72 TEST_F(VersionReadBlobTest, VerifyUnopenedReadFails) 73 { 74 EXPECT_CALL(*tm.at("blob0"), status()).Times(0); 75 EXPECT_CALL(*im.at("blob0"), open(_, _)).Times(0); 76 EXPECT_CALL(*im.at("blob0"), read(_, _)).Times(0); 77 78 EXPECT_THAT(h->read(defaultSessionNumber, 0, 10), IsEmpty()); 79 } 80 81 TEST_F(VersionReadBlobTest, VerifyTriggerFailureReadFails) 82 { 83 EXPECT_CALL(*tm.at("blob0"), status()) 84 .Times(1) 85 .WillOnce(Return(ActionStatus::failed)); 86 EXPECT_CALL(*im.at("blob0"), open(_, _)).Times(0); 87 EXPECT_TRUE(h->open(defaultSessionNumber, blobs::read, "blob0")); 88 EXPECT_THAT(h->read(defaultSessionNumber, 0, 10), IsEmpty()); 89 } 90 91 TEST_F(VersionReadBlobTest, VerifyReadFailsOnFileReadFailure) 92 { 93 EXPECT_CALL(*tm.at("blob0"), status()) 94 .Times(1) 95 .WillOnce(Return(ActionStatus::success)); 96 /* file path gets bound to file_handler on creation so path parameter 97 * doesn't actually matter 98 */ 99 EXPECT_CALL(*im.at("blob0"), open(_, std::ios::in)) 100 .Times(1) 101 .WillOnce(Return(true)); 102 EXPECT_CALL(*im.at("blob0"), read(_, _)) 103 .Times(1) 104 .WillOnce(Return(std::nullopt)); 105 EXPECT_CALL(*im.at("blob0"), close()).Times(1); 106 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 /* first call to trigger status fails, second succeeds */ 114 EXPECT_CALL(*tm.at("blob0"), status()) 115 .Times(1) 116 .WillOnce(Return(ActionStatus::success)); 117 /* file path gets bound to file_handler on creation so path parameter 118 * doesn't actually matter 119 */ 120 EXPECT_CALL(*im.at("blob0"), open(_, std::ios::in)) 121 .Times(1) 122 .WillOnce(Return(false)); 123 124 EXPECT_TRUE(h->open(defaultSessionNumber, blobs::read, "blob0")); 125 EXPECT_THAT(h->read(defaultSessionNumber, 0, 10), IsEmpty()); 126 } 127 128 } // namespace ipmi_flash 129