xref: /openbmc/libpldm/tests/oem/meta/fileio.cpp (revision 7a8d932bc3cd30a0869b2e5cfd38c1b87019cffb)
1 /* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */
2 
3 #include "msgbuf.hpp"
4 
5 #include <endian.h>
6 #include <libpldm/base.h>
7 #include <libpldm/oem/meta/file_io.h>
8 
9 #include <cstdlib>
10 #include <new>
11 
12 #include "gmock/gmock.h"
13 #include <gtest/gtest.h>
14 
TEST(DecodeOemMetaFileIoWriteReq,testGoodDecodeRequest)15 TEST(DecodeOemMetaFileIoWriteReq, testGoodDecodeRequest)
16 {
17     constexpr const uint8_t postCode[4] = {0x93, 0xe0, 0x00, 0xea};
18     PLDM_MSGBUF_RW_DEFINE_P(ctx);
19     int rc;
20 
21     constexpr size_t encodedPayloadLen =
22         PLDM_OEM_META_FILE_IO_WRITE_REQ_MIN_LENGTH + sizeof(postCode);
23     constexpr size_t encodedMsgLen = sizeof(pldm_msg_hdr) + encodedPayloadLen;
24     alignas(pldm_msg) unsigned char encodedMsgBuf[encodedMsgLen] = {};
25     auto* encodedMsg = new (encodedMsgBuf) pldm_msg;
26 
27     rc = pldm_msgbuf_init_errno(ctx, 0, encodedMsg->payload, encodedPayloadLen);
28     ASSERT_EQ(rc, 0);
29 
30     pldm_msgbuf_insert_uint8(ctx, 0);
31     pldm_msgbuf_insert_int32(ctx, sizeof(postCode));
32     rc = pldm_msgbuf_insert_array_uint8(ctx, sizeof(postCode), postCode,
33                                         sizeof(postCode));
34     ASSERT_EQ(rc, 0);
35 
36     rc = pldm_msgbuf_complete_consumed(ctx);
37     ASSERT_EQ(rc, 0);
38 
39     constexpr size_t decodedReqLen =
40         sizeof(struct pldm_oem_meta_file_io_write_req) + sizeof(postCode);
41     alignas(pldm_oem_meta_file_io_write_req) unsigned char
42         decodedReqBuf[decodedReqLen];
43     auto* decodedReq = new (decodedReqBuf) pldm_oem_meta_file_io_write_req;
44     auto* decodedReqData =
45         static_cast<uint8_t*>(pldm_oem_meta_file_io_write_req_data(decodedReq));
46 
47     rc = decode_oem_meta_file_io_write_req(encodedMsg, encodedPayloadLen,
48                                            decodedReq, decodedReqLen);
49     ASSERT_EQ(rc, 0);
50 
51     EXPECT_EQ(decodedReq->handle, 0);
52     ASSERT_EQ(decodedReq->length, sizeof(postCode));
53     EXPECT_EQ(memcmp(decodedReqData, postCode, decodedReq->length), 0);
54 }
55 
TEST(DecodeOemMetaFileIoWriteReq,testInvalidFieldsDecodeRequest)56 TEST(DecodeOemMetaFileIoWriteReq, testInvalidFieldsDecodeRequest)
57 {
58     struct pldm_msg msg = {};
59 
60     auto rc = decode_oem_meta_file_io_write_req(&msg, sizeof(msg), NULL, 0);
61     EXPECT_EQ(rc, -EINVAL);
62 }
63 
TEST(DecodeOemMetaFileIoWriteReq,testInvalidLengthDecodeRequest)64 TEST(DecodeOemMetaFileIoWriteReq, testInvalidLengthDecodeRequest)
65 {
66     struct pldm_oem_meta_file_io_write_req req = {};
67     struct pldm_msg msg = {};
68 
69     auto rc = decode_oem_meta_file_io_write_req(&msg, 0, &req, sizeof(req));
70     EXPECT_EQ(rc, -EOVERFLOW);
71 }
72 
TEST(DecodeOemMetaFileIoWriteReq,testInvalidDataRequest)73 TEST(DecodeOemMetaFileIoWriteReq, testInvalidDataRequest)
74 {
75     struct pldm_oem_meta_file_io_write_req req = {};
76     struct pldm_msg msg = {};
77     int rc;
78 
79     rc = decode_oem_meta_file_io_write_req(
80         &msg, PLDM_OEM_META_FILE_IO_WRITE_REQ_MIN_LENGTH - 1, &req,
81         sizeof(req));
82     EXPECT_EQ(rc, -EOVERFLOW);
83 }
84 
TEST(DecodeOemMetaFileIoReadReq,testGoodDecodeRequest)85 TEST(DecodeOemMetaFileIoReadReq, testGoodDecodeRequest)
86 {
87     PLDM_MSGBUF_RW_DEFINE_P(ctx);
88     int rc;
89 
90     constexpr size_t payloadLen = PLDM_OEM_META_FILE_IO_READ_REQ_MIN_LENGTH +
91                                   PLDM_OEM_META_FILE_IO_READ_DATA_INFO_LENGTH;
92     alignas(pldm_msg) unsigned char buf[sizeof(pldm_msg_hdr) + payloadLen]{};
93     auto* msg = new (buf) pldm_msg;
94 
95     rc = pldm_msgbuf_init_errno(ctx, 0, msg->payload, payloadLen);
96     ASSERT_EQ(rc, 0);
97 
98     pldm_msgbuf_insert_uint8(ctx, 0);
99     pldm_msgbuf_insert_uint8(ctx, PLDM_OEM_META_FILE_IO_READ_DATA);
100     pldm_msgbuf_insert_uint8(ctx, PLDM_OEM_META_FILE_IO_READ_DATA_INFO_LENGTH);
101     pldm_msgbuf_insert_uint8(ctx, 1);
102     pldm_msgbuf_insert_uint16(ctx, 1223);
103 
104     rc = pldm_msgbuf_complete_consumed(ctx);
105     ASSERT_EQ(rc, 0);
106 
107     struct pldm_oem_meta_file_io_read_req req = {};
108     req.version = sizeof(req);
109     rc = decode_oem_meta_file_io_read_req(msg, payloadLen, &req);
110     ASSERT_EQ(rc, 0);
111 
112     EXPECT_EQ(req.handle, 0);
113     EXPECT_EQ(req.option, PLDM_OEM_META_FILE_IO_READ_DATA);
114     EXPECT_EQ(req.length, PLDM_OEM_META_FILE_IO_READ_DATA_INFO_LENGTH);
115     EXPECT_EQ(req.info.data.transferFlag, 1);
116     EXPECT_EQ(req.info.data.offset, 1223);
117 }
118 
TEST(DecodeOemMetaFileIoReadReq,testInvalidFieldsDecodeRequest)119 TEST(DecodeOemMetaFileIoReadReq, testInvalidFieldsDecodeRequest)
120 {
121     struct pldm_msg msg = {};
122 
123     auto rc = decode_oem_meta_file_io_read_req(
124         &msg, PLDM_OEM_META_FILE_IO_READ_REQ_MIN_LENGTH, NULL);
125     EXPECT_EQ(rc, -EINVAL);
126 }
127 
TEST(DecodeOemMetaFileIoReadReq,testInvalidLengthDecodeRequest)128 TEST(DecodeOemMetaFileIoReadReq, testInvalidLengthDecodeRequest)
129 {
130     struct pldm_oem_meta_file_io_read_req req = {};
131     struct pldm_msg msg = {};
132 
133     auto rc = decode_oem_meta_file_io_read_req(&msg, 0, &req);
134     EXPECT_EQ(rc, -EOVERFLOW);
135 }
136 
TEST(DecodeOemMetaFileIoReadReq,testInvalidDataRequest)137 TEST(DecodeOemMetaFileIoReadReq, testInvalidDataRequest)
138 {
139     struct pldm_oem_meta_file_io_read_req req = {};
140     struct pldm_msg msg = {};
141 
142     auto rc = decode_oem_meta_file_io_read_req(
143         &msg, PLDM_OEM_META_FILE_IO_READ_REQ_MIN_LENGTH - 1, &req);
144     EXPECT_EQ(rc, -EOVERFLOW);
145 }
146 
TEST(EncodeOemMetaFileIoReadResp,testGoodEncodeReadAttrResponse)147 TEST(EncodeOemMetaFileIoReadResp, testGoodEncodeReadAttrResponse)
148 {
149     int rc;
150 
151     alignas(pldm_oem_meta_file_io_read_resp) unsigned char
152         decodedBuf[sizeof(pldm_oem_meta_file_io_read_resp)];
153     auto* resp = new (decodedBuf) pldm_oem_meta_file_io_read_resp;
154     resp->version = sizeof(struct pldm_oem_meta_file_io_read_resp);
155     resp->completion_code = PLDM_SUCCESS;
156     resp->handle = 1;
157     resp->option = PLDM_OEM_META_FILE_IO_READ_ATTR;
158     resp->length = 0;
159     resp->info.attr.size = 0x1284;
160     resp->info.attr.crc32 = 0xab715432;
161 
162     constexpr size_t payloadLen = PLDM_OEM_META_FILE_IO_READ_RESP_MIN_SIZE +
163                                   PLDM_OEM_META_FILE_IO_READ_ATTR_INFO_LENGTH;
164     alignas(pldm_msg) unsigned char
165         encodedBuf[sizeof(pldm_msg_hdr) + payloadLen] = {};
166     auto* msg = new (encodedBuf) pldm_msg;
167 
168     rc = encode_oem_meta_file_io_read_resp(
169         0, resp, sizeof(pldm_oem_meta_file_io_read_resp), msg, payloadLen);
170     ASSERT_EQ(rc, 0);
171 
172     EXPECT_THAT(encodedBuf, testing::ElementsAreArray(
173                                 {0x00, 0x3f, 0x03, 0x00, 0x01, 0x00, 0x00, 0x84,
174                                  0x12, 0x32, 0x54, 0x71, 0xab}));
175 }
176 
TEST(EncodeOemMetaFileIoReadResp,testGoodEncodeReadDataResponse)177 TEST(EncodeOemMetaFileIoReadResp, testGoodEncodeReadDataResponse)
178 {
179     constexpr static const uint8_t readbuf[4] = {0x23, 0xca, 0x84, 0x9d};
180     int rc;
181 
182     alignas(pldm_oem_meta_file_io_read_resp) unsigned char
183         decodedBuf[sizeof(pldm_oem_meta_file_io_read_resp) + sizeof(readbuf)];
184     auto* resp = new (decodedBuf) pldm_oem_meta_file_io_read_resp;
185     resp->version = sizeof(struct pldm_oem_meta_file_io_read_resp);
186     resp->completion_code = PLDM_SUCCESS;
187     resp->handle = 1;
188     resp->option = PLDM_OEM_META_FILE_IO_READ_DATA;
189     resp->length = 4;
190     resp->info.data.transferFlag = 0x05;
191     resp->info.data.offset = 0x75cd;
192     memcpy(pldm_oem_meta_file_io_read_resp_data(resp), readbuf,
193            sizeof(readbuf));
194 
195     constexpr size_t payloadLen = PLDM_OEM_META_FILE_IO_READ_RESP_MIN_SIZE +
196                                   PLDM_OEM_META_FILE_IO_READ_DATA_INFO_LENGTH +
197                                   sizeof(readbuf);
198     alignas(pldm_msg) unsigned char
199         encodedBuf[sizeof(pldm_msg_hdr) + payloadLen] = {};
200     auto* msg = new (encodedBuf) pldm_msg;
201 
202     rc = encode_oem_meta_file_io_read_resp(
203         0, resp, sizeof(pldm_oem_meta_file_io_read_resp) + sizeof(readbuf), msg,
204         payloadLen);
205     ASSERT_EQ(rc, 0);
206 
207     EXPECT_THAT(encodedBuf, testing::ElementsAreArray(
208                                 {0x00, 0x3f, 0x03, 0x00, 0x01, 0x01, 0x04, 0x05,
209                                  0xcd, 0x75, 0x23, 0xca, 0x84, 0x9d}));
210 }
211 
TEST(EncodeOemMetaFileIoReadResp,testInvalidFieldsEncodeResponse)212 TEST(EncodeOemMetaFileIoReadResp, testInvalidFieldsEncodeResponse)
213 {
214     struct pldm_msg msg = {};
215 
216     auto rc = encode_oem_meta_file_io_read_resp(
217         0, NULL, 0, &msg, PLDM_OEM_META_FILE_IO_READ_RESP_MIN_SIZE);
218     EXPECT_EQ(rc, -EINVAL);
219 }
220 
TEST(EncodeOemMetaFileIoReadResp,testInvalidLengthEncodeResponse)221 TEST(EncodeOemMetaFileIoReadResp, testInvalidLengthEncodeResponse)
222 {
223     struct pldm_oem_meta_file_io_read_resp resp = {};
224     struct pldm_msg msg = {};
225 
226     auto rc =
227         encode_oem_meta_file_io_read_resp(0, &resp, sizeof(resp), &msg, 0);
228     EXPECT_EQ(rc, -EOVERFLOW);
229 }
230 
TEST(EncodeOemMetaFileIoReadResp,testInvalidDataEncodeResponse)231 TEST(EncodeOemMetaFileIoReadResp, testInvalidDataEncodeResponse)
232 {
233     struct pldm_oem_meta_file_io_read_resp resp = {};
234     struct pldm_msg msg = {};
235 
236     auto rc = encode_oem_meta_file_io_read_resp(
237         0, &resp, sizeof(resp), &msg,
238         PLDM_OEM_META_FILE_IO_READ_RESP_MIN_SIZE - 1);
239     EXPECT_EQ(rc, -EOVERFLOW);
240 }
241