blob: 5b18631e9d921c864b1b499b949f03ae52429d36 [file] [log] [blame]
Patrick Ventureef3aead2018-09-12 08:53:29 -07001#include "ipmi.hpp"
Patrick Venturecd8dab42019-01-15 19:57:38 -08002#include "manager_mock.hpp"
Patrick Ventureef3aead2018-09-12 08:53:29 -07003
Patrick Ventureef3aead2018-09-12 08:53:29 -07004#include <cstring>
5#include <string>
6
7#include <gtest/gtest.h>
8
9namespace blobs
10{
11
12using ::testing::_;
13using ::testing::Invoke;
14using ::testing::NotNull;
15using ::testing::Return;
16using ::testing::StrEq;
17
18// ipmid.hpp isn't installed where we can grab it and this value is per BMC
19// SoC.
20#define MAX_IPMI_BUFFER 64
21
22TEST(BlobOpenTest, InvalidRequestLengthReturnsFailure)
23{
24 // There is a minimum blobId length of one character, this test verifies
25 // we check that.
26
27 ManagerMock mgr;
28 size_t dataLen;
29 uint8_t request[MAX_IPMI_BUFFER] = {0};
30 uint8_t reply[MAX_IPMI_BUFFER] = {0};
31 auto req = reinterpret_cast<struct BmcBlobOpenTx*>(request);
32 std::string blobId = "abc";
33
Patrick Venture00d5f0d2019-05-17 19:21:35 -070034 req->cmd = static_cast<std::uint8_t>(BlobOEMCommands::bmcBlobOpen);
Patrick Ventureef3aead2018-09-12 08:53:29 -070035 req->crc = 0;
36 req->flags = 0;
37 // length() doesn't include the nul-terminator.
William A. Kennington III117912d2021-06-15 18:22:44 -070038 std::memcpy(req + 1, blobId.c_str(), blobId.length());
Patrick Ventureef3aead2018-09-12 08:53:29 -070039
40 dataLen = sizeof(struct BmcBlobOpenTx) + blobId.length();
41
Patrick Venture41258802018-11-12 10:46:30 -080042 EXPECT_EQ(IPMI_CC_REQ_DATA_LEN_INVALID,
43 openBlob(&mgr, request, reply, &dataLen));
Patrick Ventureef3aead2018-09-12 08:53:29 -070044}
45
46TEST(BlobOpenTest, RequestRejectedReturnsFailure)
47{
48 // The blobId is rejected for any reason.
49
50 ManagerMock mgr;
51 size_t dataLen;
52 uint8_t request[MAX_IPMI_BUFFER] = {0};
53 uint8_t reply[MAX_IPMI_BUFFER] = {0};
54 auto req = reinterpret_cast<struct BmcBlobOpenTx*>(request);
55 std::string blobId = "a";
56
Patrick Venture00d5f0d2019-05-17 19:21:35 -070057 req->cmd = static_cast<std::uint8_t>(BlobOEMCommands::bmcBlobOpen);
Patrick Ventureef3aead2018-09-12 08:53:29 -070058 req->crc = 0;
59 req->flags = 0;
60 // length() doesn't include the nul-terminator, request buff is initialized
61 // to 0s
William A. Kennington III117912d2021-06-15 18:22:44 -070062 std::memcpy(req + 1, blobId.c_str(), blobId.length());
Patrick Ventureef3aead2018-09-12 08:53:29 -070063
64 dataLen = sizeof(struct BmcBlobOpenTx) + blobId.length() + 1;
65
66 EXPECT_CALL(mgr, open(req->flags, StrEq(blobId), _))
67 .WillOnce(Return(false));
68
Patrick Venture41258802018-11-12 10:46:30 -080069 EXPECT_EQ(IPMI_CC_UNSPECIFIED_ERROR,
70 openBlob(&mgr, request, reply, &dataLen));
Patrick Ventureef3aead2018-09-12 08:53:29 -070071}
72
73TEST(BlobOpenTest, BlobOpenReturnsOk)
74{
75 // The boring case where the blobId opens.
76
77 ManagerMock mgr;
78 size_t dataLen;
79 uint8_t request[MAX_IPMI_BUFFER] = {0};
80 uint8_t reply[MAX_IPMI_BUFFER] = {0};
81 auto req = reinterpret_cast<struct BmcBlobOpenTx*>(request);
82 struct BmcBlobOpenRx rep;
83 std::string blobId = "a";
84
Patrick Venture00d5f0d2019-05-17 19:21:35 -070085 req->cmd = static_cast<std::uint8_t>(BlobOEMCommands::bmcBlobOpen);
Patrick Ventureef3aead2018-09-12 08:53:29 -070086 req->crc = 0;
87 req->flags = 0;
88 // length() doesn't include the nul-terminator, request buff is initialized
89 // to 0s
William A. Kennington III117912d2021-06-15 18:22:44 -070090 std::memcpy(req + 1, blobId.c_str(), blobId.length());
Patrick Ventureef3aead2018-09-12 08:53:29 -070091
92 dataLen = sizeof(struct BmcBlobOpenTx) + blobId.length() + 1;
93 uint16_t returnedSession = 0x54;
94
95 EXPECT_CALL(mgr, open(req->flags, StrEq(blobId), NotNull()))
William A. Kennington III993f5412021-06-15 18:19:18 -070096 .WillOnce(Invoke([&](uint16_t, const std::string&, uint16_t* session) {
97 (*session) = returnedSession;
98 return true;
99 }));
Patrick Ventureef3aead2018-09-12 08:53:29 -0700100
101 EXPECT_EQ(IPMI_CC_OK, openBlob(&mgr, request, reply, &dataLen));
102
103 rep.crc = 0;
104 rep.sessionId = returnedSession;
105
106 EXPECT_EQ(sizeof(rep), dataLen);
107 EXPECT_EQ(0, std::memcmp(reply, &rep, sizeof(rep)));
108}
109} // namespace blobs