summaryrefslogtreecommitdiffstats
path: root/test/tools_blob_unittest.cpp
diff options
context:
space:
mode:
authorPatrick Venture <venture@google.com>2019-03-05 14:01:00 -0800
committerPatrick Venture <venture@google.com>2019-03-06 07:51:32 -0800
commit123b5c0910e000cf9b00a37146aae99a835f3063 (patch)
treee1aacf85711d9c5f7e8ad87a1c8e671e09f61db8 /test/tools_blob_unittest.cpp
parent85e320906546f3e5a0dfe1ab54a826517dae2a0d (diff)
downloadipmi-blob-tool-123b5c0910e000cf9b00a37146aae99a835f3063.tar.gz
ipmi-blob-tool-123b5c0910e000cf9b00a37146aae99a835f3063.zip
initial commit
Add initial code from phosphor-ipmi-flash/tools that was not specific to firmware update over ipmi-blobs. Change-Id: I360537a7392347fe989397a699f6a712bc36e62c Signed-off-by: Patrick Venture <venture@google.com>
Diffstat (limited to 'test/tools_blob_unittest.cpp')
-rw-r--r--test/tools_blob_unittest.cpp289
1 files changed, 289 insertions, 0 deletions
diff --git a/test/tools_blob_unittest.cpp b/test/tools_blob_unittest.cpp
new file mode 100644
index 0000000..f7f58c4
--- /dev/null
+++ b/test/tools_blob_unittest.cpp
@@ -0,0 +1,289 @@
+#include "crc_mock.hpp"
+
+#include <ipmiblob/blob_handler.hpp>
+#include <ipmiblob/test/ipmi_interface_mock.hpp>
+
+#include <gtest/gtest.h>
+
+namespace host_tool
+{
+CrcInterface* crcIntf = nullptr;
+
+std::uint16_t generateCrc(const std::vector<std::uint8_t>& data)
+{
+ return (crcIntf) ? crcIntf->generateCrc(data) : 0x00;
+}
+
+using ::testing::Eq;
+using ::testing::Return;
+
+class BlobHandlerTest : public ::testing::Test
+{
+ protected:
+ void SetUp() override
+ {
+ crcIntf = &crcMock;
+ }
+
+ CrcMock crcMock;
+};
+
+TEST_F(BlobHandlerTest, getCountIpmiHappy)
+{
+ /* Verify returns the value specified by the IPMI response. */
+ IpmiInterfaceMock ipmiMock;
+ BlobHandler blob(&ipmiMock);
+ std::vector<std::uint8_t> request = {
+ 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobGetCount};
+
+ /* return 1 blob count. */
+ std::vector<std::uint8_t> resp = {0xcf, 0xc2, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00};
+
+ std::vector<std::uint8_t> bytes = {0x01, 0x00, 0x00, 0x00};
+ EXPECT_CALL(crcMock, generateCrc(Eq(bytes))).WillOnce(Return(0x00));
+
+ EXPECT_CALL(ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
+ EXPECT_EQ(1, blob.getBlobCount());
+}
+
+TEST_F(BlobHandlerTest, enumerateBlobIpmiHappy)
+{
+ /* Verify returns the name specified by the IPMI response. */
+ IpmiInterfaceMock ipmiMock;
+ BlobHandler blob(&ipmiMock);
+ std::vector<std::uint8_t> request = {
+ 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobEnumerate,
+ 0x00, 0x00, 0x01, 0x00,
+ 0x00, 0x00};
+
+ /* return value. */
+ std::vector<std::uint8_t> resp = {0xcf, 0xc2, 0x00, 0x00, 0x00,
+ 'a', 'b', 'c', 'd', 0x00};
+
+ std::vector<std::uint8_t> bytes = {'a', 'b', 'c', 'd', 0x00};
+ std::vector<std::uint8_t> reqCrc = {0x01, 0x00, 0x00, 0x00};
+ EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
+ EXPECT_CALL(crcMock, generateCrc(Eq(bytes))).WillOnce(Return(0x00));
+
+ EXPECT_CALL(ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
+ EXPECT_STREQ("abcd", blob.enumerateBlob(1).c_str());
+}
+
+TEST_F(BlobHandlerTest, enumerateBlobIpmiNoBytes)
+{
+ /* Simulate a case where the IPMI command returns no data. */
+ IpmiInterfaceMock ipmiMock;
+ BlobHandler blob(&ipmiMock);
+ std::vector<std::uint8_t> request = {
+ 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobEnumerate,
+ 0x00, 0x00, 0x01, 0x00,
+ 0x00, 0x00};
+
+ /* return value. */
+ std::vector<std::uint8_t> resp = {};
+
+ std::vector<std::uint8_t> reqCrc = {0x01, 0x00, 0x00, 0x00};
+ EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
+
+ EXPECT_CALL(ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
+ EXPECT_STREQ("", blob.enumerateBlob(1).c_str());
+}
+
+TEST_F(BlobHandlerTest, getBlobListIpmiHappy)
+{
+ /* Verify returns the list built via the above two commands. */
+ IpmiInterfaceMock ipmiMock;
+ BlobHandler blob(&ipmiMock);
+
+ std::vector<std::uint8_t> request1 = {
+ 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobGetCount};
+
+ /* return 1 blob count. */
+ std::vector<std::uint8_t> resp1 = {0xcf, 0xc2, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00};
+
+ std::vector<std::uint8_t> bytes1 = {0x01, 0x00, 0x00, 0x00};
+ EXPECT_CALL(crcMock, generateCrc(Eq(bytes1))).WillOnce(Return(0x00));
+
+ EXPECT_CALL(ipmiMock, sendPacket(Eq(request1))).WillOnce(Return(resp1));
+
+ std::vector<std::uint8_t> request2 = {
+ 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobEnumerate,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00};
+
+ /* return value. */
+ std::vector<std::uint8_t> resp2 = {0xcf, 0xc2, 0x00, 0x00, 0x00,
+ 'a', 'b', 'c', 'd', 0x00};
+
+ std::vector<std::uint8_t> reqCrc = {0x00, 0x00, 0x00, 0x00};
+ std::vector<std::uint8_t> bytes2 = {'a', 'b', 'c', 'd', 0x00};
+ EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
+ EXPECT_CALL(crcMock, generateCrc(Eq(bytes2))).WillOnce(Return(0x00));
+
+ EXPECT_CALL(ipmiMock, sendPacket(Eq(request2))).WillOnce(Return(resp2));
+
+ /* A std::string is not nul-terminated by default. */
+ std::vector<std::string> expectedList = {std::string{"abcd"}};
+
+ EXPECT_EQ(expectedList, blob.getBlobList());
+}
+
+TEST_F(BlobHandlerTest, getStatWithMetadata)
+{
+ /* Stat received metadata. */
+ IpmiInterfaceMock ipmiMock;
+ BlobHandler blob(&ipmiMock);
+ std::vector<std::uint8_t> request = {
+ 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobStat,
+ 0x00, 0x00, 'a', 'b',
+ 'c', 'd', 0x00};
+
+ /* return blob_state: 0xffff, size: 0x00, metadata 0x3445 */
+ std::vector<std::uint8_t> resp = {0xcf, 0xc2, 0x00, 0x00, 0x00, 0xff, 0xff,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x34, 0x45};
+
+ std::vector<std::uint8_t> reqCrc = {'a', 'b', 'c', 'd', 0x00};
+ std::vector<std::uint8_t> respCrc = {0xff, 0xff, 0x00, 0x00, 0x00,
+ 0x00, 0x02, 0x34, 0x45};
+ EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
+ EXPECT_CALL(crcMock, generateCrc(Eq(respCrc))).WillOnce(Return(0x00));
+
+ EXPECT_CALL(ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
+
+ auto meta = blob.getStat("abcd");
+ EXPECT_EQ(meta.blob_state, 0xffff);
+ EXPECT_EQ(meta.size, 0x00);
+ std::vector<std::uint8_t> metadata = {0x34, 0x45};
+ EXPECT_EQ(metadata, meta.metadata);
+}
+
+TEST_F(BlobHandlerTest, getStatNoMetadata)
+{
+ /* Stat received no metadata. */
+ IpmiInterfaceMock ipmiMock;
+ BlobHandler blob(&ipmiMock);
+ std::vector<std::uint8_t> request = {
+ 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobStat,
+ 0x00, 0x00, 'a', 'b',
+ 'c', 'd', 0x00};
+
+ /* return blob_state: 0xffff, size: 0x00, metadata 0x3445 */
+ std::vector<std::uint8_t> resp = {0xcf, 0xc2, 0x00, 0x00, 0x00, 0xff,
+ 0xff, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+ std::vector<std::uint8_t> reqCrc = {'a', 'b', 'c', 'd', 0x00};
+ std::vector<std::uint8_t> respCrc = {0xff, 0xff, 0x00, 0x00,
+ 0x00, 0x00, 0x00};
+
+ EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
+ EXPECT_CALL(crcMock, generateCrc(Eq(respCrc))).WillOnce(Return(0x00));
+
+ EXPECT_CALL(ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
+
+ auto meta = blob.getStat("abcd");
+ EXPECT_EQ(meta.blob_state, 0xffff);
+ EXPECT_EQ(meta.size, 0x00);
+ std::vector<std::uint8_t> metadata = {};
+ EXPECT_EQ(metadata, meta.metadata);
+}
+
+TEST_F(BlobHandlerTest, openBlobSucceeds)
+{
+ /* The open blob succeeds. */
+ IpmiInterfaceMock ipmiMock;
+ BlobHandler blob(&ipmiMock);
+
+ std::vector<std::uint8_t> request = {
+ 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobOpen,
+ 0x00, 0x00, 0x02, 0x04,
+ 'a', 'b', 'c', 'd',
+ 0x00};
+
+ std::vector<std::uint8_t> resp = {0xcf, 0xc2, 0x00, 0x00, 0x00, 0xfe, 0xed};
+
+ std::vector<std::uint8_t> reqCrc = {0x02, 0x04, 'a', 'b', 'c', 'd', 0x00};
+ std::vector<std::uint8_t> respCrc = {0xfe, 0xed};
+ EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
+ EXPECT_CALL(crcMock, generateCrc(Eq(respCrc))).WillOnce(Return(0x00));
+
+ EXPECT_CALL(ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
+
+ const int writeBit = (1 << 1);
+ const int lpcBit = (1 << 10);
+
+ auto session = blob.openBlob("abcd", writeBit | lpcBit);
+ EXPECT_EQ(0xedfe, session);
+}
+
+TEST_F(BlobHandlerTest, closeBlobSucceeds)
+{
+ /* The close succeeds. */
+ IpmiInterfaceMock ipmiMock;
+ BlobHandler blob(&ipmiMock);
+
+ std::vector<std::uint8_t> request = {
+ 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobClose,
+ 0x00, 0x00, 0x01, 0x00};
+ std::vector<std::uint8_t> resp = {0xcf, 0xc2, 0x00};
+ std::vector<std::uint8_t> reqCrc = {0x01, 0x00};
+ EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
+
+ EXPECT_CALL(ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
+
+ blob.closeBlob(0x0001);
+}
+
+TEST_F(BlobHandlerTest, writeBytesSucceeds)
+{
+ /* The write bytes succeeds. */
+ IpmiInterfaceMock ipmiMock;
+ BlobHandler blob(&ipmiMock);
+
+ std::vector<std::uint8_t> request = {
+ 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobWrite,
+ 0x00, 0x00, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 'a', 'b', 'c', 'd'};
+
+ std::vector<std::uint8_t> bytes = {'a', 'b', 'c', 'd'};
+ std::vector<std::uint8_t> resp = {0xcf, 0xc2, 0x00};
+ std::vector<std::uint8_t> reqCrc = {0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 'a', 'b', 'c', 'd'};
+ EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
+
+ EXPECT_CALL(ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
+
+ blob.writeBytes(0x0001, 0, bytes);
+}
+
+TEST_F(BlobHandlerTest, readBytesSucceeds)
+{
+ /* The reading of bytes succeeds. */
+
+ IpmiInterfaceMock ipmiMock;
+ BlobHandler blob(&ipmiMock);
+
+ std::vector<std::uint8_t> request = {
+ 0xcf, 0xc2, 0x00, BlobHandler::BlobOEMCommands::bmcBlobRead,
+ 0x00, 0x00, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x00, 0x00, 0x00};
+
+ std::vector<std::uint8_t> expectedBytes = {'a', 'b', 'c', 'd'};
+ std::vector<std::uint8_t> resp = {0xcf, 0xc2, 0x00, 0x00, 0x00,
+ 'a', 'b', 'c', 'd'};
+ std::vector<std::uint8_t> reqCrc = {0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x04, 0x00, 0x00, 0x00};
+ std::vector<std::uint8_t> respCrc = {'a', 'b', 'c', 'd'};
+
+ EXPECT_CALL(crcMock, generateCrc(Eq(reqCrc))).WillOnce(Return(0x00));
+ EXPECT_CALL(crcMock, generateCrc(Eq(respCrc))).WillOnce(Return(0x00));
+
+ EXPECT_CALL(ipmiMock, sendPacket(Eq(request))).WillOnce(Return(resp));
+
+ EXPECT_EQ(blob.readBytes(0x0001, 0, 4), expectedBytes);
+}
+
+} // namespace host_tool
OpenPOWER on IntegriCloud