1 #include "helper.hpp"
2 #include "status.hpp"
3 #include "tool_errors.hpp"
4 
5 #include <blobs-ipmid/blobs.hpp>
6 #include <ipmiblob/test/blob_interface_mock.hpp>
7 
8 #include <cstdint>
9 
10 #include <gtest/gtest.h>
11 
12 namespace host_tool
13 {
14 using ::testing::Return;
15 using ::testing::TypedEq;
16 
17 class HelperTest : public ::testing::Test
18 {
19   protected:
20     ipmiblob::BlobInterfaceMock blobMock;
21     std::uint16_t session = 0xbeef;
22 };
23 
24 TEST_F(HelperTest, PollStatusReturnsAfterSuccess)
25 {
26     ipmiblob::StatResponse verificationResponse = {};
27     /* the other details of the response are ignored, and should be. */
28     verificationResponse.metadata.push_back(
29         static_cast<std::uint8_t>(ipmi_flash::ActionStatus::success));
30 
31     EXPECT_CALL(blobMock, getStat(TypedEq<std::uint16_t>(session)))
32         .WillOnce(Return(verificationResponse));
33 
34     EXPECT_NO_THROW(pollStatus(session, &blobMock));
35 }
36 
37 TEST_F(HelperTest, PollStatusReturnsAfterFailure)
38 {
39     ipmiblob::StatResponse verificationResponse = {};
40     /* the other details of the response are ignored, and should be. */
41     verificationResponse.metadata.push_back(
42         static_cast<std::uint8_t>(ipmi_flash::ActionStatus::failed));
43 
44     EXPECT_CALL(blobMock, getStat(TypedEq<std::uint16_t>(session)))
45         .WillOnce(Return(verificationResponse));
46 
47     EXPECT_THROW(pollStatus(session, &blobMock), ToolException);
48 }
49 
50 TEST_F(HelperTest, PollReadReadyReturnsAfterSuccess)
51 {
52     ipmiblob::StatResponse blobResponse = {};
53     /* the other details of the response are ignored, and should be. */
54     blobResponse.blob_state = blobs::StateFlags::open_read |
55                               blobs::StateFlags::committed;
56 
57     EXPECT_CALL(blobMock, getStat(TypedEq<std::uint16_t>(session)))
58         .WillOnce(Return(blobResponse));
59 
60     EXPECT_NO_THROW(pollReadReady(session, &blobMock));
61 }
62 
63 TEST_F(HelperTest, PollReadReadyReturnsAfterFailure)
64 {
65     ipmiblob::StatResponse blobResponse = {};
66     /* the other details of the response are ignored, and should be. */
67     blobResponse.blob_state = blobs::StateFlags::commit_error;
68 
69     EXPECT_CALL(blobMock, getStat(TypedEq<std::uint16_t>(session)))
70         .WillOnce(Return(blobResponse));
71 
72     EXPECT_THROW(pollReadReady(session, &blobMock), ToolException);
73 }
74 
75 TEST_F(HelperTest, PollReadReadyReturnsAfterRetrySuccess)
76 {
77     ipmiblob::StatResponse blobResponseRunning = {};
78     /* the other details of the response are ignored, and should be. */
79     blobResponseRunning.blob_state = blobs::StateFlags::committing;
80 
81     ipmiblob::StatResponse blobResponseReadReady = {};
82     /* the other details of the response are ignored, and should be. */
83     blobResponseReadReady.blob_state = blobs::StateFlags::open_read;
84 
85     EXPECT_CALL(blobMock, getStat(TypedEq<std::uint16_t>(session)))
86         .WillOnce(Return(blobResponseRunning))
87         .WillOnce(Return(blobResponseReadReady));
88 
89     EXPECT_NO_THROW(pollReadReady(session, &blobMock));
90 }
91 
92 TEST_F(HelperTest, PollReadReadyReturnsAfterRetryFailure)
93 {
94     ipmiblob::StatResponse blobResponseRunning = {};
95     /* the other details of the response are ignored, and should be. */
96     blobResponseRunning.blob_state = blobs::StateFlags::committing;
97 
98     ipmiblob::StatResponse blobResponseError = {};
99     /* the other details of the response are ignored, and should be. */
100     blobResponseError.blob_state = blobs::StateFlags::commit_error;
101 
102     EXPECT_CALL(blobMock, getStat(TypedEq<std::uint16_t>(session)))
103         .WillOnce(Return(blobResponseRunning))
104         .WillOnce(Return(blobResponseError));
105 
106     EXPECT_THROW(pollReadReady(session, &blobMock), ToolException);
107 }
108 
109 TEST_F(HelperTest, MemcpyAlignedOneByte)
110 {
111     const char source = 'a';
112     char destination;
113 
114     EXPECT_EQ(&destination,
115               memcpyAligned(&destination, &source, sizeof(source)));
116     EXPECT_EQ(destination, source);
117 }
118 
119 TEST_F(HelperTest, MemcpyAlignedMultiByte)
120 {
121     const char source[14] = "abcdefghijklm";
122     char destination[14] = "xxxxxxxxxxxxx";
123 
124     EXPECT_EQ(&destination,
125               memcpyAligned(&destination, &source, sizeof(source)));
126     EXPECT_EQ(0, memcmp(&destination, &source, sizeof(source)));
127 }
128 
129 } // namespace host_tool
130