1 #include "helper.hpp"
2 #include "ipmi.hpp"
3 #include "manager_mock.hpp"
4 
5 #include <cstring>
6 #include <string>
7 
8 #include <gtest/gtest.h>
9 
10 namespace blobs
11 {
12 
13 using ::testing::_;
14 using ::testing::Invoke;
15 using ::testing::NotNull;
16 using ::testing::Return;
17 using ::testing::StrEq;
18 
19 TEST(BlobOpenTest, InvalidRequestLengthReturnsFailure)
20 {
21     // There is a minimum blobId length of one character, this test verifies
22     // we check that.
23     ManagerMock mgr;
24     std::vector<uint8_t> request;
25     BmcBlobOpenTx req;
26     std::string blobId = "abc";
27 
28     req.crc = 0;
29     req.flags = 0;
30 
31     // Missintg the nul-terminator.
32     request.resize(sizeof(struct BmcBlobOpenTx));
33     std::memcpy(request.data(), &req, sizeof(struct BmcBlobOpenTx));
34     request.insert(request.end(), blobId.begin(), blobId.end());
35 
36     EXPECT_EQ(ipmi::responseReqDataLenInvalid(), openBlob(&mgr, request));
37 }
38 
39 TEST(BlobOpenTest, RequestRejectedReturnsFailure)
40 {
41     // The blobId is rejected for any reason.
42     ManagerMock mgr;
43     std::vector<uint8_t> request;
44     BmcBlobOpenTx req;
45     std::string blobId = "a";
46 
47     req.crc = 0;
48     req.flags = 0;
49     request.resize(sizeof(struct BmcBlobOpenTx));
50     std::memcpy(request.data(), &req, sizeof(struct BmcBlobOpenTx));
51     request.insert(request.end(), blobId.begin(), blobId.end());
52     request.emplace_back('\0');
53 
54     EXPECT_CALL(mgr, open(req.flags, StrEq(blobId), _)).WillOnce(Return(false));
55 
56     EXPECT_EQ(ipmi::responseUnspecifiedError(), openBlob(&mgr, request));
57 }
58 
59 TEST(BlobOpenTest, BlobOpenReturnsOk)
60 {
61     // The boring case where the blobId opens.
62 
63     ManagerMock mgr;
64     std::vector<uint8_t> request;
65     BmcBlobOpenTx req;
66     struct BmcBlobOpenRx rep;
67     std::string blobId = "a";
68 
69     req.crc = 0;
70     req.flags = 0;
71     request.resize(sizeof(struct BmcBlobOpenTx));
72     std::memcpy(request.data(), &req, sizeof(struct BmcBlobOpenTx));
73     request.insert(request.end(), blobId.begin(), blobId.end());
74     request.emplace_back('\0');
75 
76     uint16_t returnedSession = 0x54;
77 
78     EXPECT_CALL(mgr, open(req.flags, StrEq(blobId), NotNull()))
79         .WillOnce(Invoke([&](uint16_t, const std::string&, uint16_t* session) {
80             (*session) = returnedSession;
81             return true;
82         }));
83 
84     auto result = validateReply(openBlob(&mgr, request));
85 
86     rep.crc = 0;
87     rep.sessionId = returnedSession;
88 
89     EXPECT_EQ(sizeof(rep), result.size());
90     EXPECT_EQ(0, std::memcmp(result.data(), &rep, sizeof(rep)));
91 }
92 } // namespace blobs
93