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::Return; 14 namespace ipmi_flash 15 { 16 17 class VersionOpenBlobTest : public ::testing::Test 18 { 19 protected: 20 void SetUp() override 21 { 22 VersionInfoMap vim; 23 for (const auto& blobName : blobNames) 24 { 25 auto t = CreateTriggerMock(); 26 auto i = CreateImageMock(); 27 tm[blobName] = reinterpret_cast<TriggerMock*>(t.get()); 28 im[blobName] = reinterpret_cast<ImageHandlerMock*>(i.get()); 29 vim.try_emplace( 30 blobName, 31 VersionInfoPack( 32 blobName, std::make_unique<VersionActionPack>(std::move(t)), 33 std::move(i))); 34 } 35 h = VersionBlobHandler::create(std::move(vim)); 36 ASSERT_NE(h, nullptr); 37 for (const auto& [key, val] : tm) 38 { 39 /* by default no action triggers expected to be called */ 40 EXPECT_CALL(*val, trigger()).Times(0); 41 } 42 for (const auto& [key, val] : im) 43 { 44 /* by default no image handler open is expected to be called */ 45 EXPECT_CALL(*val, open(_, _)).Times(0); 46 } 47 } 48 std::unique_ptr<blobs::GenericBlobInterface> h; 49 std::vector<std::string> blobNames{"blob0", "blob1", "blob2", "blob3"}; 50 std::unordered_map<std::string, TriggerMock*> tm; 51 std::unordered_map<std::string, ImageHandlerMock*> im; 52 const std::uint16_t defaultSessionNumber{0}; 53 }; 54 55 TEST_F(VersionOpenBlobTest, VerifySingleBlobOpen) 56 { 57 EXPECT_CALL(*tm.at("blob0"), trigger()).Times(1).WillOnce(Return(true)); 58 EXPECT_TRUE(h->open(defaultSessionNumber, blobs::read, "blob0")); 59 } 60 61 TEST_F(VersionOpenBlobTest, VerifyMultipleBlobOpens) 62 { 63 for (const auto& [key, val] : tm) 64 { 65 /* set the expectation that every onOpen will be triggered */ 66 EXPECT_CALL(*val, trigger()).Times(1).WillOnce(Return(true)); 67 } 68 int i{defaultSessionNumber}; 69 for (const auto& blob : blobNames) 70 { 71 EXPECT_TRUE(h->open(i++, blobs::read, blob)); 72 } 73 } 74 75 TEST_F(VersionOpenBlobTest, VerifyOpenAfterClose) 76 { 77 EXPECT_CALL(*tm.at("blob0"), trigger()) 78 .Times(2) 79 .WillRepeatedly(Return(true)); 80 EXPECT_TRUE(h->open(defaultSessionNumber, blobs::read, "blob0")); 81 EXPECT_TRUE(h->close(defaultSessionNumber)); 82 EXPECT_TRUE(h->open(defaultSessionNumber, blobs::read, "blob0")); 83 } 84 85 TEST_F(VersionOpenBlobTest, VerifyDuplicateSessionNumberFails) 86 { 87 EXPECT_CALL(*tm.at("blob0"), trigger()).Times(1).WillOnce(Return(true)); 88 EXPECT_CALL(*tm.at("blob1"), trigger()).Times(1).WillOnce(Return(true)); 89 EXPECT_TRUE(h->open(defaultSessionNumber, blobs::read, "blob1")); 90 /* the duplicate session number of 0 91 * should cause a failure for the open of a different blob 92 */ 93 EXPECT_FALSE(h->open(defaultSessionNumber, blobs::read, "blob0")); 94 /* open after fail due to seq number works */ 95 EXPECT_TRUE(h->open(defaultSessionNumber + 1, blobs::read, "blob0")); 96 } 97 98 TEST_F(VersionOpenBlobTest, VerifyDoubleOpenFails) 99 { 100 EXPECT_CALL(*tm.at("blob1"), trigger()) 101 .Times(1) 102 .WillRepeatedly(Return(true)); 103 EXPECT_TRUE(h->open(0, blobs::read, "blob1")); 104 EXPECT_FALSE(h->open(2, blobs::read, "blob1")); 105 } 106 107 TEST_F(VersionOpenBlobTest, VerifyFailedTriggerFails) 108 { 109 EXPECT_CALL(*tm.at("blob1"), trigger()) 110 .Times(2) 111 .WillOnce(Return(false)) 112 .WillOnce(Return(true)); 113 EXPECT_FALSE(h->open(0, blobs::read, "blob1")); 114 EXPECT_TRUE(h->open(0, blobs::read, "blob1")); 115 } 116 117 TEST_F(VersionOpenBlobTest, VerifyUnsupportedOpenFlagsFails) 118 { 119 EXPECT_CALL(*tm.at("blob1"), trigger()).Times(1).WillOnce(Return(true)); 120 EXPECT_FALSE(h->open(0, blobs::write, "blob1")); 121 EXPECT_TRUE(h->open(0, blobs::read, "blob1")); 122 } 123 124 } // namespace ipmi_flash 125