1*a49a3f79SGaurav Gandhi // Copyright 2021 Google Inc.
2*a49a3f79SGaurav Gandhi //
3*a49a3f79SGaurav Gandhi // Licensed under the Apache License, Version 2.0 (the "License");
4*a49a3f79SGaurav Gandhi // you may not use this file except in compliance with the License.
5*a49a3f79SGaurav Gandhi // You may obtain a copy of the License at
6*a49a3f79SGaurav Gandhi //
7*a49a3f79SGaurav Gandhi // http://www.apache.org/licenses/LICENSE-2.0
8*a49a3f79SGaurav Gandhi //
9*a49a3f79SGaurav Gandhi // Unless required by applicable law or agreed to in writing, software
10*a49a3f79SGaurav Gandhi // distributed under the License is distributed on an "AS IS" BASIS,
11*a49a3f79SGaurav Gandhi // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*a49a3f79SGaurav Gandhi // See the License for the specific language governing permissions and
13*a49a3f79SGaurav Gandhi // limitations under the License.
14*a49a3f79SGaurav Gandhi
15*a49a3f79SGaurav Gandhi #include "log_handler.hpp"
16*a49a3f79SGaurav Gandhi #include "log_mock.hpp"
17*a49a3f79SGaurav Gandhi
18*a49a3f79SGaurav Gandhi #include <memory>
19*a49a3f79SGaurav Gandhi #include <string>
20*a49a3f79SGaurav Gandhi #include <string_view>
21*a49a3f79SGaurav Gandhi #include <vector>
22*a49a3f79SGaurav Gandhi
23*a49a3f79SGaurav Gandhi #include <gtest/gtest.h>
24*a49a3f79SGaurav Gandhi
25*a49a3f79SGaurav Gandhi using ::testing::_;
26*a49a3f79SGaurav Gandhi using ::testing::DoAll;
27*a49a3f79SGaurav Gandhi using ::testing::ElementsAreArray;
28*a49a3f79SGaurav Gandhi using ::testing::Ge;
29*a49a3f79SGaurav Gandhi using ::testing::IsEmpty;
30*a49a3f79SGaurav Gandhi using ::testing::Return;
31*a49a3f79SGaurav Gandhi
32*a49a3f79SGaurav Gandhi namespace ipmi_flash
33*a49a3f79SGaurav Gandhi {
34*a49a3f79SGaurav Gandhi
35*a49a3f79SGaurav Gandhi class LogReadBlobTest : public ::testing::Test
36*a49a3f79SGaurav Gandhi {
37*a49a3f79SGaurav Gandhi protected:
SetUp()38*a49a3f79SGaurav Gandhi void SetUp() override
39*a49a3f79SGaurav Gandhi {
40*a49a3f79SGaurav Gandhi h = std::make_unique<LogBlobHandler>(
41*a49a3f79SGaurav Gandhi createMockLogConfigs(blobNames, &im, &tm));
42*a49a3f79SGaurav Gandhi }
43*a49a3f79SGaurav Gandhi std::unique_ptr<blobs::GenericBlobInterface> h;
44*a49a3f79SGaurav Gandhi std::vector<std::string> blobNames{"blob0", "blob1", "blob2", "blob3"};
45*a49a3f79SGaurav Gandhi std::unordered_map<std::string, TriggerMock*> tm;
46*a49a3f79SGaurav Gandhi std::unordered_map<std::string, ImageHandlerMock*> im;
47*a49a3f79SGaurav Gandhi const std::uint16_t defaultSessionNumber{200};
48*a49a3f79SGaurav Gandhi std::vector<uint8_t> vector1{0xDE, 0xAD, 0xBE, 0xEF,
49*a49a3f79SGaurav Gandhi 0xBA, 0xDF, 0xEE, 0x0D};
50*a49a3f79SGaurav Gandhi std::vector<uint8_t> vector2{0xCE, 0xAD, 0xDE, 0xFF};
51*a49a3f79SGaurav Gandhi };
52*a49a3f79SGaurav Gandhi
TEST_F(LogReadBlobTest,VerifyValidRead)53*a49a3f79SGaurav Gandhi TEST_F(LogReadBlobTest, VerifyValidRead)
54*a49a3f79SGaurav Gandhi {
55*a49a3f79SGaurav Gandhi testing::InSequence seq;
56*a49a3f79SGaurav Gandhi EXPECT_CALL(*tm.at("blob0"), trigger())
57*a49a3f79SGaurav Gandhi .WillOnce(DoAll([&]() { tm.at("blob0")->cb(*tm.at("blob0")); },
58*a49a3f79SGaurav Gandhi Return(true)));
59*a49a3f79SGaurav Gandhi EXPECT_CALL(*tm.at("blob0"), status())
60*a49a3f79SGaurav Gandhi .WillOnce(Return(ActionStatus::success));
61*a49a3f79SGaurav Gandhi EXPECT_CALL(*im.at("blob0"), open(_, std::ios::in)).WillOnce(Return(true));
62*a49a3f79SGaurav Gandhi EXPECT_CALL(*im.at("blob0"), read(0, Ge(vector1.size())))
63*a49a3f79SGaurav Gandhi .WillOnce(Return(vector1));
64*a49a3f79SGaurav Gandhi EXPECT_CALL(*im.at("blob0"), close()).Times(1);
65*a49a3f79SGaurav Gandhi EXPECT_TRUE(h->open(defaultSessionNumber, blobs::read, "blob0"));
66*a49a3f79SGaurav Gandhi
67*a49a3f79SGaurav Gandhi std::basic_string_view<uint8_t> vectorS(vector1.data(), vector1.size());
68*a49a3f79SGaurav Gandhi EXPECT_THAT(h->read(defaultSessionNumber, 0, 7),
69*a49a3f79SGaurav Gandhi ElementsAreArray(vectorS.substr(0, 7)));
70*a49a3f79SGaurav Gandhi EXPECT_THAT(h->read(defaultSessionNumber, 2, 10),
71*a49a3f79SGaurav Gandhi ElementsAreArray(vectorS.substr(2, 6)));
72*a49a3f79SGaurav Gandhi EXPECT_THAT(h->read(defaultSessionNumber, 10, 0), IsEmpty());
73*a49a3f79SGaurav Gandhi }
74*a49a3f79SGaurav Gandhi
TEST_F(LogReadBlobTest,VerifyMultipleSession)75*a49a3f79SGaurav Gandhi TEST_F(LogReadBlobTest, VerifyMultipleSession)
76*a49a3f79SGaurav Gandhi {
77*a49a3f79SGaurav Gandhi testing::InSequence seq;
78*a49a3f79SGaurav Gandhi EXPECT_CALL(*tm.at("blob0"), trigger()).WillOnce(Return(true));
79*a49a3f79SGaurav Gandhi EXPECT_TRUE(h->open(0, blobs::read, "blob0"));
80*a49a3f79SGaurav Gandhi EXPECT_TRUE(h->open(1, blobs::read, "blob0"));
81*a49a3f79SGaurav Gandhi
82*a49a3f79SGaurav Gandhi EXPECT_CALL(*tm.at("blob0"), status())
83*a49a3f79SGaurav Gandhi .WillOnce(Return(ActionStatus::success));
84*a49a3f79SGaurav Gandhi EXPECT_CALL(*im.at("blob0"), open(_, std::ios::in)).WillOnce(Return(true));
85*a49a3f79SGaurav Gandhi EXPECT_CALL(*im.at("blob0"), read(0, Ge(vector1.size())))
86*a49a3f79SGaurav Gandhi .WillOnce(Return(vector1));
87*a49a3f79SGaurav Gandhi EXPECT_CALL(*im.at("blob0"), close()).Times(1);
88*a49a3f79SGaurav Gandhi tm.at("blob0")->cb(*tm.at("blob0"));
89*a49a3f79SGaurav Gandhi
90*a49a3f79SGaurav Gandhi EXPECT_CALL(*tm.at("blob0"), trigger()).WillOnce(Return(true));
91*a49a3f79SGaurav Gandhi EXPECT_TRUE(h->open(2, blobs::read, "blob0"));
92*a49a3f79SGaurav Gandhi
93*a49a3f79SGaurav Gandhi EXPECT_CALL(*tm.at("blob0"), status())
94*a49a3f79SGaurav Gandhi .WillOnce(Return(ActionStatus::success));
95*a49a3f79SGaurav Gandhi EXPECT_CALL(*im.at("blob0"), open(_, std::ios::in)).WillOnce(Return(true));
96*a49a3f79SGaurav Gandhi EXPECT_CALL(*im.at("blob0"), read(0, Ge(vector2.size())))
97*a49a3f79SGaurav Gandhi .WillOnce(Return(vector2));
98*a49a3f79SGaurav Gandhi EXPECT_CALL(*im.at("blob0"), close()).Times(1);
99*a49a3f79SGaurav Gandhi tm.at("blob0")->cb(*tm.at("blob0"));
100*a49a3f79SGaurav Gandhi
101*a49a3f79SGaurav Gandhi EXPECT_THAT(h->read(0, 0, 10), ElementsAreArray(vector1));
102*a49a3f79SGaurav Gandhi EXPECT_THAT(h->read(1, 0, 10), ElementsAreArray(vector1));
103*a49a3f79SGaurav Gandhi EXPECT_THAT(h->read(2, 0, 10), ElementsAreArray(vector2));
104*a49a3f79SGaurav Gandhi }
105*a49a3f79SGaurav Gandhi
TEST_F(LogReadBlobTest,VerifyReadEarlyFails)106*a49a3f79SGaurav Gandhi TEST_F(LogReadBlobTest, VerifyReadEarlyFails)
107*a49a3f79SGaurav Gandhi {
108*a49a3f79SGaurav Gandhi EXPECT_CALL(*tm.at("blob0"), trigger()).WillOnce(Return(true));
109*a49a3f79SGaurav Gandhi
110*a49a3f79SGaurav Gandhi EXPECT_TRUE(h->open(defaultSessionNumber, blobs::read, "blob0"));
111*a49a3f79SGaurav Gandhi EXPECT_THROW(h->read(defaultSessionNumber, 0, 10), std::runtime_error);
112*a49a3f79SGaurav Gandhi }
113*a49a3f79SGaurav Gandhi
TEST_F(LogReadBlobTest,VerifyTriggerFailureReadFails)114*a49a3f79SGaurav Gandhi TEST_F(LogReadBlobTest, VerifyTriggerFailureReadFails)
115*a49a3f79SGaurav Gandhi {
116*a49a3f79SGaurav Gandhi EXPECT_CALL(*tm.at("blob0"), trigger())
117*a49a3f79SGaurav Gandhi .WillOnce(DoAll([&]() { tm.at("blob0")->cb(*tm.at("blob0")); },
118*a49a3f79SGaurav Gandhi Return(true)));
119*a49a3f79SGaurav Gandhi EXPECT_CALL(*tm.at("blob0"), status())
120*a49a3f79SGaurav Gandhi .WillOnce(Return(ActionStatus::failed));
121*a49a3f79SGaurav Gandhi EXPECT_TRUE(h->open(defaultSessionNumber, blobs::read, "blob0"));
122*a49a3f79SGaurav Gandhi EXPECT_THROW(h->read(defaultSessionNumber, 0, 10), std::runtime_error);
123*a49a3f79SGaurav Gandhi }
124*a49a3f79SGaurav Gandhi
TEST_F(LogReadBlobTest,VerifyReadFailsOnFileOpenFailure)125*a49a3f79SGaurav Gandhi TEST_F(LogReadBlobTest, VerifyReadFailsOnFileOpenFailure)
126*a49a3f79SGaurav Gandhi {
127*a49a3f79SGaurav Gandhi EXPECT_CALL(*tm.at("blob0"), trigger())
128*a49a3f79SGaurav Gandhi .WillOnce(DoAll([&]() { tm.at("blob0")->cb(*tm.at("blob0")); },
129*a49a3f79SGaurav Gandhi Return(true)));
130*a49a3f79SGaurav Gandhi EXPECT_CALL(*tm.at("blob0"), status())
131*a49a3f79SGaurav Gandhi .WillOnce(Return(ActionStatus::success));
132*a49a3f79SGaurav Gandhi EXPECT_CALL(*im.at("blob0"), open(_, std::ios::in)).WillOnce(Return(false));
133*a49a3f79SGaurav Gandhi
134*a49a3f79SGaurav Gandhi EXPECT_TRUE(h->open(defaultSessionNumber, blobs::read, "blob0"));
135*a49a3f79SGaurav Gandhi EXPECT_THROW(h->read(defaultSessionNumber, 0, 10), std::runtime_error);
136*a49a3f79SGaurav Gandhi }
137*a49a3f79SGaurav Gandhi
TEST_F(LogReadBlobTest,VerifyReadFailsOnFileReadFailure)138*a49a3f79SGaurav Gandhi TEST_F(LogReadBlobTest, VerifyReadFailsOnFileReadFailure)
139*a49a3f79SGaurav Gandhi {
140*a49a3f79SGaurav Gandhi EXPECT_CALL(*tm.at("blob0"), trigger())
141*a49a3f79SGaurav Gandhi .WillOnce(DoAll([&]() { tm.at("blob0")->cb(*tm.at("blob0")); },
142*a49a3f79SGaurav Gandhi Return(true)));
143*a49a3f79SGaurav Gandhi EXPECT_CALL(*tm.at("blob0"), status())
144*a49a3f79SGaurav Gandhi .WillOnce(Return(ActionStatus::success));
145*a49a3f79SGaurav Gandhi EXPECT_CALL(*im.at("blob0"), open(_, std::ios::in)).WillOnce(Return(true));
146*a49a3f79SGaurav Gandhi EXPECT_CALL(*im.at("blob0"), read(_, _)).WillOnce(Return(std::nullopt));
147*a49a3f79SGaurav Gandhi EXPECT_CALL(*im.at("blob0"), close()).Times(1);
148*a49a3f79SGaurav Gandhi
149*a49a3f79SGaurav Gandhi EXPECT_TRUE(h->open(defaultSessionNumber, blobs::read, "blob0"));
150*a49a3f79SGaurav Gandhi EXPECT_THROW(h->read(defaultSessionNumber, 0, 10), std::runtime_error);
151*a49a3f79SGaurav Gandhi }
152*a49a3f79SGaurav Gandhi
153*a49a3f79SGaurav Gandhi } // namespace ipmi_flash
154